Hi, Readers.
Last year, we have discussed how to save the report as a PDF, Excel, Word, HTML, or XML file.
More details: Dynamics 365 Business Central: How to save the report as a PDF, Excel, Word, HTML, or XML file (Report.RunRequestPage Method and Report.SaveAs Method) | Dynamics 365 Lab (yzhums.com)
As you might know, Report.SaveAsPDF() function or Report.SaveAsExcel() function not supported in Business Central Cloud SaaS (Cloud). So I tried to save report in Stream objects then convert to file using BlobExport function.
For example:
FileManagement.BLOBExport(TempBlob, Format(Rec."Report ID") + '_' + Rec."Report Name" + '_' + Format(CURRENTDATETIME, 0, '<Day,2><Month,2><Year4><Hours24><Minutes,2><Seconds,2>') + '.docx', true);
It works well for me. But yesterday I received an interesting question. They tried to export multiple reports using this method at the same time (In a loop), but each time only the last file was saved.
Let’s look at a simple scenario: In the sales order list, add a new export action, then select multiple sales orders and export them into separate pdf files (report 1305 “Standard Sales – Order Conf.”).
Here is the code:
pageextension 50212 SalesOrderEx extends "Sales Order List"
{
actions
{
addfirst(processing)
{
action("Download Selected SO")
{
Caption = 'Download Selected Sales Orders';
ApplicationArea = All;
Image = ExportFile;
Promoted = true;
PromotedIsBig = true;
PromotedCategory = Process;
trigger OnAction()
var
SalesHeader: Record "Sales Header";
OutS: OutStream;
RecRef: RecordRef;
FldRef: FieldRef;
TempBlob: Codeunit "Temp Blob";
FileManagement: Codeunit "File Management";
begin
SalesHeader.Reset;
TempBlob.CreateOutStream(OutS);
CurrPage.SetSelectionFilter(SalesHeader);
if SalesHeader.FindSet() then
repeat
RecRef.GetTable(SalesHeader);
FldRef := RecRef.Field(SalesHeader.FieldNo("No."));
FldRef.SetRange(SalesHeader."No.");
if RecRef.FindFirst() then begin
Report.SaveAs(Report::"Standard Sales - Order Conf.", '', ReportFormat::Pdf, OutS, RecRef);
FileManagement.BLOBExport(TempBlob, STRSUBSTNO('SalesOrder_%1.Pdf', SalesHeader."No."), true);
Commit();
end
until SalesHeader.Next() = 0;
end;
}
}
}
}
Test Video:
Obviously there is nothing wrong with the code and the report has been exported many times, but the web client (browser) has not saved them separately, only last file is saved.
I’m not sure if Microsoft plans to improve this feature in the future, but we need an alternate solution for now.
So, let’s change our thinking, if there is only one exported file, there is no problem, so we can archive the files into a zip file first, then download it.
Let’s update the code:
pageextension 50212 SalesOrderExt extends "Sales Order List"
{
actions
{
addfirst(processing)
{
action("Download Selected SO")
{
Caption = 'Download Selected Sales Orders';
ApplicationArea = All;
Image = ExportFile;
Promoted = true;
PromotedIsBig = true;
PromotedCategory = Process;
trigger OnAction()
var
TempBlob: Codeunit "Temp Blob";
OutS: OutStream;
InS: InStream;
RecRef: RecordRef;
FldRef: FieldRef;
//FileManagement: Codeunit "File Management";
SalesHeader: Record "Sales Header";
DataCompression: Codeunit "Data Compression";
ZipFileName: Text[50];
PdfFileName: Text[50];
begin
ZipFileName := 'SalesOrder_' + Format(CurrentDateTime) + '.zip';
DataCompression.CreateZipArchive();
SalesHeader.Reset;
CurrPage.SetSelectionFilter(SalesHeader);
if SalesHeader.FindSet() then
repeat
TempBlob.CreateOutStream(OutS);
RecRef.GetTable(SalesHeader);
FldRef := RecRef.Field(SalesHeader.FieldNo("No."));
FldRef.SetRange(SalesHeader."No.");
if RecRef.FindFirst() then begin
Report.SaveAs(Report::"Standard Sales - Order Conf.", '', ReportFormat::Pdf, OutS, RecRef);
TempBlob.CreateInStream(InS);
PdfFileName := Format(SalesHeader."Document Type") + ' ' + SalesHeader."No." + '.pdf';
DataCompression.AddEntry(InS, PdfFileName);
//FileManagement.BLOBExport(TempBlob, STRSUBSTNO('SalesOrder_%1.Pdf', Rec."No."), TRUE);
end
until SalesHeader.Next() = 0;
TempBlob.CreateOutStream(OutS);
DataCompression.SaveZipArchive(OutS);
TempBlob.CreateInStream(InS);
DownloadFromStream(InS, '', '', '', ZipFileName);
end;
}
}
}
}
Test Video:
Well, we can now export each separate files, but it needs to be unzipped once.🤦♂️ If you have the same problem, please try it.
Update 2021/11/24:
A new solution from Bojan L: Only need to add a Comfirm method before BLOBExport, the problem of not being able to download all files will be solved.
Let’s try it.
Test Video:
Source Code:
pageextension 50212 SalesOrderEx extends "Sales Order List"
{
actions
{
addfirst(processing)
{
action("Download Selected SO")
{
Caption = 'Download Selected Sales Orders';
ApplicationArea = All;
Image = ExportFile;
Promoted = true;
PromotedIsBig = true;
PromotedCategory = Process;
trigger OnAction()
var
SalesHeader: Record "Sales Header";
OutS: OutStream;
RecRef: RecordRef;
FldRef: FieldRef;
TempBlob: Codeunit "Temp Blob";
FileManagement: Codeunit "File Management";
begin
SalesHeader.Reset;
TempBlob.CreateOutStream(OutS);
CurrPage.SetSelectionFilter(SalesHeader);
if SalesHeader.FindSet() then
repeat
RecRef.GetTable(SalesHeader);
FldRef := RecRef.Field(SalesHeader.FieldNo("No."));
FldRef.SetRange(SalesHeader."No.");
if RecRef.FindFirst() then begin
Report.SaveAs(Report::"Standard Sales - Order Conf.", '', ReportFormat::Pdf, OutS, RecRef);
if Confirm('Do you want to export Sales Order?') then
FileManagement.BLOBExport(TempBlob, STRSUBSTNO('SalesOrder_%1.Pdf', SalesHeader."No."), true);
Commit();
end
until SalesHeader.Next() = 0;
end;
}
}
}
}
END
Hope this will help.
Thanks for reading.
ZHU
コメント