Export paginated report to file
The exportToFile
API enables exporting a Power BI paginated report by using a REST call. The following file formats are supported:
.pptx (PowerPoint)
.pdf (and Accessible PDF, or PDF/UA)
.xlsx (Excel)
.docx (Word)
.csv
.xml
.mhtml
Image
When exporting to an image, set the image format via theOutputFormat
format setting. The supportedOutputFormat
values are:- .tiff (default)
- .bmp
- .emf
- .gif
- .jpeg
- .png
Usage examples
You can use the export feature in various ways. Here are a couple of examples:
Send to print button - In your application, create a button that when clicked on triggers an export job. The job can export the viewed report as a .pdf or a .pptx. When it's complete, the user can receive the file as a download. Using report parameters and format settings you can export the report in a specific state, including filtered data, custom page sizes, and other format-specific settings. As the API is asynchronous, it may take some time for the file to be available.
Email attachment - Send an automated email at set intervals, with an attached .pdf report. This scenario can be useful if you want to automate sending a weekly report to executives.
Using the API
License requirements
- The report you're exporting must reside in a workspace backed by a Premium, Embedded, or Fabric capacity.
- The
exportToFile
API, has limited support in Premium Per User (PPU).
Rendering events
To make sure the export doesn't begin before the visual finishes rendering, use the "Rendering" events API and only begin the export when rendering is finished.
Polling
The API is asynchronous. When the exportToFile API is called, it triggers an export job. After triggering an export job, use polling to track the job, until it's complete.
When the export is complete, the polling API call returns a Power BI URL for getting the file. The URL is available for 24 hours.
Supported features
Format settings
Specify various format settings for each file format. The supported properties and values are equivalent to Device Info parameters for paginated report URL parameters.
Here are two examples. The first is for exporting the first four pages of a report using the report page size to a .pptx file. The second example is for exporting the third page of a report to a .jpeg file.
Exporting the first four pages to a .pptx
{
"format": "PPTX",
"paginatedReportConfiguration":{
"formatSettings":{
"UseReportPageSize": "true",
"StartPage": "1",
"EndPage": "4"
}
}
}
Exporting the third page to a .jpeg
{
"format": "IMAGE",
"paginatedReportConfiguration":{
"formatSettings":{
"OutputFormat": "JPEG",
"StartPage": "3",
"EndPage": "3"
}
}
}
Report parameters
You can use the exportToFile
API to programmatically export a report with a set of report parameters. This is done using report parameter capabilities.
Here's an example for setting report parameter values.
{
"format": "PDF",
"paginatedReportConfiguration":{
"parameterValues":[
{"name": "State", "value": "WA"},
{"name": "City", "value": "Seattle"},
{"name": "City", "value": "Bellevue"},
{"name": "City", "value": "Redmond"}
]
}
}
Authentication
You can authenticate using a user (or master user) or a service principal.
Row Level Security (RLS)
When using a Power BI semantic model that has Row Level Security (RLS) defined as a data source, you can export a report showing data that's only visible to certain users. For example, if you're exporting a sales report that's defined with regional roles, you can programmatically filter the report so that only a certain region is displayed.
To export using RLS, you must have read permission for the Power BI semantic model the report is using as a data source.
Here's an example of supplying an effective user name for RLS.
{
"format": "PDF",
"paginatedReportConfiguration":{
"identities": [
{"username": "john@contoso.com"}
]
}
}
Single Sign-on SQL and Dataverse (SSO)
In Power BI, you have the option to set OAuth with SSO. When you do, the credentials for the user viewing the report are used to retrieve data. The access token in the request header isn't used to access the data. The token must be passed in with the effective identity in the post body.
Getting the correct access token for the resource that you want to access can sometimes be tricky.
- For Azure SQL, the resource is
https://database.windows.net
. - For Dataverse, the resource is the
https://
address for your environment. For example,https://contoso.crm.dynamics.com
.
Access the token API using the AuthenticationContext.AcquireTokenAsync method.
Here's an example for supplying an effective identity (user name) with an access token.
{
"format":"PDF",
"paginatedReportConfiguration":{
"formatSettings":{
"AccessiblePDF":"true",
"PageHeight":"11in",
"PageWidth":"8.5in",
"MarginBottom":"2in"
},
"identities":[
{
"username":"john@contoso.com",
"identityBlob": {
"value": "eyJ0eX....full access token"
}
}
]
}
}
Concurrent requests
The exportToFile
supports a limited number of concurrent requests. The maximum number of concurrent paginated report render requests is 500. To avoid exceeding the limit and getting a Too Many Requests (429) error, either distribute the load over time or across capacities.
With Premium Per User (PPU), the exportToFile
API allows just one request in a five-minute window. Multiple requests within the five-minute window result in a Too Many Requests (429) error.
Code examples
The Power BI API SDK used in the code examples can be download here.
When you create an export job, there are three steps to follow:
- Sending an export request.
- Polling.
- Getting the file.
This section provides examples for each step.
Step 1 - sending an export request
The first step is sending an export request. In this example, an export request is sent for a specific page range, size, and report parameter values.
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;
}
Step 2 - polling
After you've sent an export request, use polling to identify when the export file you're waiting for is ready.
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;
}
Step 3 - getting the file
Once polling returns a URL, use this example to get the received file.
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;
}
End-to-end example
This is an end-to-end example for exporting a report. This example includes the following stages:
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;
}
}
Considerations and limitations
Exporting a paginated report that has a Power BI semantic model as its data source, isn't supported in the following cases:
- The caller is a service principal profile.
- One of the semantic model's data sources is configured with single sign-on (SSO) enabled and an effective identity was provided.
- The Power BI semantic model has DirectQuery to Azure Analysis Services or to another Power BI semantic model, and an effective identity was provided.
Exporting a paginated report that has Azure Analysis Services data source configured with single sign-on (SSO) enabled, isn't supported in the following cases:
- The caller is a service principal profile.
- The caller is a master user and an effective identity was provided.
To export a paginated report with an effective identity, the username must be an existing user from your tenant’s Microsoft Entra ID.
Export of a report is limited to 60 minutes, which matches the life of the user access token. If you get a timeout error past the 60-minute mark when exporting large amounts of data, consider reducing the amount of data using appropriate filters.
The file share URL hyperlink (file share /UNC path) doesn't works when exporting a published paginated report on Power BI service online.
Related content
Review how to embed content for your customers and your organization: