Dva obrasca mogu imati ista polja, a ponašati se potpuno različito. AcroForm čuva svoja polja kao obične PDF objekte koji se nalaze na vrhu stvarnog sadržaja stranice, pa ih svaki usklađeni preglednik iscrtava. Dinamički XFA obrazac gotovo ništa ne čuva kao PDF: polja, raspored, pa čak i geometrija stranice žive u XML paketu, a vidljive stranice stvara mehanizam za raspored (layout engine) pri otvaranju koji je samo Adobe ikada šire distribuirao. Pošaljite tu datoteku web pregledniku, arhivskom rendereru ili ekstraktoru teksta i nećete dobiti obrazac. Dobit ćete samo sivu stranicu s porukom \"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.\" Svatko tko je ikada radio s državnim ili osiguravajućim obrascima prepoznaje tu stranicu na prvi pogled.
Rezervirano mjesto (placeholder) nije oštećenje datoteke. To je točno ono što specifikacija formata nalaže kada XFA procesor nije prisutan, a to opisuje gotovo svaki preglednik izvan stolnog Acrobata. Stoga je praktičan korak pretvoriti dinamički obrazac u običan AcroForm prije nego što stigne do bilo kojeg sljedećeg sustava. HotPDF, losLabova PDF knjižnica za Delphi i C++Builder, obavlja tu pretvorbu u kodu, ponovno gradeći XML obrazac kao izvorna polja na izvornim stranicama.
Zašto ova dva modela ne mogu koegzistirati
AcroForm je definiran u standardu ISO 32000-1 §12.7. Svako polje je PDF objekt s bilješkom widgeta (widget annotation) i tokom izgleda (appearance stream), stranica je stvarni PDF sadržaj, a podaci se nalaze na vrhu. XFA to preokreće: obrazac je XML dokument, XDP paket pohranjen u unosu /XFA AcroForm rječnika, a PDF stranice dinamičkog obrasca sadrže samo poruku upozorenja i ništa više jer stvarni sadržaj nikada nije serijaliziran kao PDF. Preglednik obrađuje datoteku kao jedan ili drugi model. Ignorirajte unos /XFA i vidjet ćete praznu ljusku; poštujte ga bez XFA mehanizma i vidjet ćete upozorenje. Standard ISO 32000-2 okončao je ovu raspravu izbacivanjem XFA iz PDF-a 2.0, što je glavni razlog zašto se pravilo \"pretvori dok još možemo\" pretvorilo iz iznimke u uobičajenu politiku unosa podataka.
Prije nego što bilo što pretvorite, klasificirajte to jer ne prikazuje svaka XFA datoteka rezervirano mjesto. Statički XFA obrasci isporučuju unaprijed renderirane PDF stranice uz XML, pa se prikazuju posvuda i ponašaju se neispravno samo kada su popunjeni. Dinamički obrasci isporučuju samo rezervirano mjesto i neupotrebljivi su dok se ne pretvore. Vjerujte dokumentu, nikada ekstenziji ili pošiljatelju. Datoteka koja prikazuje stvarni sadržaj u pregledniku koji nije Adobe, a još uvijek sadrži unos /XFA, jest statički ili hibridni obrazac; datoteka koja prikazuje stranicu s upozorenjem je dinamički obrazac. Zabilježite u koju je kategoriju uvrštena svaka zaprimljena datoteka. Te dvije vrste kasnije zakazuju na različite načine, a prijava o praznom arhiviranom obrascu zatvara se u sekundi kada u dnevniku unosa već stoji: \"dinamički XFA, pretvoren, 47 polja preslikano, 2 upozorenja\".
Pretvaranje učitanog XFA dokumenta u izvorna polja
Pretvorba se izvodi na dokumentu koji je već učitan u memoriju. Funkcija FlattenLoadedXFA analizira XFA predložak i njegove pakete podataka, raspoređuje obrazac i ponovno ga gradi kao AcroForm polja na stvarnim PDF stranicama:
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;
Povratna vrijednost i popis upozorenja su izlazni podaci, a ne pozadinski šum za otklanjanje pogrešaka, stoga zadržite oboje. Pretvorba po svojoj prirodi gubi određene informacije: XFA skripte, izračunata polja i dinamičko ponašanje podobrazaca nemaju ekvivalent u AcroForm-u, a XFAFlattenWarnings imenuje svaki element predloška koji se nije uspio preslikati. Ako arhivirate pretvorenu datoteku bez popisa upozorenja, jednog dana ćete gledati u prazno polje za zbroj u arhiviranoj kopiji bez ikakvog zapisa o tome zašto je tako. Zastavica Editable kontrolira hoće li nova polja ostati popunjiva. Proslijedite True ako će ljudi i dalje raditi s obrascem, a zaključajte vrijednosti kada je cilj zamrznuti zapis.
Provjera pretvorbe je dijelom vizualna, a dijelom strukturna, i trebate oba dijela. Strukturni dio je jednostavan: potvrdite da broj polja odgovara vrijednosti MappedCount. Vizualni dio je onaj koji otkriva stvarna oštećenja. Otvorite izvorni obrazac u stolnom Acrobat-u (koji je još uvijek jedini preglednik koji pokreće XFA mehanizam) pokraj pretvorene datoteke u običnom čitaču i usporedite vrijednosti i raspored na barem jednom ispunjenom uzorku po predlošku. Datum koji je XFA mehanizam prikazao kao 2026-06-11 može u AcroForm kopiji završiti kao sirova, neoblikovana vrijednost, a to mogu uočiti samo vaše oči.
Kada je ulaz XDP paket
Ne počinje svaki zadatak od popunjenog PDF-a. Ponekad dobijete XDP paket samostalno, izvezen iz alata za dizajn obrazaca ili predan od strane partnerskog sustava. Metoda ApplyXFAAsAcroForm preskače korak učitavanja i primjenjuje paket izravno na trenutačni dokument:
XDPBytes := TFile.ReadAllBytes('benefit-claim.xdp');
MappedCount := Pdf.ApplyXFAAsAcroForm(XDPBytes, True);
Drugo značenje pojma "spljoštavanje" (flatten)
Riječ \"spljoštiti\" (flatten) stvara zabunu u mnogim razgovorima jer označava sasvim drugu operaciju: trajno upisivanje izgleda AcroForm polja u tok sadržaja stranice dok ne nestanu svi interaktivni objekti. HotPDF danas nema API za tu namjenu i to trebate znati sada, a ne usred projekta. Ono što vam knjižnica daje umjesto toga jest zaključavanje na razini polja u trenutku kada se polje stvara, podržano dopuštenjima dokumenta:
// 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
Budite jasni oko toga što time dobivate, a što ne. Polje samo za čitanje (read-only) i dalje je objekt obrasca. Ono se pojavljuje na ploči s poljima preglednika, njegova je vrijednost čitljiva kroz API obrasca, a alat koji prepiše datoteku može ponovno ukloniti flag samo za čitanje. Flagovi dopuštenja podižu razinu sigurnosti, ali ovise o tome hoće li ih preglednik poštovati, što je ograničenje koje ISO 32000-1 jasno navodi. Kada regulator inzistira na tome da arhivirani zapis ne smije sadržavati nikakve objekte obrasca, iskren odgovor s HotPDF-om danas je rekonstruirati dokument: pročitati vrijednosti, a zatim ih nacrtati kao običan TextOut sadržaj na novoj stranici, umjesto da flagove samo za čitanje prikazujete kao spljoštavanje. Jedna stvar koju treba zapamtiti kod dopuštenja jest da CryptKeyLength mora biti postavljen prije BeginDoc; ostatak je opisan u našem članku o AES-256 enkripciji i dopuštenjima.
Što XFA znači za usklađenost arhiviranja
PDF/A i PDF/X u potpunosti odbacuju XFA. Cjevovod koji napaja arhivu prema standardu ISO 19005 stoga prvo mora izvršiti pretvorbu, a redoslijed nije pregovarački: učitavanje, FlattenLoadedXFA, spremanje, a zatim pokretanje arhivskog generiranja ili provjere valjanosti na rezultirajućem AcroForm-u. Nemojte tretirati pretvorbu kao dokaz usklađenosti. Ona ispravlja model obrasca, ali ostavlja fontove, boje i metapodatke točno onakvima kakvi su bili, stoga provjerite izlaz pomoću veraPDF-a prije nego što mu povjerujete. Nakon što je obrazac na strani AcroForm-a, njegovo ponažanje dobiva vlastiti skup kontrola. JavaScript okidači, akcije slanja i skripte za provjeru valjanosti opisani su u članku o HotPDF AcroForm poljima i akcijama.
API-ji za registraciju, pretvorbu i obrasce XFA prikazani ovdje isporučuju se s komponentom HotPDF Component za Delphi i C++Builder, čija dokumentacija prati skup značajki XFA kako se razvijao kroz nedavna izdanja.