Dynamics 365 Business Central: How to save a report as encoded text (Base64 String) via AL

Dynamics 365 Business Central

Hi, Readers.
Today I would like to briefly talk about a qustion I saw in the Dynamics 365 Community last month, how to save a report as encoded text (Base64 String) via AL. The partner wants to pass a base64 string through APIs. More details: How to run a report and convert it to Base64 string. (dynamics.com)

Base64 is a binary to a text encoding scheme that represents binary data in an American Standard Code for Information Interchange (ASCII) string format. It’s designed to carry data stored in binary format across the channels, and it takes any form of data and transforms it into a long string of plain text. You can find more about Base64 in wiki.

We have discussed Dynamics 365 Business Central: How to convert Image (item picture) to encoded text (Base64 String) via AL

As an example this time, similar to the above, I added a field on the Sales Order page to store the encoded text (Base64 String). Add an action to print the current order after clicking it and convert it into encoded text (Base64 String)

We can use the third-party tool below to check whether the conversion is successful.
Base64 Guru:

In simple terms, this requires three steps.

1. Save the report as pdf

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

2. 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)

2. Convert PDF to encoded text (Base64 String)

PS: Dynamics 365 Business Central: How to convert Image (item picture) to encoded text (Base64 String) via AL

3. Save Convert PDF to encoded text (Base64 String) in a blob field

PS:
1. How to save large text/string in the table

2. If you encounter the following error, please do not use the System-defined variable “Rec”. Declaring a variable will solve the problem.

The changes to the Sales Header record cannot be saved because some information on the page is not up-to-date. Close the page, reopen it, and try again.

Identification fields and values:
Document Type=’Order’,No.=’101001′

For example,

Okay, let’s do a quick test.

Test video:

Source code: Github (Please note that the source code is for reference only, you can improve it according to your own needs)

tableextension 50114 ZYSalesHeaderExt extends "Sales Header"
{
    fields
    {
        field(50101; "Large Text"; Blob)
        {
            Caption = 'Large Text';
            DataClassification = CustomerContent;
        }
    }
}
pageextension 50114 ZYSalesOrderExt extends "Sales Order"
{
    layout
    {
        addlast(General)
        {
            field(LargeText; LargeText)
            {
                Caption = 'Large Text';
                ApplicationArea = All;
                MultiLine = true;
                ShowCaption = false;
                trigger OnValidate()
                begin
                    SetLargeText(LargeText);
                end;
            }
        }
    }

    actions
    {
        addafter(Post)
        {
            action(SaveReportAsEncodedText)
            {
                Caption = 'Save Sales Report As Encoded Text';
                Image = Transactions;
                ApplicationArea = All;
                Promoted = true;
                PromotedCategory = Process;
                PromotedIsBig = true;

                trigger OnAction()
                var
                    Base64Convert: Codeunit "Base64 Convert";
                    InStr: InStream;
                    OutStr: OutStream;
                    SalesHeader: Record "Sales Header";
                    RecRef: RecordRef;
                    FldRef: FieldRef;
                    TempBlob: Codeunit "Temp Blob";
                begin
                    if SalesHeader.Get(Rec."Document Type", Rec."No.") then begin
                        RecRef.GetTable(SalesHeader);
                        FldRef := RecRef.Field(SalesHeader.FieldNo("No."));
                        FldRef.SetRange(SalesHeader."No.");
                        TempBlob.CreateOutStream(OutStr);
                        Report.SaveAs(Report::"Standard Sales - Order Conf.", '', ReportFormat::Pdf, OutStr, RecRef);
                        TempBlob.CreateInStream(InStr);
                        LargeText := Base64Convert.ToBase64(InStr, false);
                        SetLargeText(LargeText);
                    end;
                end;
            }
        }
    }
    var
        LargeText: Text;

    trigger OnAfterGetRecord()
    begin
        LargeText := GetLargeText();
    end;

    procedure SetLargeText(NewLargeText: Text)
    var
        OutStream: OutStream;
        SalesHeader: Record "Sales Header";
    begin
        SalesHeader.Get(Rec."Document Type", Rec."No.");
        SalesHeader."Large Text".CreateOutStream(OutStream, TEXTENCODING::UTF8);
        OutStream.WriteText(LargeText);
        SalesHeader.Modify();
    end;

    procedure GetLargeText() NewLargeText: Text
    var
        TypeHelper: Codeunit "Type Helper";
        InStream: InStream;
    begin
        Rec.CalcFields("Large Text");
        Rec."Large Text".CreateInStream(InStream, TEXTENCODING::UTF8);
        exit(TypeHelper.TryReadAsTextWithSepAndFieldErrMsg(InStream, TypeHelper.LFSeparator(), Rec.FieldName("Large Text")));
    end;
}

