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?
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With