Hi, Readers.
Today I would like to briefly share a recent requirement, how to bulk export/download reports with different layouts to a zip file.
2024 is almost over, and a client wants to batch print the Posted Sales Invoices/Posted Purchase Invoices for this year. But for the sales process, there are special cases, depending on the customer, different layouts and reports can be used. Let’s look at a simple example.
In Report Selection – Sales, the Report ID of Invoice Uage is 1306.
I then set up specialized Document Layouts for the customers.
Customer 10000:
Customer 20000:
Customer 30000: A new custom report.
So when printing the invoice, Customer 10000, 20000, 30000 will have different layouts, and then 40000 and 50000 will have the default layout. For example,
Customer 10000:
Customer 20000:
Customer 30000:
Customer 40000:
PS: Dynamics 365 Business Central: Report Selection for standard documents (Set up default reports)
So, if we want to export and save these different layouts at the same time, can this be done in the standard? Unfortunately, as far as I know, this is not possible at the moment. Although you can change the layout and filters on the request page when printing, there is only one layout and you cannot print other reports at the same time.
So we need customization. We can save these reports into zip files and let users download them. We have discussed similar requirements before.
PS:
1. Dynamics 365 Business Central: FileManagement.BLOBExport only save last file? -> Adding multiple files into a zip file
The difficulty this time is how the system automatically finds the reports and layouts that need to be printed. We can refer to some standard processing. For example,
table 112 “Sales Invoice Header” -> local procedure DoPrintToDocumentAttachment
table 77 “Report Selections” -> procedure SaveAsDocumentAttachment
We can use the following two methods.
Here is how I handle it.
Test:
The four invoices downloaded are all in different layouts.
Test video:
Source code: Github (Please note that the source code is for reference only, you can improve it according to your own needs)
pageextension 50115 PostedSalesInvoicesExt extends "Posted Sales Invoices"
{
actions
{
addafter("&Invoice")
{
action(DownloadSelectedInvoicesAsPDF)
{
ApplicationArea = All;
Caption = 'Download Selected Invoices as PDF';
Image = Download;
Promoted = true;
PromotedCategory = Process;
trigger OnAction()
var
ReportSelection: Record "Report Selections";
SalesInvHeader: Record "Sales Invoice Header";
SalesInvHeader2: Record "Sales Invoice Header";
TempReportSelections: Record "Report Selections" temporary;
TempBlob: Codeunit "Temp Blob";
RecordVariant: Variant;
ZipFileName: Text[50];
PdfFileName: Text[50];
DataCompression: Codeunit "Data Compression";
InS: InStream;
OutS: OutStream;
begin
ZipFileName := 'SalesInvoice_' + Format(CurrentDateTime) + '.zip';
DataCompression.CreateZipArchive();
SalesInvHeader.Reset();
CurrPage.SetSelectionFilter(SalesInvHeader);
if SalesInvHeader.FindSet() then
repeat
SalesInvHeader2.Get(SalesInvHeader."No.");
SalesInvHeader2.SetRecFilter();
ReportSelection.FindReportUsageForCust(Enum::"Report Selection Usage"::"S.Invoice", SalesInvHeader2."Bill-to Customer No.", TempReportSelections);
Clear(TempBlob);
TempReportSelections.SaveReportAsPDFInTempBlob(TempBlob, TempReportSelections."Report ID", SalesInvHeader2, TempReportSelections."Custom Report Layout Code", Enum::"Report Selection Usage"::"S.Invoice");
TempBlob.CreateInStream(InS);
PdfFileName := Format(SalesInvHeader2."No." + '.pdf');
DataCompression.AddEntry(InS, PdfFileName);
until SalesInvHeader.Next() = 0;
TempBlob.CreateOutStream(OutS);
DataCompression.SaveZipArchive(OutS);
TempBlob.CreateInStream(InS);
DownloadFromStream(InS, '', '', '', ZipFileName);
end;
}
}
}
}
If you’re worried about performance, here’s a video of 218 invoices being downloaded simultaneously. (Of course this is related to the processing and number of rows in the report)
Although Purchase Invoice cannot be set up with different reports and layouts, it can be used in the same way. I only provide the code and do not test it in detail.
Source code: Github (Please note that the source code is for reference only, you can improve it according to your own needs)
pageextension 50116 PostedPurchaseInvoicesExt extends "Posted Purchase Invoices"
{
actions
{
addafter("&Invoice")
{
action(DownloadSelectedInvoicesAsPDF)
{
ApplicationArea = All;
Caption = 'Download Selected Invoices as PDF';
Image = Download;
Promoted = true;
PromotedCategory = Process;
trigger OnAction()
var
ReportSelection: Record "Report Selections";
PurchInvHeader: Record "Purch. Inv. Header";
PurchInvHeader2: Record "Purch. Inv. Header";
TempReportSelections: Record "Report Selections" temporary;
TempBlob: Codeunit "Temp Blob";
RecordVariant: Variant;
ZipFileName: Text[50];
PdfFileName: Text[50];
DataCompression: Codeunit "Data Compression";
InS: InStream;
OutS: OutStream;
begin
ZipFileName := 'PurchaseInvoice_' + Format(CurrentDateTime) + '.zip';
DataCompression.CreateZipArchive();
PurchInvHeader.Reset();
CurrPage.SetSelectionFilter(PurchInvHeader);
if PurchInvHeader.FindSet() then
repeat
PurchInvHeader2.Get(PurchInvHeader."No.");
PurchInvHeader2.SetRecFilter();
ReportSelection.FindReportUsageForVend(Enum::"Report Selection Usage"::"P.Invoice", PurchInvHeader2."Buy-from Vendor No.", TempReportSelections);
Clear(TempBlob);
TempReportSelections.SaveReportAsPDFInTempBlob(TempBlob, TempReportSelections."Report ID", PurchInvHeader2,
TempReportSelections."Custom Report Layout Code", Enum::"Report Selection Usage"::"P.Invoice");
TempBlob.CreateInStream(InS);
PdfFileName := Format(PurchInvHeader2."No." + '.pdf');
DataCompression.AddEntry(InS, PdfFileName);
until PurchInvHeader.Next() = 0;
TempBlob.CreateOutStream(OutS);
DataCompression.SaveZipArchive(OutS);
TempBlob.CreateInStream(InS);
DownloadFromStream(InS, '', '', '', ZipFileName);
end;
}
}
}
}
Very simple, give it a try!!!😁
END
Hope this will help.
Thanks for reading.
ZHU
コメント