OnCustomDocumentMergerEx event
This article describes the syntax of the OnCustomDocumentMergerEx event, which will enable use of custom renders given a dataset and a layout. The layout must be specified as a Custom Layout in the rendering section within the report definition.
Usage
Use the OnCustomDocumentMergerEx event to specify what happens when the user has specified a custom report layout type that is to be rendered into an artifact in application code. For more information about subscribing to this event, see Developing Report Custom Render Extensions Overview.
Publisher
Codeunit 44 ReportManagement.
Raised
When a user runs a report that uses a custom layout format handled by application code (extension).
Syntax
[IntegrationEvent(false, false)]
local procedure OnCustomDocumentMergerEx(ObjectID: Integer; ReportAction: Option SaveAsPdf,SaveAsWord,SaveAsExcel,Preview,Print,SaveAsHtml; ObjectPayload: JsonObject; XmlData: InStream; LayoutData: InStream; var DocumentStream: OutStream; var IsHandled: Boolean)
Parameters
ObjectID
Type: Integer
The ID of the report object to be run.
ReportAction
Type: [Option]
Specifies the action to take in the custom document merge process.
Valid values include:
SaveAsPdf
Generates a PDF document in the target stream.SaveAsWord
Generates a Microsoft Word document in the target stream.SaveAsExcel
Generates a Microsoft Excel document in the target stream.SaveAsHtml
Generates an HTML document in the target stream.Preview
Generates a PDF document in the target stream, which the platform downloads to the client for preview.Print
Generates a PDF document in the target stream, which the platform prints using the printer specified for the present report ID.
ObjectPayload
Type: JsonObject
Instance of the report payload. For more information, see Report payload structure.
XmlData
Type: InStream
A stream object that contains the XML dataset generated by the platform runtime. This stream contains the input data for the rendering process.
LayoutData
Type: InStream
A stream object that contains the report layout to be used in the rendering process. The platform provides this data from the standard report layout selection logic and it contains the currently selected layout.
Success
Type: Boolean
Specifies whether the extension handled the merge action successfully.
Note
The platform will handle further processing of the result stream and the extension code must return the rendered artifact in the target stream. The platform will handle:
- Saving to a specified file in save-as scenarios
- Saving to a given stream
- Download to the client
- Print or preview
Report payload
The report payload contains metadata for the report object and a list of attributes that identifies that current invocation. The payload consists of several attributes and has the following structure.
{
"filterviews":
[
{"name":"Header","tableid":112,"view":"VERSION(1) SORTING(Field3) WHERE(Field3=1(103027))"},
{"name":"Line","tableid":113,"view":"VERSION(1) SORTING(Field3,Field4) WHERE(Field4=1(0..10000))"},
{"name":"ShipmentLine","tableid":7190,"view":"VERSION(1) SORTING(Field1,Field2,Field3) WHERE(Field2=1(10000))"}
],
"version":1,
"objectname":"Standard Sales - Invoice",
"objectid":1306,
"documenttype":"application/pdf",
"invokedby":"00000000-0000-0000-0000-000000000001",
"invokeddatetime":"2020-01-17T15:33:52.48+01:00",
"companyname":"CRONUS International Ltd.",
"printername":"My Printer",
"duplex":false,
"color":false,
"defaultcopies":1,
"papertray":
{
"papersourcekind":257,
"paperkind":0,
"landscape":false,
"units":0,
"height":1268,
"width":929
},
"intent":"Print",
"layoutmodel": "Rdlc",
"layoutname": "RDLCLayout",
"layoutmimetype": "Application/ReportLayout/Rdlc",
"layoutapplicationid": "00001111-aaaa-2222-bbbb-3333cccc4444",
"reportrunid": "6a3742c1-65ef-44a6-af58-3ef4a902932b"
}
Attributes
objectname
Specifies the name of the object.
objectid
Specifies the ID of the object.
documenttype
Specifies the MIME type of the document. Currently only application/pdf
is supported for printing, other intents can have types specific to the report layout model and selected output target type.
invokedby
Specifies the ID of the user who invoked the print action.
invokeddatetime
Specifies the date and time that the print action was invoked, for example, 2019-10-22T22:25:54.338+02:00
. The value is the date and time on the client machine.
companyname
Specifies the Business Central company.
version
Specifies the version of the report payload. Currently, the only supported version for the payload is 1
.
duplex
Specifies whether to use duplex (2-sided) printing. true
specifies duplex printing; otherwise false
.
Note
duplex
is currently not used and ignored at runtime.
color
Specifies whether color printing is set. true
specifies color printing; otherwise false
.
Note
color
is currently not used and ignored at runtime.
defaultcopies
Specifies the number of copies to print by default. The default is 1
.
Note
defaultcopies
is currently not used and ignored at runtime.
filterviews
Specifies views that are used on the document.
name
Specifies the name of data item that the filter view applies to.
tableid
Specifies the ID of the table for the view.
view
Specifies the name of the view.
papertray
Specifies the paper tray settings from the printer payload.
papersourcekind
Specifies a standard paper source for the paper tray. The value can be either the text representation (such as AutomaticFeed
) or the corresponding number (such as 7
).
paperkind
Specifies the paper size. The value can be either the text representation (such as A4
) or the corresponding number (such as 9
).
landscape
Specifies whether landscape orientation is used. true
specifies landscape orientation; otherwise false
.
units
Specifies the units of measurement for values in height
and width
attributes. Valid values include:
HI
for hundredths of an inch (default value).TI
for thousandths of an inch.IN
for inches.CM
for centimeters.MM
for millimeters.PC
for picas.PT
for points.
height
Specifies the height of the paper. The values include positive integers up to 2,147,483,647.
width
Specifies the width of the paper. The values include positive integers up to 2,147,483,647.
intent
Specifies the intent of the current report invocation, which can be one of the following values.
- None
- Preview
- Save
- Schedule
- Download
- Parameters
layoutmodel
Specifies the layout model selected for teh current report invocation, which can be one of the following values.
- Rdlc
- Word
- Excel
- Custom
layoutname
Specifies the layout name for the currently selected layout.
layoutmimetype
Specifies the layout mimetype for the currently selected layout. The built-in layout types are:
- Application/ReportLayout/Rdlc
- Application/ReportLayout/Word
- Application/ReportLayout/Excel
layoutapplicationid
Specifies the ID of the application that provides the selected layout.
reportrunid
Specifies a unique ID of type Guid
that identifies the current report invocation. This value can be used to correlate calls to report event that support json
payloads.
Sample code
The simplest possible custom document render can be implemented as shown in the following sample, which will use the existing application logic to render XML datasets into Microsoft Word or PDF documents using a given template (Word template).
[EventSubscriber(ObjectType::Codeunit, Codeunit::ReportManagement, 'OnCustomDocumentMergerEx', '', true, true)]
local procedure OnCustomDocumentMergerEx(ObjectID: Integer; ReportAction: Option SaveAsPdf,SaveAsWord,SaveAsExcel,Preview,Print,SaveAsHtml; ObjectPayload: JsonObject; XmlData: InStream; LayoutData: InStream; var DocumentStream: OutStream; var IsHandled: Boolean)
var
DocumentReportMgt: Codeunit "Document Report Mgt.";
TempBlob: Codeunit "Temp Blob";
DataInStream: InStream;
DataOutStream: OutStream;
SharedXmlData: InStream;
SharedLayoutData: InStream;
ObjectName: JsonToken;
DocumentTypeParts: List of [Text];
DocumentType: JsonToken;
Extension: Text;
Token: JsonToken;
MimeType: Text;
LayoutName: Text;
LayoutModel: Text;
JsonText: Text;
JsonFile: File;
begin
if IsHandled then
exit;
// Setup shared streams
// Empty stream, no actions possible on the stream so return immediately
if XmlData.Length < 1 then
exit;
// Use a shared stream and reset the read pointer to beginning of stream
SharedXmlData := XmlData;
if SharedXmlData.Position > 1 then
SharedXmlData.ResetPosition();
SharedLayoutData := LayoutData;
if SharedLayoutData.Position > 1 then
SharedLayoutData.ResetPosition();
Init();
// Sample code to persist the JSON object to disk
ObjectPayload.WriteTo(JsonText);
JsonFile.TextMode := true;
JsonFile.Create(TempFolderPath + 'OnCustomDocumentMergerEx.json', TextEncoding::UTF8);
JsonFile.Write(JsonText);
JsonFile.Close();
// Get report options from the JSON object
ObjectPayload.Get('objectname', ObjectName);
ObjectPayload.Get('documenttype', DocumentType);
ObjectPayload.Get('layoutmimetype', Token);
MimeType := Token.AsValue().AsText();
ObjectPayload.Get('layoutname', Token);
LayoutName := Token.AsValue().AsText();
ObjectPayload.Get('layoutmodel', Token);
LayoutModel := Token.AsValue().AsText();
DocumentTypeParts := DocumentType.AsValue().AsText().Split('/');
// Notice that the Extension string below have to be remapped to a standard file extension
// based on the document mimetype
Extension := DocumentTypeParts.Get(DocumentTypeParts.Count);
TempBlob.CreateOutStream(DataOutStream);
// The
case ReportAction of
ReportAction::SaveAsPdf, ReportAction::Preview, ReportAction::Print:
begin
if not DocumentReportMgt.TryXmlMergeWordDocument(SharedLayoutData, SharedXmlData, DataOutStream) then
error('Unable to handle custom document merge');
DocumentReportMgt.ConvertWordToPdf(TempBlob, ObjectID);
TempBlob.CreateInStream(DataInStream);
CopyStream(DocumentStream, DataInStream);
IsHandled := true;
end;
ReportAction::SaveAsHtml:
begin
if not DocumentReportMgt.TryXmlMergeWordDocument(SharedLayoutData, SharedXmlData, DataOutStream) then
error('Unable to handle custom document merge');
DocumentReportMgt.ConvertWordToHtml(TempBlob);
TempBlob.CreateInStream(DataInStream);
CopyStream(DocumentStream, DataInStream);
IsHandled := true;
end;
ReportAction::SaveAsWord:
begin
if not DocumentReportMgt.TryXmlMergeWordDocument(SharedLayoutData, SharedXmlData, DocumentStream) then
error('Unable to handle custom document merge');
IsHandled := true;
end;
else
error('Unsupported report action %0', ReportAction);
end;
end;
Related information
Working With and Troubleshooting Payloads
Developing Report Custom Render Extensions Overview
Developing Printer Extensions Overview
Creating a Printer Extension
Events in AL
Publishing Events
Raising Events
Subscribing to Events