Question
“How can I alter the default metadata when exporting to PDF/A?”
Solution
Use the TppPDFDevice.OnGetPDFMetadata event to retrieve the default metadata and alter it to meet your specific needs. All metadata is in XML format so it is beneficial to use the Delphi built-in XML classes to edit the data. The following example shows how to alter the Conformance Level when exporting to the PDF/A-3 ZUGFeRD format.
Download: ZUGFeRDCustomMetaData.zip
1. First implement the OnGetPDFMetadata event in the TppReport.OnFileDeviceCreate event.
1 2 3 4 5 6 7 |
procedure TForm1.ppReport1FileDeviceCreate(Sender: TObject); begin //Assign the OnGetMetaData event of the PDF Device if ppReport1.FileDevice is TppPDFDevice then TppPDFDevice(ppReport1.FileDevice).OnGetPDFMetaData := ehPDF_GetMetaData; end; |
2. Next, we plan to use the built-in Delphi XML classes to edit the XML. For this example we will simply alter the value of an existing XML node. To do so, we will need a separate routine to recursively find the XML node we need.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
function FindNodeByName(aNode: IXMLNode; const aName: String): IXMLNode; var liIndex: Integer; begin Result := nil; if aNode = nil then Exit; if (aNode.NodeName = aName) then Result := aNode else if (aNode.HasChildNodes) then begin liIndex := 0; while (Result = nil) and (liIndex < aNode.ChildNodes.Count) do begin Result := FindNodeByName(aNode.ChildNodes[liIndex], aName); liIndex := liIndex + 1; end; end; end; |
3. Finally, we put everthing together to alter a specific node in the existing metadata to meet our needs. The following code alters the “zf:ConformanceLevel” node to have a value of “COMFORT” instead of the default “BASIC”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
procedure TForm1.ehPDF_GetMetaData(Sender: TObject; aMetaData: TStrings); var lXMLDoc: TXMLDocument; lNodeElement: IXMLNode; begin lXMLDoc := TXMLDocument.Create(Self); //Load the existing XML text into the XML Document object lXMLDoc.LoadFromXML(aMetaData.Text); //Find the node that needs to be edited lNodeElement := FindNodeByName(lXMLDoc.DocumentElement,'zf:ConformanceLevel'); //Update the node value if lNodeElement <> nil then lNodeElement.Text := 'COMFORT'; //Save the updated XML back to the PDF aMetaData.Text := lXMLDoc.XML.Text; lXMLDoc.Free; end; |