Technical Article

Sploštenie XFA na AcroForm v Delphi pomocou HotPDF

Dva formuláre môžu obsahovať rovnaké polia, no ich správanie môže byť úplne odlišné. AcroForm uchováva svoje polia ako bežné PDF objekty umiestnené nad samotným obsahom stránky, takže ich dokáže vykresliť akýkoľvek kompatibilný prehliadač. Dynamický formulár XFA neuchováva v PDF takmer nič: polia, rozvrhnutie a dokonca aj geometria stránky sú uložené v balíku XML. Viditeľné stránky sa generujú až pri otvorení pomocou vykresľovacieho engine-u, ktorý vo veľkej miere distribuovala iba spoločnosť Adobe. Ak takýto súbor odošlete do webového prehliadača, archívneho vykresľovača alebo extraktora textu, formulár sa nezobrazí. Namiesto neho uvidíte len sivú stránku s textom „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.“ Každý, kto niekedy spracovával úradné dokumenty alebo poistné zmluvy, túto stránku dôverne pozná.

Tento zástupný text (placeholder) nie je chybou súboru. Formát presne takto definuje správanie v situácii, keď nie je k dispozícii procesor XFA, čo v roku 2026 platí pre takmer každý prehliadač s výnimkou desktopovej aplikácie Acrobat. Praktickým krokom je previesť dynamický formulár na štandardný AcroForm predtým, než sa dostane k ďalšiemu spracovaniu. HotPDF, PDF knižnica pre Delphi a C++Builder od spoločnosti losLab, vykonáva túto konverziu programovo a prestavuje formulár XML na natívne polia na natívnych stránkach.

Prečo tieto dva modely nemôžu koexistovať

Model AcroForm je definovaný v norme ISO 32000-1 §12.7. Každé pole je objektom PDF s anotáciou widgetu a prúdom vzhľadu (appearance stream). Stránka obsahuje reálny PDF obsah a dáta sú umiestnené na ňom. XFA tento prístup obracia: formulár je XML dokument (balík XDP) uložený v položke /XFA slovníka AcroForm a PDF stránky dynamického formulára obsahujú iba zástupný text „Please wait“, pretože skutočný obsah nebol nikdy serializovaný do PDF. Prehliadač spracuje súbor buď podľa jedného, alebo druhého modelu. Ak ignoruje položku /XFA, uvidí prázdny shell. Ak ju rešpektuje, no nemá engine pre XFA, zobrazí varovanie. Norma ISO 32000-2 ukončila diskusiu odstránením podpory XFA z verzie PDF 2.0, čo je hlavný dôvod, prečo sa konverzia „kým je to možné“ zmenila z výnimočného prípadu na bežný proces spracovania na vstupe.

Pred akoukoľvek konverziou dokument najskôr klasifikujte, pretože nie každý súbor XFA zobrazuje zástupný text. Statické formuláre XFA obsahujú predrenderované PDF stránky vedľa dát XML, takže sa zobrazujú všade a nesprávne sa správajú až po vyplnení. Dynamické formuláre obsahujú iba zástupný text a sú pred konverziou nepoužiteľné. Dôverujte samotnému dokumentu, nie prípone súboru alebo odosielateľovi. Súbor, ktorý zobrazuje skutočný obsah aj v prehliadačoch iných ako Adobe, no stále obsahuje položku /XFA, je statický alebo hybridný. Súbor, ktorý zobrazuje varovnú stránku, je dynamický. Zaznamenajte si, do ktorej kategórie vstupný súbor patrí. Tieto dva typy neskôr zlyhávajú odlišným spôsobom a požiadavka na podporu ohľadom prázdneho archived formulára sa vyrieši za pár sekúnd, ak v logu už svieti záznam „dynamické XFA, prevedené, priradených 47 polí, 2 varovania“.

Prevod načítaného dokumentu XFA na natívne polia

Konverzia prebieha nad dokumentom, ktorý je už načítaný v pamäti. Metóda FlattenLoadedXFA analyzuje šablónu XFA a jej dátové balíky, navrhne rozvrhnutie formulára a znova ho zostaví ako polia AcroForm na reálnych stránkach PDF:

var
  Pdf: THotPDF;
  MappedCount, I: Integer;
  Warnings: TStrings;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.LoadFromFile('dynamic_xfa.pdf');
    MappedCount := Pdf.FlattenLoadedXFA(True);   // True = fields stay editable
    Warnings := Pdf.XFAFlattenWarnings;
    for I := 0 to Warnings.Count - 1 do
      Log('XFA flatten warning: ' + Warnings[I]); // unmapped elements
    Pdf.SaveLoadedDocument('native_acroform.pdf');
    Log(Format('Mapped %d fields', [MappedCount]));
  finally
    Pdf.Free;
  end;
end;

Návratová hodnota aj zoznam varovaní sú dôležitým výstupom, nie len ladiacim šumom, preto si uchovajte oboje. Konverzia zo svojej podstaty stráca informácie: skripty XFA, kalkulované polia a dynamické správanie podformulárov nemajú v modeli AcroForm priamy ekvivalent a vlastnosť XFAFlattenWarnings menuje každý prvok šablóny, ktorý sa nepodarilo priradiť. Ak archivujete skonvertovaný súbor bez tohto zoznamu varovaní, jedného dňa sa môžete pozerať na prázdne pole s celkovou sumou bez možnosti zistiť, prečo sa tak stalo. Príznak Editable určuje, či nové polia zostanú upravovateľné. Odovzdajte hodnotu True, ak majú používatelia s formulárom ďalej pracovať, a uzamknite hodnoty vtedy, ak je cieľom vytvoriť nemenný archívny záznam.

