将 Power BI 报表导出到文件

  • 版本 :2023.1(当前版本)

将 Power BI 报表导出到文件

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

  • .pptx (PowerPoint)

  • .pdf

  • .png

    • 导出为 .png 时,包含多个报表页的报表会压缩为 .zip 文件

    • .zip 中的每个文件都代表一个报表页

    • 报表页名称与 Get Pages 或 Get Pages in Group API 返回的值相同

用法示例

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

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

  • 电子邮件附件 - 每隔一段时间自动发送包含 .pdf 报表附件的电子邮件。 如果需要自动向主管发送每周报表,就会发现此方案非常有用。 有关更多信息,请参阅使用 Power Automate 导出 Power BI 报表并以电子邮件的方式发送

使用 API

管理员设置

使用此 API 前,请先验证是否已启用以下管理员租户设置:

  • 将报表导出为 PowerPoint 演示文稿或 PDF 文档 - 默认处于启用状态。

  • 将报表导出为图像文件 - 只有导出为 .png 才需要启用,默认处于禁用状态。

“呈现”事件

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

轮询

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

在轮询期间,此 API 返回表示已完成工作量的数字。 每个导出作业中的工作量都是根据作业中的导出总数计算的。 导出包括导出单个视觉对象或导出带有或不带有书签的页面。 所有导出的权重都相同。 例如,如果导出作业包括导出包含 10 页报表,且轮询返回 70,则表示此 API 已处理导出作业中 10 页中的 7 页。

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

支持的功能

本部分介绍如何使用以下受支持功能:

  • 选择要打印哪些报表页

  • 导出页面或单个视觉对象

  • 书签

  • 筛选器

  • 身份验证

  • 行级别安全性 (RLS)

  • 数据保护

  • 本地化

  • 动态绑定

选择要打印哪些报表页

根据 Get Pages 或 Get Pages in Group 返回值,指定要打印的报表页。 还可以指定要导出的报表页的顺序。

导出页面或单个视觉对象

可以指定要导出的页面或单个视觉对象。 可以导出带有或不带有书签的页面。

需要根据导出的类型将不同的属性传递给 ExportReportPage 对象。 下表指定每个导出作业所需的属性。

备注

导出单个视觉对象与导出页面(带有或不带有书签)的权重相同。 这意味着就系统计算而言,两个操作都具有相同的值。

Attribute单个视觉对象注释
bookmark可选不适用于:用于导出处于特定状态的页面
pageName适用于。适用于使用 GetPages REST API 或 getPages 客户端 API。
visualName不适用于:适用于。可通过两种方法获取视觉对象的名称:
  • 使用 getVisuals 客户端 API。

  • 侦听并记录 visualClicked 事件,此事件在选择视觉对象时触发。 有关详细信息,请参阅如何处理事件

  • .

书签

书签可用于在特定的配置中保存报表,包括已应用的筛选器和报表视觉对象的状态。 可以通过两种方式使用 exportToFile API 以编程方式导出报表的书签:

  • 导出现有书签

    若要导出现有报表书签,请使用 name 属性,它是一个唯一(区分大小写)标识符,你可以使用书签 JavaScript API 获取该标识符。

  • 导出报表的状态

    若要导出报表的当前状态,请使用 state 属性。 例如,可以使用书签的 bookmarksManager.capture 方法来捕获特定用户对报表所做的更改,然后使用 capturedBookmark.state 导出当前状态下的报表。

备注

不支持导出使用个人书签和永久性筛选器的报表。

筛选器

使用 PowerBIReportExportConfiguration 中的 reportLevelFilters,可以在筛选条件下导出报表。

若要导出筛选报表,请将要用作筛选器的 URL 查询字符串参数插入到 ExportFilter。 输入字符串时,必须删除 URL 查询参数的 ?filter= 部分。

下表包含一些可传递给 ExportFilter 的字符串语法示例。

筛选器语法示例
字段中的一个值Table/Field eq 'value'Store/Territory eq 'NC'
字段中的多个值Table/Field in ('value1', 'value2')Store/Territory in ('NC', 'TN')
一个字段中的非重复值,另一个字段中的其他非重复值Table/Field1 eq 'value1' and Table/Field2 eq 'value2'Store/Territory eq 'NC' and Store/Chain eq 'Fashions Direct'

身份验证

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

行级别安全性 (RLS)

使用行级别安全性 (RLS),可以导出仅对特定用户显示数据的报表。 例如,若要导出使用区域角色定义的销售报表,可以编程方式将报表筛选为只显示特定区域。

