4

I'm trying to implement the "Export to PDF" functionality for my Power BI reports embedded (https://learn.microsoft.com/en-us/power-bi/developer/embedded/export-to). The process explained in the docs is pretty clear, but I have only one doubt that has not been addressed: how we need to pass the slicers/filters applied in order to have the current report view as PDF file? I mean, suppose that I have a report with a custom slicers applied with a certain value in a certain time, for example to view all data related to the Germany country, how we can pass this slicer? It must be converted in ODATA query string? I think it's pretty uncomfortable because from the JavaScript API it would mean that we need to retrieve all the state of all the slicer objects in a report and convert them into ODATA query string, managing also particular case (slicer not applied to specific visual and other cases...) is not a simple job. Are there any alternatives?

AGuyCalledGerald
  • 7,882
  • 17
  • 73
  • 120
MFF
  • 137
  • 8
  • Did you finally find a solution ? @MFF – Thomas Rollet Mar 23 '21 at 14:19
  • @ThomasRollet No, I used the print function made available by PowerBI Javascript which works in a completely different way compared to the API made available by microsoft. – MFF Mar 31 '21 at 16:53
  • @ThomasRollet check if [BI Helper](https://bihelper.tech) suffices your use case. They have both slicer and API support. – GTO Jul 13 '21 at 05:00

2 Answers2

2

Query String filtering doesn't work with Publish to web or Export to PDF. But You can capture the filters in bookmark and then export the report to pdf with the filters or slicers you applies.

// Capture the Bookmark state 
const capturedBookmark = await report.bookmarksManager.capture();

The captured state (which is just a string) is then passed to the PowerBI .NET SDK method ExportToFileInGroupAsync as part of the PowerBIReportExportConfiguration that is necessary.

References:

ExportReporttoPdf-React-Samplegist

Export Power BI Report to File

Service-url-filters

PowerBI-Bookmarks

Kotana Sai
  • 1,207
  • 3
  • 9
  • 20
1

I faced exact same issue. the Business wanted to export embedded powerBI dashboard with filters selected. I solved the problem with following function. You need access to the container of the embedded report. In the code below it is @ViewChild('reportContainer') reportContainer?: PowerBIReportEmbedComponent;. Key to passing the filters is to use await report.bookmarksManager.capture() and then using defaultBookmark parameter as shown below.

async exportAndDownloadReport(): Promise<void> {

    if (!this.reportContainer) {
        return;
    }

    this.percentComplete = 1;

    const report = this.reportContainer.getReport();
    const reportId = report.getId();
    console.log(`reportId= ${reportId}`);

    // Capture the Bookmark state
    const capturedBookmark = await report.bookmarksManager.capture();

    // Define the export settings
    const settings = {
        format: 'PDF',
        powerBIReportConfiguration: {
            defaultBookmark: {
                state: capturedBookmark.state
            }
        }
    };

    const headers = new HttpHeaders({
        'Content-Type': 'application/json',
        Authorization: 'Bearer ' + this.embedInfo?.accessToken
    });

    try {
        // Send the export request
        const response: any = await this.http.post(`https://api.powerbi.com/v1.0/myorg/reports/${reportId}/ExportTo`,
            settings, {headers}).toPromise();

        const exportId = response.id;
        console.log(`exportId= ${exportId}`);

        // Poll to check if the export is complete
        const intervalId = setInterval(async () => {

            const exportStatus = await this.checkExportStatus(reportId, exportId, headers);
            this.percentComplete = exportStatus.percentComplete === 0 ? 1 : exportStatus.percentComplete;

            if (exportStatus.status === 'Succeeded') {

                await this.downloadExportedFile(reportId, exportId, headers);
                this.reset(intervalId, 'Export Succeeded');

            } else if (exportStatus.status !== 'Running') {
                this.reset(intervalId, 'Export failed');
            }
        }, 1000);
        setTimeout(() => {
            this.reset(intervalId, 'Export timeout');
        }, 300000);
    } catch (error) {
        console.log(`Export failed: ${error}`);
    }
}

You can also implement a polling subscription using setInterval(async () so that the file can be downloaded once the export is complete.

private async checkExportStatus(reportId: string, exportId: string, headers: HttpHeaders): Promise<any> {
    try {
        const response: any = await this.http.get(`https://api.powerbi.com/v1.0/myorg/reports/${reportId}/exports/${exportId}`, {
            responseType: 'json',
            headers
        }).toPromise();
        return {percentComplete: response.percentComplete, status: response.status};
    } catch (error) {
        console.log(`Failed to check export status: ${error}`);
    }
}

Finally you will need code to download the PDF file when it is ready.

private async downloadExportedFile(reportId: string, exportId: any, headers: HttpHeaders): Promise<void> {
    // Download the exported file
    const file = await this.http.get(`https://api.powerbi.com/v1.0/myorg/reports/${reportId}/exports/${exportId}/file`, {
        responseType: 'blob',
        headers
    }).toPromise();
    const link = document.createElement('a');
    link.href = window.URL.createObjectURL(file);
    link.download = reportId + '.pdf';
    link.click();
}
Sacky San
  • 1,535
  • 21
  • 26