Kontrola úspešnosti konverzie je sčasti vizuálna a sčasti štrukturálna. Tá štrukturálna je jednoduchá: overte, či počet polí zodpovedá hodnote MappedCount. Vizuálna časť je tá, ktorá pomáha odhaliť skutočné poškodenie dát. Otvorte pôvodný formulár v desktopovom programe Acrobat (čo je stále jediný prehliadač spúšťajúci engine XFA) vedľa skonvertovaného súboru v bežnom prehliadači a porovnajte hodnoty a rozvrhnutie aspoň na jednej vyplnenej vzorke pre každú šablónu. Dátum, ktorý engine XFA zobrazil ako 2026-06-11, sa môže v kópii AcroForm objaviť ako surová, nenaformátovaná hodnota, čo odhalíte len vizuálnou kontrolou.

Keď je vstupom balík XDP

Nie každá úloha začína z naplneného súboru PDF. Niekedy dostanete balík XDP samostatne, napríklad exportovaný z nástroja na návrh formulárov alebo odovzdaný partnerským systémom. Metóda ApplyXFAAsAcroForm vynecháva krok načítania a aplikuje balík priamo na aktuálny dokument:

XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);

Rovnaká skupina volaní funguje aj opačným smerom pre menej časté prípady, kedy potrebujete XFA generovať a nie spracovávať. Metóda AddXFAPacket pripája jednotlivé pomenované balíky, ako napríklad 'xdp' alebo 'config'. Volanie SetXFADocument nainštaluje kompletné dáta v jednom volaní. Metóda ClearXFAPackets vymaže registráciu, aby ste mohli začať znova, a AddXFASignaturePacket vloží podpisy XAdES pre procesy, ktoré priamo podpisujú XML dáta formulára. Generovanie XFA v roku 2026 je špecifická potreba vynútená staršími systémami, ktoré iný formát neprijímajú. Ak to však zmluva vyžaduje, tieto volania vám umožnia vyriešiť to konfiguráciou namiesto použitia samostatného nástroja.

Druhý význam pojmu „sploštenie“ (flatten)

Slovo „sploštenie“ (flatten) často vedie k nedorozumeniam, pretože označuje aj druhú, úplne odlišnú operáciu: vpečatenie vzhľadu polí AcroForm priamo do obsahu stránky, kým nezostanú žiadne interaktívne objekty. HotPDF dnes pre túto operáciu neponúka API, čo je dobré vedieť hneď na začiatku projektu. Knižnica namiesto toho poskytuje uzamknutie na úrovni jednotlivých polí pri ich vytváraní, podporené oprávneniami dokumentu:

// Lock the value at field creation: read-only text field
Pdf.CurrentPage.AddTextField('CaseNumber', 'BC-2026-0117',
  Rect(50, 700, 220, 720), 0, [ffReadOnly]);

// Belt and suspenders: restrict form filling document-wide
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.OwnerPassword := 'records-owner';
Pdf.ProtectOptions := [prPrint, prInformationCopy, prExtractContent];
// fill permission withheld: prFillAnnotations is absent from the set

Ujasnite si, čo vám toto riešenie prináša a čo nie. Pole určené iba na čítanie (read-only) je stále objektom formulára. Zobrazuje sa v paneli polí prehliadača, jeho hodnota je čitateľná cez API formulára a nástroj na prepisovanie súborov môže príznak read-only znova odstrániť. Príznaky oprávnení zvyšujú bezpečnosť, ale závisia od toho, či ich prehliadač rešpektuje, čo otvorene uvádza aj norma ISO 32000-1. Ak regulátor trvá na tom, aby archivovaný záznam neobsahoval vôbec žiadne objekty formulára, správnym riešením v HotPDF je dokument znova vygenerovať: prečítať hodnoty a vykresliť ich ako bežný text cez TextOut na novú stránku, namiesto predstierania sploštenia pomocou príznakov iba na čítanie. Dôležité je pamätať na to, že CryptKeyLength musí byť nastavená ešte pred zavolaním BeginDoc. Viac informácií nájdete v našom článku o šifrovaní AES-256 a oprávneniach.

Čo znamená XFA pre archívny súlad

Štandardy PDF/A aj PDF/X formát XFA striktne odmietajú. Proces spracovania smerujúci do archívu podľa normy ISO 19005 archive preto musí najskôr vykonať konverziu a poradie krokov je nemenné: načítať, spustiť FlattenLoadedXFA, uložiť a až potom spustiť archívne generovanie alebo overenie na výsledku AcroForm. Nepovažujte konverziu za automatický dôkaz súladu s normami. Opravuje iba model formulára a ponecháva písma, farby aj metadáta nezmenené. Predtým, než výsledku začnete dôverovať, ho overte pomocou veraPDF. Keď je formulár prevedený na model AcroForm, jeho správanie sa riadi vlastnou sadou ovládacích prvkov. Spúšťače JavaScriptu, odosielacie akcie a validačné skripty sú popísané v článku o poliach a akciách AcroForm v HotPDF.

API pre registráciu XFA, konverziu a formuláre popísané v tomto článku sú súčasťou komponentu HotPDF Component pre Delphi a C++Builder, ktorého dokumentácia mapuje rozširovanie funkcií XFA v novších verziách.