若要使用 RLS 导出报表,必须拥有以下权限:

  • 对报表连接到的数据集的写入和重新共享权限

  • 报表所在工作区的工作区成员或管理员

数据保护

.pdf 和 .pptx 格式支持敏感度标签。 如果将包含敏感度标签的报表导出为 .pdf 或 .pptx,导出的文件会显示包含其敏感度标签的报表。

无法使用服务主体将具有敏感度标签的报表导出到 .pdf 或 .pptx。

本地化

使用 exportToFile API 时,可以传递所需区域设置。 本地化设置会影响报表的显示方式(例如,根据所选的本地化设置来更改格式设置)。

动态绑定

若要在报表连接到非默认数据集时导出报表,请在调用 API 时在 datasetToBind 参数中指定所需的数据集 ID。 详细了解动态绑定。

并发请求

exportToFile API 支持并发导出作业请求。 下表列出了可同时运行的作业数,具体视报表所驻留在的 SKU 而定。 并发请求引用报表页。 例如,在 A4 SKU 上,一个导出请求中的 55 个报表页会同时得到处理。 此过程与发送 55 个导出请求(每个报表页一个请求)所花费的时间大致相同。

超出并发请求数的作业不会终止。 例如,如果在 A2 SKU 中导出 30 个页面,前 25 个作业会运行,其余 5 个作业将等待下一个执行周期。

只会同时处理一个报表中的 5 页。 例如,如果要导出包含 50 页的报表,导出作业将按 10 次连续进行处理。 优化导出作业时,可能会希望并行执行多个作业。 例如,如果你有一个 A1 SKU,每次导出最多能同时处理 20 页,你可以同时处理四个 50 页的报表。 在给定时间只会处理每个作业中的五个页面。 因此,完成四个作业的总时间比在一个作业中导出整个报表要短。

备注

  • Premium Per User (PPU) 不支持使用 exportToFile API 将 Power BI 报表导出到文件。

  • 并发分页报表的上限是不同的,这在将分页报表导出到文件中进行了介绍。

Azure SKUOffice SKU并发报表页数上限
A1EM120
A2EM225
A3EM335
A4P155
A5P295
A6P3175
A71P41200
A81P51200

1 大于 100 GB 的 SKU 并非在所有区域都可用。 若要请求在不可用的区域使用这些 SKU,请联系 Microsoft 客户经理。

代码示例

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

  1. 发送导出请求。

  2. 轮询。

  3. 获取文件。

  4. 使用文件流。

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

第 1 步 - 发送导出请求

第 1 步是发送导出请求。 在下面的示例中,导出请求是针对特定报表页发送的。

C#复制

private async Taskstring> PostExportRequest(
Guid reportId,
Guid groupId,
FileFormat format,
IListstring> pageNames = null, /* Get the page names from the GetPages REST API */
string urlFilter = null){ var powerBIReportExportConfiguration = new PowerBIReportExportConfiguration
{
Settings = new ExportReportSettings
{
Locale = "en-us",
}, // Note that page names differ from the page display names
// To get the page names use the GetPages REST API
Pages = pageNames?.Select(pn => new ExportReportPage(Name = pn)).ToList(), // ReportLevelFilters collection needs to be instantiated explicitly
ReportLevelFilters = !string.IsNullOrEmpty(urlFilter) ? new List() { new ExportFilter(urlFilter) } : null,

}; var exportRequest = new ExportReportRequest
{
Format = format,
PowerBIReportConfiguration = powerBIReportExportConfiguration,
}; // The 'Client' object is an instance of the Power BI .NET SDK
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 步 - 轮询

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

C#复制

private async Task> PollExportRequest(
Guid reportId,
Guid groupId, string exportId /* Get from the PostExportRequest response */, int timeOutInMinutes,
CancellationToken token)
{
HttpOperationResponse httpMessage = null;
Export exportStatus = null;
DateTime startTime = DateTime.UtcNow; const int c_secToMillisec = 1000; do
{ if (DateTime.UtcNow.Subtract(startTime).TotalMinutes > timeOutInMinutes || token.IsCancellationRequested)
{ // Error handling for timeout and cancellations
return null;
} // The 'Client' object is an instance of the Power BI .NET SDK
httpMessage = await Client.Reports.GetExportToFileStatusInGroupWithHttpMessagesAsync(groupId, reportId, exportId);
exportStatus = httpMessage.Body; // You can track the export progress using the PercentComplete that's part of the response
SomeTextBox.Text = string.Format("{0} (Percent Complete : {1}%)", exportStatus.Status.ToString(), exportStatus.PercentComplete); 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 not always populated
var retryAfter = httpMessage.Response.Headers.RetryAfter; var retryAfterInSec = retryAfter.Delta.Value.Seconds; await Task.Delay(retryAfterInSec * c_secToMillisec);
}
} // While not in a terminal state, keep polling
while (exportStatus.Status != ExportState.Succeeded && exportStatus.Status != ExportState.Failed); return httpMessage;
}

