Műszaki cikk

XFA lapítása AcroForm-má Delphi-ben HotPDF segítségével

Két űrlap hordozhatja ugyanazokat a mezőket, és viselkedhet teljesen másképp. Az AcroForm a mezőit közönséges PDF-objektumként tartja valódi oldaltartalom fölött, így bármelyik szabálykövető olvasó kirajzolja. A dinamikus XFA-űrlap szinte semmit nem tart PDF-ként: a mezők, az elrendezés, sőt az oldalgeometria is egy XML-csomagban él, a látható oldalakat pedig megnyitáskor egy olyan elrendezőmotor állítja elő, amelyet széles körben csak az Adobe szállított valaha. Adja ezt a fájlt egy webes megjelenítőnek, egy archiválórajzolónak vagy egy szövegkinyerőnek, és nem az űrlapot kapja. Egyetlen szürke oldalt kap ezzel a felirattal: "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." Aki dolgozott már állami vagy biztosítási papírmunkával, ránézésre felismeri ezt az oldalt

A helykitöltő nem sérülés. Pontosan az, aminek a formátum előírása szerint történnie kell, ha nincs jelen XFA-feldolgozó, és 2026-ban ez majdnem minden megjelenítőre igaz az asztali Acrobaton kívül. A gyakorlati lépés tehát az, hogy a dinamikus űrlapot sima AcroFormmá alakítjuk, mielőtt bármi továbbihoz eljutna. A HotPDF, a losLab Delphihez és C++Builderhez készült PDF-könyvtára, ezt az átalakítást kódból végzi el, és az XML-űrlapot natív oldalakon lévő natív mezőkként építi újra

HotPDF: egymás melletti összehasonlítás: egy AcroForm, amelynek oldalai, widgetei és értékei mind a PDF-ben élnek, és egy dinamikus XFA űrlap, amely helyőrző oldalt mutat XFA motor nélkül
Az AcroForm az oldalakat, widgeteket és értékeket a PDF-en belül tartja, így bármely olvasó kirajzolja az űrlapot, míg a dinamikus XFA a Kérjük, várjon helyőrző mögé rejti őket

Miért nem élhet együtt a két modell

Az AcroFormot az ISO 32000-1 §12.7 definiálja. Minden mező egy PDF-objektum widget-jegyzettel és megjelenésfolyammal, az oldal valódi PDF-tartalom, az adat pedig ennek a tetején utazik. Az XFA ezt megfordítja: az űrlap egy XML-dokumentum, egy XDP-csomag, amelyet az AcroForm-szótár /XFA bejegyzése tárol, és egy dinamikus űrlap PDF-oldalai a „Please wait” helykitöltőt tartalmazzák, semmi mást, mert a valódi tartalom soha nem lett PDF-ként sorosítva. Az olvasó a fájlt vagy az egyik, vagy a másik modell szerint dolgozza fel. Hagyja figyelmen kívül a /XFA bejegyzést, és az üres burkot látja; tartsa tiszteletben XFA-motor nélkül, és a figyelmeztetést látja. Az ISO 32000-2 azzal zárta le a vitát, hogy kihagyta az XFA-t a PDF 2.0 formátumból, és főként ezért vált az „alakítsuk át, amíg még tudjuk” hozzáállás peremesetből rutinszerű átvételi szabállyá

Bármit is alakít át, előbb sorolja be, mert nem minden XFA-fájl mutatja a helykitöltőt. A statikus XFA-űrlapok előre kirajzolt PDF-oldalakat szállítanak az XML mellett, így mindenhol megjelennek, és csak kitöltéskor viselkednek rosszul. A dinamikus űrlapok egyedül a helykitöltőt szállítják, és átalakításig használhatatlanok. Amiben megbízhat, az a dokumentum, soha nem a kiterjesztés vagy a feladó. Az a fájl, amely nem Adobe-megjelenítőben valódi tartalmat rajzol ki, mégis visel /XFA bejegyzést, statikus vagy hibrid; az a fájl, amely a figyelmeztető oldalt mutatja, dinamikus. Jegyezze fel, melyik kosárba került az egyes átvett fájlok. A kétféle később másképp romlik el, és egy üres archivált űrlapról szóló jegy másodpercek alatt lezárul, ha az átvételi napló már azt írja: „dinamikus XFA, átalakítva, 47 mező leképezve, 2 figyelmeztetés”