PS: This time I fixed the filters and options on the request page. You can also use the following method to open the request page and save it directly as encoded text (Base64 String) without printing.

Test:

This is not a good example of where the value is stored, it is just for testing.

Source code: Github (Please note that the source code is for reference only, you can improve it according to your own needs)

tableextension 50114 ZYSalesHeaderExt extends "Sales Header"
{
    fields
    {
        field(50101; "Large Text"; Blob)
        {
            Caption = 'Large Text';
            DataClassification = CustomerContent;
        }
    }
}
pageextension 50114 ZYSalesOrderExt extends "Sales Order"
{
    layout
    {
        addlast(General)
        {
            field(LargeText; LargeText)
            {
                Caption = 'Large Text';
                ApplicationArea = All;
                MultiLine = true;
                ShowCaption = false;
                trigger OnValidate()
                begin
                    SetLargeText(LargeText);
                end;
            }
        }
    }

    actions
    {
        addafter(Post)
        {
            action(SaveReportAsEncodedText)
            {
                Caption = 'Save Sales Report As Encoded Text';
                Image = Transactions;
                ApplicationArea = All;
                Promoted = true;
                PromotedCategory = Process;
                PromotedIsBig = true;

                trigger OnAction()
                var
                    Base64Convert: Codeunit "Base64 Convert";
                    InStr: InStream;
                    OutStr: OutStream;
                    TempBlob: Codeunit "Temp Blob";
                    ReportParameters: text;
                begin
                    ReportParameters := Report.RunRequestPage(Report::"Standard Sales - Order Conf.");
                    TempBlob.CreateOutStream(OutStr);
                    Report.SaveAs(Report::"Standard Sales - Order Conf.", ReportParameters, ReportFormat::Pdf, OutStr);
                    TempBlob.CreateInStream(InStr);
                    LargeText := Base64Convert.ToBase64(InStr, false);
                    SetLargeText(LargeText);
                end;
            }
        }
    }
    var
        LargeText: Text;

    trigger OnAfterGetRecord()
    begin
        LargeText := GetLargeText();
    end;

    procedure SetLargeText(NewLargeText: Text)
    var
        OutStream: OutStream;
        SalesHeader: Record "Sales Header";
    begin
        SalesHeader.Get(Rec."Document Type", Rec."No.");
        SalesHeader."Large Text".CreateOutStream(OutStream, TEXTENCODING::UTF8);
        OutStream.WriteText(LargeText);
        SalesHeader.Modify();
    end;

    procedure GetLargeText() NewLargeText: Text
    var
        TypeHelper: Codeunit "Type Helper";
        InStream: InStream;
    begin
        Rec.CalcFields("Large Text");
        Rec."Large Text".CreateInStream(InStream, TEXTENCODING::UTF8);
        exit(TypeHelper.TryReadAsTextWithSepAndFieldErrMsg(InStream, TypeHelper.LFSeparator(), Rec.FieldName("Large Text")));
    end;
}

END

Hope this will help.

Thanks for reading.

ZHU

コメント

Copied title and URL