第 3 步 - 获取文件

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

C#复制

private async Task GetExportedFile(
Guid reportId,
Guid groupId,
Export export /* Get from the PollExportRequest response */){ if (export.Status == ExportState.Succeeded)
{ // The 'Client' object is an instance of the Power BI .NET SDK
var fileStream = await Client.Reports.GetFileOfExportToFileAsync(groupId, reportId, export.Id); return new ExportedFile
{
FileStream = fileStream,
FileSuffix = export.ResourceFileExtension,
};
} return null;
}public class ExportedFile{ public Stream FileStream; public string FileSuffix;
}

步骤 4 - 使用文件流

如果有文件流,可以按照最适合你需要的方式对其进行处理。 例如,你可以通过电子邮件发送它或使用它来下载导出的报表。

端到端示例

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

  1. 发送导出请求。

  2. 轮询。

  3. 获取文件。

C#复制

private async Task ExportPowerBIReport(
Guid reportId,
Guid groupId,
FileFormat format, int pollingtimeOutInMinutes,
CancellationToken token,
IListstring> pageNames = null, /* Get the page names from the GetPages REST API */
string urlFilter = null){ const int c_maxNumberOfRetries = 3; /* Can be set to any desired number */
const int c_secToMillisec = 1000; try
{
Export export = null; int retryAttempt = 1; do
{ var exportId = await PostExportRequest(reportId, groupId, format, pageNames, urlFilter); var httpMessage = await PollExportRequest(reportId, groupId, exportId, pollingtimeOutInMinutes, token);
export = httpMessage.Body; if (export == null)
{ // Error, failure in exporting the report
return null;
} if (export.Status == ExportState.Failed)
{ // Some failure cases indicate that the system is currently busy. The entire export operation can be retried after a certain delay
// In such cases the recommended waiting time before retrying the entire export operation can be found in the RetryAfter header
var retryAfter = httpMessage.Response.Headers.RetryAfter; if(retryAfter == null)
{ // Failed state with no RetryAfter header indicates that the export failed permanently
return null;
} var retryAfterInSec = retryAfter.Delta.Value.Seconds; await Task.Delay(retryAfterInSec * c_secToMillisec);
}
} while (export.Status != ExportState.Succeeded && retryAttempt++ if (export.Status != ExportState.Succeeded)
{ // Error, failure in exporting the report
return null;
} var exportedFile = await GetExportedFile(reportId, groupId, export); // Now you have the exported file stream ready to be used according to your specific needs
// For example, saving the file can be done as follows:
/*
var pathOnDisk = @"C:\temp\" + export.ReportName + exportedFile.FileSuffix;

using (var fileStream = File.Create(pathOnDisk))
{
exportedFile.FileStream.CopyTo(fileStream);
}
*/

return exportedFile;
}
catch
{ // Error handling
throw;
}
}

注意事项和限制

  • 导出 API 操作负载将被评估为运行缓慢的后台操作,如 Premium Gen2 容量负载评估中所述。

  • 要导出的报表必须驻留在高级容量或嵌入式容量中。

  • 要导出的报表中的所有相关数据集必须驻留在高级容量或嵌入式容量中,包括具有直接查询连接的数据集。

  • 导出的报表的文件大小不得超过 250MB。

  • 导出为 .png 时,不支持敏感度标签。

  • 单个导出的报表中可包含的导出(单个视觉对象或报表页面)的数量为 50(这不包括导出分页报表)。 如果请求包含更多导出,此 API 会返回错误,导出作业也会遭取消。

  • 不支持导出使用个人书签和永久性筛选器的报表。

  • Premium Per User (PPU) 不支持使用 exportToFile API 将 Power BI 报表导出到文件。

  • 不支持导出包含下列 Power BI 视觉对象的报表。 如果你导出包含这些视觉对象的报表,包含这些视觉对象的报表部分将不会呈现,并会显示错误符号。

    • 未经认证的 Power BI 自定义视觉对象

    • R 视觉对象

    • PowerApps

    • Python 视觉对象

    • Power Automate

    • 分页报表视觉对象

    • Visio