Betöltött XFA-dokumentum átalakítása natív mezőkké

Az átalakítás egy már memóriában lévő dokumentumon fut. A FlattenLoadedXFA elemzi az XFA-sablont és az adatcsomagjait, kiszedi az elrendezést, és AcroForm-mezőkként építi újra valódi PDF-oldalakon:

var
  Pdf: THotPDF;
  MappedCount, I: Integer;
  Warnings: TStrings;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.LoadFromFile('dynamic_xfa.pdf');
    MappedCount := Pdf.FlattenLoadedXFA(True);   // True = a mezők szerkeszthetők maradnak
    Warnings := Pdf.XFAFlattenWarnings;
    for I := 0 to Warnings.Count - 1 do
      Log('XFA flatten warning: ' + Warnings[I]); // le nem képezett elemek
    Pdf.SaveLoadedDocument('native_acroform.pdf');
    Log(Format('Mapped %d fields', [MappedCount]));
  finally
    Pdf.Free;
  end;
end;

A visszatérési érték és a figyelmeztetéslista kimenet, nem hibakeresési zaj, ezért mindkettőt őrizze meg. Az átalakítás természeténél fogva információt veszít: az XFA-szkriptelésnek, a számított mezőknek és a dinamikus alűrlapok viselkedésének nincs AcroForm-megfelelője, és az XFAFlattenWarnings minden le nem képezett sablonelemet megnevez. Archiválja az átalakított fájlt a figyelmeztetéslistája nélkül, és egy szép napon egy archivált példány üres összesítő dobozát fogja bámulni anélkül, hogy bármi feljegyzés lenne az okáról. Az Editable jelző szabályozza, hogy az új mezők kitölthetők maradnak-e. Adjon True értéket, ha az emberek utána is dolgoznak az űrlappal, és zárja le az értékeket, ha a cél egy befagyasztott irat

Egy átalakítás ellenőrzése részben szemrevételezés, részben szerkezeti vizsgálat, és mindkét félre szüksége van. A szerkezeti fele könnyű: ellenőrizze, hogy a mezők száma egyezik a MappedCount értékkel. A vizuális fele az, amelyik a valódi kárt elkapja. Nyissa meg a forrásűrlapot az asztali Acrobatban – továbbra is ez az egyetlen megjelenítő, amely futtatja az XFA-motort –, mellette az átalakított fájlt egy hétköznapi olvasóban, és hasonlítsa össze az értékeket és az elrendezést sablononként legalább egy kitöltött mintán. Az a dátum, amelyet az XFA-motor 2026-06-11 alakban jelenített meg, az AcroForm-példányban nyers, formázatlan értékként landolhat, és ezt csakis a szeme fogja elkapni

Bevételi osztályozási folyamat XFA dokumentumokhoz Delphi-ben: azok a fájlok, amelyek valódi tartalmat renderelnek Acrobaton kívül, statikusak vagy hibridek, míg a Please-wait oldalt mutató fájlok dinamikusak, és konvertálni kell őket
A hibrid űrlapok azzal igazolják magukat, hogy valós tartalmat rajzolnak nem Adobe olvasókban, míg a dinamikus űrlapok egyedül a helyőrző oldalon keresztül lepleződnek le

Amikor a bemenet egy XDP-csomag

Nem minden feladat népesített PDF-ből indul. Néha magát az XDP-csomagot kapja meg, űrlaptervező eszközből exportálva vagy partnerrendszer által átadva. Az ApplyXFAAsAcroForm elhagyja a betöltési lépést, és a csomagot közvetlenül az aktuális dokumentumra alkalmazza:

HotPDF folyamat: egy betöltött dinamikus XFA dokumentumot szerkeszthető AcroForm mezőkké lapít Delphi-ben, feltárva a hozzá nem rendelt szkripteket és számított mezőket az XFAFlattenWarningsen át
A FlattenLoadedXFA feldolgozza és átfordítja az XDP csomagokat szerkeszthető AcroForm mezőkbe, az XFAFlattenWarnings pedig rögzíti minden elemet, amelyet nem tudott leképezni
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);

