将分页报表导出为文件

使用 exportToFile API,可通过 REST 调用来导出 Power BI 分页报表。 支持以下文件格式:

  • .pptx (PowerPoint)

  • .pdf(和可访问 PDF 或 PDF/UA

  • .xlsx (Excel)

  • .docx (Word)

  • .csv

  • .xml

  • .mhtml

  • 图像
    导出为图像时,可以通过 OutputFormat 格式设置来设置图像格式。 支持的 OutputFormat 值包括:

    • .tiff(默认值)
    • .bmp
    • .emf
    • .gif
    • .jpeg
    • .png

用法示例

可通过多种方式使用导出功能。 下面是几个示例:

  • “发送到打印程序”按钮 - 在应用中创建一个按钮;如果有人单击此按钮,就会触发导出作业。 此作业可将已查看的报表导出为 .pdf 或 .pptx。 完成后,用户可以下载该文件。 使用报表参数和格式设置,你可以以特定的状态导出报表,包括筛选数据、自定义页面大小和其他特定于格式的设置。 由于此 API 是异步的,因此可能需要一段时间才能获取文件。

  • 电子邮件附件 - 每隔一段时间自动发送包含 .pdf 报表附件的电子邮件。 如果需要自动向主管发送每周报表,就会发现此方案非常有用。

使用 API

许可要求

呈现事件

若要确保在视觉对象完成呈现后才开始导出,请使用“呈现”事件 API,并且仅在呈现完成后才开始导出。

轮询

此 API 是异步的。 调用后,exportToFile API 会触发导出作业。 在导出作业触发后,使用轮询来跟踪此作业,直到它完成。

在导出完成后,轮询 API 调用返回用于获取文件的 Power BI URL。 此 URL 在 24 小时内有效。

支持的功能

格式设置

为每种文件格式指定各项格式设置。 支持的属性和值等同于分页报表 URL 参数的设备信息参数

下面展示了两个示例。 第一个演示如何按报表页面大小将报表的前四页导出到 .pptx 文件中。 第二个演示如何将报表的第三页导出到 .jpeg 文件中。

将前四页导出为 .pptx

{
      "format": "PPTX",
      "paginatedReportConfiguration":{
            "formatSettings":{
                  "UseReportPageSize": "true",
                  "StartPage": "1",
                  "EndPage": "4"
            }
      }
}

将第三页导出为 .jpeg

{
      "format": "IMAGE",
      "paginatedReportConfiguration":{
            "formatSettings":{
                  "OutputFormat": "JPEG",
                  "StartPage": "3",
                  "EndPage": "3"
            }
      }
}

报表参数

你可以使用 exportToFile API,通过一组报表参数以编程方式导出报表。 这种方法是使用报表参数功能实现的。

下面是设置报表参数值的示例。

{
      "format": "PDF",
      "paginatedReportConfiguration":{
            "parameterValues":[
                  {"name": "State", "value": "WA"},
                  {"name": "City", "value": "Seattle"},
                  {"name": "City", "value": "Bellevue"},
                  {"name": "City", "value": "Redmond"}
            ]
      }
}

身份验证

只能使用用户(或主用户)或服务主体进行身份验证。

行级别安全性 (RLS)

使用定义了行级别安全性 (RLS) 的 Power BI 语义模型作为数据源时,你可以导出显示仅对某些用户可见的数据的报表。 例如,若要导出使用区域角色定义的销售报表,可以编程方式将报表筛选为只显示特定区域。

若要使用 RLS 进行导出,必须对报表用作数据源的 Power BI 语义模型具有读取权限。

下面是为 RLS 提供有效用户名的示例。

{
      "format": "PDF",
      "paginatedReportConfiguration":{
            "identities": [
                  {"username": "john@contoso.com"}
            ]
      }
}

单一登录 SQL 和 Dataverse (SSO)

在 Power BI 中,可以选择使用 SSO 设置 OAuth。 执行此操作时,将使用查看报表的用户的凭据来检索数据。 请求标头中的访问令牌不用于访问数据。 需要将令牌与 post 正文中的有效标识一起传入。

获取正确的用于要访问的资源的访问令牌有时会比较麻烦

  • 对于 Azure SQL,资源是 https://database.windows.net
  • 对于 Dataverse,资源是环境的 https:// 地址。 例如,https://contoso.crm.dynamics.com

使用 AuthenticationContext.AcquireTokenAsync 方法访问令牌 API。

下面是使用访问令牌提供有效标识(用户名)的示例。

{
       "format":"PDF",
       "paginatedReportConfiguration":{
          "formatSettings":{
             "AccessiblePDF":"true",
             "PageHeight":"11in",
             "PageWidth":"8.5in",
             "MarginBottom":"2in"
          },
          "identities":[
             {
                "username":"john@contoso.com",
                "identityBlob": {
                "value": "eyJ0eX....full access token"
         }
        }
     ]
   }
}

并发请求

exportToFile 支持有限数量的并发请求。 并发分页报表呈现请求的最大数目为 500。 若要避免超出限制并收到 请求过多 (429) 错误,请随时间推移或跨容量分配负载。

使用 Premium Per User (PPU) 时,exportToFile API 在五分钟内只允许一个请求。 如果在五分钟的时段内发出多个请求,将导致“请求过多”(429) 错误。

代码示例

代码示例中使用的 Power BI API SDK 可从此处下载。

创建导出作业时,要遵循以下三个步骤:

  1. 发送导出请求。
  2. 轮询。
  3. 获取文件。

此部分举例说明了各个步骤。

第 1 步 - 发送导出请求

第 1 步是发送导出请求。 在本示例中,导出请求是针对特定报表页范围、大小和报表参数值发送的。

private async Task<string> PostExportRequest(
    Guid reportId,
    Guid groupId)
{
    // For documentation purposes the export configuration is created in this method
    // Ordinarily, it would be created outside and passed in
    var paginatedReportExportConfiguration = new PaginatedReportExportConfiguration()
    {
        FormatSettings = new Dictionary<string, string>()
        {
            {"PageHeight", "14in"},
            {"PageWidth", "8.5in" },
            {"StartPage", "1"},
            {"EndPage", "4"},
        },
        ParameterValues = new List<ParameterValue>()
        {
            { new ParameterValue() {Name = "State", Value = "WA"} },
            { new ParameterValue() {Name = "City", Value = "Redmond"} },
        },
    };

    var exportRequest = new ExportReportRequest
    {
        Format = FileFormat.PDF,
        PaginatedReportExportConfiguration = paginatedReportExportConfiguration,
    };

    var export = await Client.Reports.ExportToFileInGroupAsync(groupId, reportId, exportRequest);

    // Save the export ID, you'll need it for polling and getting the exported file
    return export.Id;
}

第 2 步 - 轮询

发送导出请求后,使用轮询来确定等待的导出文件何时就绪。

private async Task<Export> PollExportRequest(
    Guid reportId,
    Guid groupId,
    string exportId /* Get from the ExportToAsync response */,
    int timeOutInMinutes,
    CancellationToken token)
{
    Export exportStatus = null;
    DateTime startTime = DateTime.UtcNow;
    const int secToMillisec = 1000;
    do
    {
        if (DateTime.UtcNow.Subtract(startTime).TotalMinutes > timeOutInMinutes || token.IsCancellationRequested)
        {
            // Error handling for timeout and cancellations
            return null;
        }

        var httpMessage = 
            await Client.Reports.GetExportToFileStatusInGroupWithHttpMessagesAsync(groupId, reportId, exportId);
            
        exportStatus = httpMessage.Body;
        if (exportStatus.Status == ExportState.Running || exportStatus.Status == ExportState.NotStarted)
        {
            // The recommended waiting time between polling requests can be found in the RetryAfter header
            // Note that this header is only populated when the status is either Running or NotStarted
            var retryAfter = httpMessage.Response.Headers.RetryAfter;
            var retryAfterInSec = retryAfter.Delta.Value.Seconds;

            await Task.Delay(retryAfterInSec * secToMillisec);
        }
    }
    // While not in a terminal state, keep polling
    while (exportStatus.Status != ExportState.Succeeded && exportStatus.Status != ExportState.Failed);

    return exportStatus;
}

第 3 步 - 获取文件

在轮询返回 URL 后,参照下面的示例来获取收到的文件。

private async Task<ExportedFile> GetExportedFile(
    Guid reportId,
    Guid groupId,
    Export export /* Get from the GetExportStatusAsync response */)
{
    if (export.Status == ExportState.Succeeded)
    {
        var httpMessage = 
            await Client.Reports.GetFileOfExportToFileInGroupWithHttpMessagesAsync(groupId, reportId, export.Id);

        return new ExportedFile
        {
            FileStream = httpMessage.Body,
            ReportName = export.ReportName,
            FileExtension = export.ResourceFileExtension,
        };
    }

    return null;
}

public class ExportedFile
{
    public Stream FileStream;
    public string ReportName;
    public string FileExtension;
}

端到端示例

这是导出报表的端到端示例。 此示例包括以下几个阶段:

  1. 发送导出请求
  2. 轮询
  3. 获取文件
private async Task<ExportedFile> ExportPaginatedReport(
    Guid reportId,
    Guid groupId,
    int pollingtimeOutInMinutes,
    CancellationToken token)
{
    try
    {
        var exportId = await PostExportRequest(reportId, groupId);

        var export = await PollExportRequest(reportId, groupId, exportId, pollingtimeOutInMinutes, token);
        if (export == null || export.Status != ExportState.Succeeded)
        {
           // Error, failure in exporting the report
            return null;
        }

        return await GetExportedFile(reportId, groupId, export);
    }
    catch
    {
        // Error handling
        throw;
    }
}

注意事项和限制

  • 以下情况不支持将具有 Power BI 语义模型的分页报表导出为其数据源:

    • 调用方是服务主体配置文件
    • 语义模型的一个数据源配置为启用单一登录 (SSO),并提供了有效的标识。
    • Power BI 语义模型具有对 Azure Analysis Services 或另一个 Power BI 语义模型的 DirectQuery,并提供了有效标识。
  • 在以下情况下,不支持导出已将 Azure Analysis Services 数据源配置为启用单一登录 (SSO) 的分页报表:

  • 要导出具有有效标识的分页报表,用户名必须是租户的 Microsoft Entra ID 中的现有用户。

  • 报表的导出时间限制为 60 分钟,与用户访问令牌的生命周期一致。 导出大量数据时,如果 60 分钟后发生超时错误,请考虑使用适当的筛选器减少数据数量。

  • 联机导出 Power BI 服务上已发布的分页报表时,文件共享 URL 超链接(文件共享 /UNC 路径)不起作用。

了解如何为客户和组织嵌入内容: