Mit DynaPDF können ab sofort auch sog. ZUGFeRD Rechnungen erzeugt werden. ZUGFeRD ist ein deutsches Rechnungsformat, das den Austausch von Rechnungen zwischen Firmen und Behörden vereinfachen und standardisieren soll.

ZUGFeRD Rechnungen bestehen aus einer PDF/A 3 Datei und einer XML Rechnung, die der PDF Datei angehangen wird. Die PDF Datei repräsentiert die visuelle Darstellung der Rechnung, während die XML Datei für die elektronische Verarbeitung vorgesehen ist. Die XML und PDF Datei haben einen genau definierten Aufbau, daher ist eine elektronische Verarbeitung sehr einfach möglich.

Aus Sicht von DynaPDF ist eine ZUGFeRD Rechnung eine ganz normale PDF/A 3 Datei, der eine XML Datei angehangen wird. Da in PDF/A 3 auch Layer und Transparenz verwendet werden darf, ist die Erzeugung relativ unproblematisch. Es gibt nicht viel worauf geachtet werden müsste, außer beim Anhängen der XML Datei. Die XML Datei muss den Namen ZUGFeRD-invoice.xml haben (Groß-Kleinschreibung beachten!).

Die Datei wird vermutlich meistens direkt aus dem Speicher mit AttachFileEx() angehangen. Hierbei muss der Parameter FileName auf "ZUGFeRD-invoice.xml" gesetzt werden. In PDF/A 3 dürfen Dateien nicht einfach angehangen werden, sie müssen mit einem PDF Objekt verknüpft werden. Das geschieht mit AssociateEmbFile(). Der Parameter DestObject muss auf adCatalog gesetzt werden und RelationShip auf arAlternative.

Zu guter Letzt muss noch die PDF Version mit SetPDFVersion() auf das gewünschte Ausgabeformat gesetzt werden, bspw. auf pvZUGFeRD_Basic, fertig!

Sehr häufig werden Rechnungen aus Vorlagen erzeugt und immer wenn eine bereits existierende Datei bearbeitet wird, ist nicht sicher ob das Ergebnis auch PDF/A konform sein wird. Für diesen Zweck gibt es die Funktion CheckConformance() der PDF/A Erweiterung. Mit der Funktion können beliebige PDF Dateien nach PDF/A 1b, 2b, 3b, und ins ZUGFeRD Format konvertiert werden.

CheckConformance() kann auch für komplett neu erzeugte Dateien aufgerufen werden. Auf diese Weise können die richtigen Einstellungen sehr einfach gefunden oder überprüft werden. Wenn alles stimmt, braucht CheckConformance() auch nicht mehr aufgerufen werden.