Export Power BI report to file (preview)

The exportToFile API enables exporting a Power BI report by using a REST call. The following file formats are supported:

  • .pptx (PowerPoint)
  • .pdf
  • .png
    • When exporting to a .png, a report with multiple pages is compressed into a .zip file
    • Each file in the .zip represents a report page
    • The page names are the same as the return values of the Get Pages or Get Pages in Group APIs

Usage examples

You can use the export feature in a variety of 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, and when it's complete, the user can receive the file as a download. Using bookmarks you can export the report in a specific state, including configured filters, slicers, and additional 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

Before using the API, verify that the following admin tenant settings are enabled:

  • Export reports as PowerPoint presentations or PDF documents - Enabled by default.
  • Export reports as image files - Required only for .png and disabled by default.

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.

During polling, the API returns a number that represents the amount of work completed. The work in each export job is calculated based on the number of pages the report has. All pages have the same weight. If for example you're exporting a report with 10 pages, and the polling returns 70, it means that the API has processed seven out of the 10 pages in the export job.

When the export is complete, the polling API call returns a Power BI URL for getting the file. The URL will be available for 24 hours.

Supported features

Selecting which pages to print

Specify the pages you want to print according to the Get Pages or Get Pages in Group return value. You can also specify the order of the pages you're exporting.

Bookmarks

You can use the exportToFile API to programmatically export a report in a specific state, after applying filters to it. This is done using Bookmarks capabilities. To export a report using bookmarks, use the bookmarks JavaScript API.

For example, you can use the bookmark's capturedBookmark.state method to capture the changes a specific user made to a report, and then export it in its current state.

Personal bookmarks and persistent filters are not supported.

Authentication

You can authenticate using a user (or master user) or a service principal.

Row Level Security (RLS)

With Row Level Security (RLS), 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 the following permissions:

  • Write and reshare permissions for the dataset the report is connected to
  • If the report resides on a v1 workspace, you need to be the workspace admin
  • If the report resides on a v2 workspace, you need to be a workspace member or admin

Data protection

The .pdf and .pptx formats support sensitivity labels. If you export a report with a sensitivity label to a .pdf or a .pptx, the exported file will display the report with its sensitivity label.

A report with a sensitivity label cannot be exported to a .pdf or a .pptx using a service principal.

Localization

When using the exportToFile API, you can pass your desired local. The localization settings affect the way the report is displayed, for example by changing formatting according to the selected local.

Concurrent requests

exportToFile supports concurrent export job requests. The table below shows the number of jobs you can run at the same time, depending on the SKU your report resides on. Concurrent requests refer to report pages. For example, 20 pages in one export request on an A6 SKU, will be processed concurrently. This will take roughly the same time as sending 20 export requests with one page each.

A job that exceeds its number of concurrent requests doesn't terminate. For example, if you export three pages in an A1 SKU, the first job will run, and the latter two will wait for the next two execution cycles.

Azure SKU Office SKU Maximum concurrent report pages
A1 EM1 1
A2 EM2 2
A3 EM3 3
A4 P1 6
A5 P2 12
A6 P3 24

Limitations

  • The report you're exporting must reside on a Premium or Embedded capacity.
  • The dataset of the report you're exporting must reside on a Premium or Embedded capacity.
  • For public preview, the number of Power BI report pages exported per hour is limited to 50 per capacity.
  • Exported reports cannot exceed a file size of 250 MB.
  • When exporting to .png, sensitivity labels are not supported.
  • A report with a sensitivity label cannot be exported to a .pdf or a .pptx using a service principal.
  • The number of pages that can be included in an exported report is 30. If the report includes more pages, the API returns an error and the export job is canceled.
  • Personal bookmarks and persistent filters are not supported.
  • The Power BI visuals listed below are not supported. When a report containing these visuals is exported, the parts of the report that contain these visuals will not render, and will display an error symbol.
    • Uncertified Power BI visuals
    • R visuals
    • PowerApps
    • Python visuals
    • Visio

Code examples

When you create an export job, there are three steps to follow:

  1. Sending an export request.
  2. Polling.
  3. 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.

/////// Export sample ///////
private async Task<string> PostExportRequest(
    Guid reportId,
    Guid groupId,
    FileFormat format,
    IList<string> pageNames = null /* Get the page names from the GetPages API */)
{
    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 API.
        Pages = pageNames?.Select(pn => new ExportReportPage(pageName = pn)).ToList(),
    };
    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;
}

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 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
        var 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 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 * c_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)
    {
        // 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;
}

End-to-end example

This is an end-to-end example for exporting a report. This example includes the following stages:

  1. Sending the export request.
  2. Polling.
  3. Getting the file.
private async Task<ExportedFile> ExportPowerBIReport(
    Guid reportId,
    Guid groupId,
    FileFormat format,
    int pollingtimeOutInMinutes,
    CancellationToken token,
    IList<string> pageNames = null /* Get the page names from the GetPages API */)
{
    try
    {
        var exportId = await PostExportRequest(reportId, groupId, format, pageNames);
        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;
    }
}

Next steps

Review how to embed content for your customers and your organization: