Zwei Formulare können dieselben Felder tragen und sich dennoch völlig unterschiedlich verhalten. Ein AcroForm hält seine Felder als gewöhnliche PDF-Objekte, die auf echtem Seiteninhalt liegen, sodass jeder konforme Reader es zeichnet. Ein dynamisches XFA-Formular hält fast nichts als PDF: Die Felder, das Layout, sogar die Seitengeometrie leben in einem XML-Paket, und die sichtbaren Seiten werden beim Öffnen von einer Layout-Engine erzeugt, die nur Adobe je in nennenswertem Umfang ausgeliefert hat. Geben Sie diese Datei an einen Web-Viewer, einen Archiv-Renderer oder einen Textextraktor, und Sie erhalten nicht das Formular. Sie erhalten eine einzelne graue Seite mit dem Text „Please wait... If this message is not eventually replaced by the proper contents of the document, your PDF viewer may not be able to display this type of document.“ Wer je Behörden- oder Versicherungsunterlagen eingelesen hat, erkennt diese Seite auf den ersten Blick
Der Platzhalter ist keine Beschädigung. Er ist genau das, was das Format vorsieht, wenn kein XFA-Prozessor vorhanden ist, und im Jahr 2026 trifft das auf nahezu jeden Viewer außerhalb des Desktop-Acrobat zu. Der praktische Schritt besteht daher darin, das dynamische Formular in ein einfaches AcroForm umzuwandeln, bevor es irgendetwas Nachgelagertes erreicht. HotPDF, die losLab-PDF-Bibliothek für Delphi und C++Builder, erledigt diese Umwandlung im Code und baut das XML-Formular als native Felder auf nativen Seiten neu auf
Warum die beiden Modelle nicht nebeneinander bestehen können
AcroForm ist in ISO 32000-1 §12.7 definiert. Jedes Feld ist ein PDF-Objekt mit einer Widget-Annotation und einem Appearance-Stream, die Seite ist echter PDF-Inhalt, und die Daten liegen darauf. XFA kehrt das um: Das Formular ist ein XML-Dokument, ein XDP-Paket, das im Eintrag /XFA des AcroForm-Dictionarys gespeichert ist, und die PDF-Seiten eines dynamischen Formulars enthalten den „Please wait“-Platzhalter und sonst nichts, weil der eigentliche Inhalt nie als PDF serialisiert wurde. Ein Reader verarbeitet eine Datei nach dem einen oder dem anderen Modell. Ignoriert er den Eintrag /XFA, sehen Sie die leere Hülle; berücksichtigt er ihn ohne XFA-Engine, sehen Sie die Warnung. ISO 32000-2 hat die Debatte beendet, indem XFA aus PDF 2.0 gestrichen wurde, und das ist der Hauptgrund, warum „umwandeln, solange es noch geht“ vom Randfall zur routinemäßigen Eingangsrichtlinie wurde
Bevor Sie irgendetwas umwandeln, klassifizieren Sie es, denn nicht jede XFA-Datei zeigt den Platzhalter. Statische XFA-Formulare liefern vorgerenderte PDF-Seiten neben dem XML mit, sodass sie überall angezeigt werden und sich nur beim Ausfüllen fehlverhalten. Dynamische Formulare liefern allein den Platzhalter und sind bis zur Umwandlung unbrauchbar. Vertrauen Sie dem Dokument, niemals der Dateiendung oder dem Absender. Eine Datei, die in einem Nicht-Adobe-Viewer echten Inhalt rendert und dennoch einen Eintrag /XFA trägt, ist statisch oder hybrid; eine Datei, die die Warnseite zeigt, ist dynamisch. Halten Sie fest, in welcher Kategorie jede Eingangsdatei gelandet ist. Die beiden Arten brechen später auf unterschiedliche Weise, und ein Ticket über ein leeres archiviertes Formular ist in Sekunden geschlossen, wenn im Eingangsprotokoll bereits „dynamisches XFA, umgewandelt, 47 Felder zugeordnet, 2 Warnungen“ steht
Ein geladenes XFA-Dokument in native Felder umwandeln
Die Umwandlung läuft gegen ein bereits im Speicher befindliches Dokument. FlattenLoadedXFA parst die XFA-Vorlage und ihre Datenpakete, layoutet das Formular und baut es als AcroForm-Felder auf echten PDF-Seiten neu auf:
var
Pdf: THotPDF;
MappedCount, I: Integer;
Warnings: TStrings;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.LoadFromFile('dynamic_xfa.pdf');
MappedCount := Pdf.FlattenLoadedXFA(True); // True = Felder bleiben bearbeitbar
Warnings := Pdf.XFAFlattenWarnings;
for I := 0 to Warnings.Count - 1 do
Log('XFA flatten warning: ' + Warnings[I]); // nicht zugeordnete Elemente
Pdf.SaveLoadedDocument('native_acroform.pdf');
Log(Format('Mapped %d fields', [MappedCount]));
finally
Pdf.Free;
end;
end;
Der Rückgabewert und die Warnliste sind Ausgabe, kein Debug-Rauschen, also behalten Sie beides. Die Umwandlung verliert naturgemäß Informationen: XFA-Scripting, berechnete Felder und dynamisches Subform-Verhalten haben kein AcroForm-Gegenstück, und XFAFlattenWarnings benennt jedes Vorlagenelement, das nicht zugeordnet wurde. Archivieren Sie die umgewandelte Datei ohne ihre Warnliste, und eines Tages starren Sie auf ein leeres Summenfeld in einer archivierten Kopie, ohne dass festgehalten ist, warum. Das Flag Editable steuert, ob die neuen Felder ausfüllbar bleiben. Übergeben Sie True, wenn danach weiter mit dem Formular gearbeitet wird, und sperren Sie die Werte, wenn ein eingefrorener Datensatz das Ziel ist
Die Prüfung einer Umwandlung ist teils visuell, teils strukturell, und Sie brauchen beide Hälften. Die strukturelle Hälfte ist einfach: Bestätigen Sie, dass die Feldanzahl mit MappedCount übereinstimmt. Die visuelle Hälfte ist diejenige, die echten Schaden aufdeckt. Öffnen Sie das Quellformular im Desktop-Acrobat, nach wie vor dem einzigen Viewer mit XFA-Engine, neben der umgewandelten Datei in einem gewöhnlichen Reader, und vergleichen Sie Werte und Layout an mindestens einem ausgefüllten Muster pro Vorlage. Ein Datum, das die XFA-Engine als 2026-06-11 angezeigt hat, kann in der AcroForm-Kopie als roher, unformatierter Wert landen, und nur Ihre Augen werden das bemerken
Wenn die Eingabe ein XDP-Paket ist
Nicht jeder Auftrag beginnt mit einem ausgefüllten PDF. Manchmal erhalten Sie das XDP-Paket allein, exportiert aus einem Formular-Designwerkzeug oder übergeben von einem Partnersystem. ApplyXFAAsAcroForm lässt den Ladeschritt weg und wendet das Paket direkt auf das aktuelle Dokument an:
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);
Dieselbe Gruppe von Aufrufen läuft auch in die andere Richtung, für den selteneren Fall, dass Sie XFA erzeugen statt konsumieren müssen. AddXFAPacket hängt einzelne benannte Pakete wie 'xdp' oder 'config' an. SetXFADocument installiert eine vollständige Single-Stream-Nutzlast in einem Aufruf. ClearXFAPackets löscht die Registrierung, damit Sie von vorn beginnen können, und AddXFASignaturePacket bettet XAdES-Material für Workflows ein, die die XML-Formulardaten direkt signieren. XFA im Jahr 2026 zu erzeugen ist ein Nischenbedarf, fast immer erzwungen durch einen einzelnen Altkonsumenten, der nichts anderes akzeptiert, aber wenn ein Vertrag es vorschreibt, halten diese Aufrufe es bei einer Konfigurationsentscheidung statt eines separaten Werkzeugs
Die andere Bedeutung von „flatten“
Das Wort „flatten“ bringt viele Gespräche durcheinander, weil es eine völlig andere zweite Operation bezeichnet: das Einbrennen der Erscheinungsbilder von AcroForm-Feldern in den Content-Stream der Seite, bis keine interaktiven Objekte mehr übrig sind. HotPDF hat dafür heute keine API, und das sollten Sie jetzt wissen statt mitten im Projekt. Was die Bibliothek stattdessen bietet, ist das Sperren auf Feldebene beim Anlegen des Feldes, abgesichert durch Dokumentberechtigungen:
// Wert beim Anlegen des Feldes sperren: schreibgeschütztes Textfeld
Pdf.CurrentPage.AddTextField('CaseNumber', 'BC-2026-0117',
Rect(50, 700, 220, 720), 0, [ffReadOnly]);
// Doppelt hält besser: Formularausfüllen dokumentweit einschränken
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.OwnerPassword := 'records-owner';
Pdf.ProtectOptions := [prPrint, prInformationCopy, prExtractContent];
// Ausfüllrecht vorenthalten: prFillAnnotations fehlt im Set
Seien Sie sich im Klaren darüber, was das bringt und was nicht. Ein schreibgeschütztes Feld ist weiterhin ein Formularobjekt. Es erscheint im Feldbereich des Viewers, sein Wert ist über die Formular-API lesbar, und ein Werkzeug, das die Datei neu schreibt, kann das Schreibschutz-Flag wieder entfernen. Berechtigungs-Flags erhöhen die Hürde, hängen aber davon ab, dass der Viewer sich entscheidet, sie zu respektieren, eine Einschränkung, die ISO 32000-1 unmissverständlich benennt. Wenn eine Aufsichtsbehörde darauf besteht, dass ein archivierter Datensatz überhaupt keine Formularobjekte enthält, lautet die ehrliche Antwort mit HotPDF heute, das Dokument neu aufzubauen: Lesen Sie die Werte aus und zeichnen Sie sie dann als gewöhnlichen TextOut-Inhalt auf eine frische Seite, statt Schreibschutz-Flags als Flattening auszugeben. Auf dem Berechtigungsweg ist zu beachten, dass CryptKeyLength vor BeginDoc gesetzt werden muss; der Rest steht in unserem Artikel zu AES-256-Verschlüsselung und Berechtigungen
Was XFA für die Archivkonformität bedeutet
PDF/A und PDF/X lehnen XFA beide rundweg ab. Eine Pipeline, die ein ISO-19005-Archiv beliefert, muss daher zuerst umwandeln, und die Reihenfolge ist nicht verhandelbar: laden, FlattenLoadedXFA, speichern, dann die Archiverzeugung oder -validierung auf dem AcroForm-Ergebnis ausführen. Behandeln Sie die Umwandlung nicht als Konformitätsnachweis. Sie korrigiert das Formularmodell und lässt Schriftarten, Farbe und Metadaten genau so, wie sie waren, also validieren Sie die Ausgabe mit veraPDF, bevor Sie ihr vertrauen. Sobald das Formular auf der AcroForm-Seite ist, bekommt sein Verhalten eigene Steuerungsmöglichkeiten. JavaScript-Trigger, Submit-Aktionen und Validierungsskripte werden in dem HotPDF-Artikel zu AcroForm-Feldern und -Aktionen behandelt
Die hier gezeigten XFA-Registrierungs-, Umwandlungs- und Formular-APIs werden mit der HotPDF Delphi Component für Delphi und C++Builder ausgeliefert, deren Dokumentation den XFA-Funktionsumfang nachzeichnet, wie er über die jüngsten Releases gewachsen ist