Dynamics 365 Business Central: FileManagement.BLOBExport only save last file? -> Adding multiple files into a zip file

Dynamics 365 Business Central

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

コメント

Copied title and URL