Ugyanez a híváscsoport a másik irányba is működik arra a ritkább esetre, amikor XFA-t kell kibocsátania, nem fogyasztania. Az AddXFAPacket egyedi, megnevezett csomagokat csatol, például 'xdp' vagy 'config' néven. A SetXFADocument egyetlen hívásban telepít teljes, egyfolyamos hasznos terhet. A ClearXFAPackets törli a regisztrációt, hogy elölről kezdhesse, az AddXFASignaturePacket pedig XAdES-anyagot ágyaz be azokhoz a munkamenetekhez, amelyek közvetlenül az XML-űrlapadatot írják alá. Az XFA előállítása 2026-ban réspiaci igény, szinte mindig egyetlen olyan örökölt fogadó fél kényszeríti ki, amely semmi mást nem fogad el, de amikor egy szerződés megnevezi, ezek a hívások konfigurációs döntéssé zsugorítják, külön eszköz helyett

A „lapítás” másik jelentése

A „lapítás” szó sok beszélgetést megzavar, mert egy teljesen másik műveletet is jelöl: az AcroForm-mezők megjelenésének beleégetését az oldal tartalomfolyamába, amíg egyetlen interaktív objektum sem marad. A HotPDF-nek ma nincs erre API-ja, és ezt jobb most tudni, mint egy projekt közepén. Amit a könyvtár helyette ad, az a mezőszintű zárolás a mező létrehozásakor, dokumentumjogosultságokkal alátámasztva:

// Zárold az értéket a mező létrehozásakor: csak olvasható szövegmező
Pdf.CurrentPage.AddTextField('CaseNumber', 'BC-2026-0117',
  Rect(50, 700, 220, 720), 0, [ffReadOnly]);

// Nadrágszíj és nadrágtartó: az űrlapkitöltés korlátozása dokumentumszinten
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.OwnerPassword := 'records-owner';
Pdf.ProtectOptions := [prPrint, prInformationCopy, prExtractContent];
// a kitöltési jog visszatartva: a prFillAnnotations hiányzik a halmazból

Legyen világos, mit ad ez és mit nem. A csak olvasható mező továbbra is űrlapobjektum. Megjelenik a megjelenítő mezőpaneljén, az értéke olvasható az űrlap-API-n keresztül, és egy olyan eszköz, amely újraírja a fájlt, vissza tudja venni a csak olvasható jelzőt. A jogosultsági jelzők emelik a lécet, de attól függenek, hogy a megjelenítő úgy dönt, tiszteletben tartja őket – ezt a korlátot az ISO 32000-1 nyíltan kimondja. Amikor egy szabályozó ragaszkodik hozzá, hogy az archivált irat egyáltalán ne tartalmazzon űrlapobjektumot, a HotPDF-fel ma az őszinte válasz a dokumentum újraépítése: olvassa ki az értékeket, majd rajzolja ki őket közönséges TextOut tartalomként egy friss oldalra, ahelyett hogy a csak olvasható jelzőket lapításnak öltöztetné. A jogosultsági úton egy dolgot érdemes megjegyezni: a CryptKeyLength értékét a BeginDoc előtt kell beállítani; a többi az AES-256 titkosításról és jogosultságokról szóló cikkünkben szerepel

Mit jelent az XFA az archiválási megfelelőség szempontjából

A PDF/A és a PDF/X egyaránt kereken elutasítja az XFA-t. Az ISO 19005 archívumot tápláló feldolgozósornak ezért előbb át kell alakítania, és a sorrend nem alku tárgya: betöltés, FlattenLoadedXFA, mentés, majd archiválási generálás vagy validálás az AcroForm-eredményen. Ne tekintse az átalakítást a megfelelőség bizonyítékának. Az űrlapmodellt rendbe teszi, a betűkészleteket, a színeket és a metaadatokat viszont pontosan úgy hagyja, ahogy voltak, ezért a kimenetet validálja veraPDF eszközzel, mielőtt megbízna benne. Amint az űrlap az AcroForm oldalára került, a viselkedése saját vezérlőket kap. A JavaScript-eseményeket, a beküldési műveleteket és az ellenőrző szkripteket a HotPDF AcroForm-mezőkről és -műveletekről szóló cikke tárgyalja

Az itt bemutatott XFA-regisztrációs, átalakítási és űrlap-API-k a Delphihez és C++Builderhez készült HotPDF Delphi Component részeként érkeznek, amelynek dokumentációja a legutóbbi kiadásokban bővülő XFA-funkciókészletet is követi