Technical Article

Sploščitev obrazcev XFA v AcroForm v Delphiju s HotPDF

Dva obrazca lahko vsebujeta enaka polja, vendar delujeta popolnoma drugače. AcroForm ohranja svoja polja kot običajne predmete PDF na vrhu dejanske vsebine strani, zato jih izriše vsak skladen bralnik. Dinamični obrazec XFA v obliki PDF ne hrani skoraj ničesar: polja, postavitev in celo geometrija strani živijo v paketu XML, vidne strani pa ob odpiranju ustvari mehanizem za postavitev, ki ga je v širšem obsegu ponujal le Adobe. Če to datoteko pošljete v spletni pregledovalnik, upodabljalnik arhivov ali bralnik besedila, obrazca ne boste dobili. Prejeli boste eno samo sivo stran z napisom »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.« Vsakdo, ki je kdaj obdeloval vladne ali zavarovalniške dokumente, to stran prepozna na prvi pogled.

Ta nadomestna stran ni poškodovana datoteka. Gre natanko za to, kar format predpisuje, ko ni prisotnega procesorja XFA, in od leta 2026 to opisuje skoraj vsak pregledovalnik zunaj namiznega programa Acrobat. Praktična rešitev je torej pretvorba dinamičnega obrazca v navaden AcroForm, preden doseže naslednje sisteme v verigi. HotPDF, losLabova knjižnica PDF za Delphi in C++Builder, to pretvorbo izvede v kodi, pri čemer znova zgradi obrazec XML kot izvorna polja na izvornih straneh.

Zakaj oba modela ne moreta soobstajati

Format AcroForm je definiran v ISO 32000-1 §12.7. Vsako polje je predmet PDF z anotacijo gradnika in tokom videza, stran je pristna vsebina PDF, podatki pa se nahajajo na vrhu te vsebine. XFA to obrne: obrazec je dokument XML, paket XDP, shranjen v vnosu /XFA slovarja AcroForm, strani PDF dinamičnega obrazca pa vsebujejo le nadomestno besedilo »Please wait« in nič drugega, saj dejanska vsebina nikoli ni bila serializirana kot PDF. Bralnik obravnava datoteko po enem ali drugem modelu. Če prezrete vnos /XFA, vidite prazno lupino; če ga upoštevate brez mehanizma XFA, vidite opozorilo. ISO 32000-2 je končal to razpravo z opustitvijo XFA iz PDF 2.0, kar je glavni razlog, da se je pretvorba iz posebnega primera spremenila v rutinsko politiko sprejema dokumentov.

Pred pretvorbo poljubne datoteke jo razvrstite, saj vsaka datoteka XFA ne prikazuje nadomestnega besedila. Statični obrazci XFA vsebujejo vnaprej upodobljene strani PDF poleg XML-ja, zato se prikazujejo povsod in povzročajo težave šele ob izpolnjevanju. Dinamični obrazci vsebujejo le nadomestno besedilo in so do pretvorbe neuporabni. Vedno zaupajte dokumentu, nikoli končnici ali pošiljatelju. Datoteka, ki prikazuje dejansko vsebino v bralnikih, ki niso Adobejevi, a še vedno vsebuje vnos /XFA, je statična ali hibridna; datoteka, ki prikazuje opozorilno stran, pa je dinamična. Zabeležite, v katero kategorijo spada posamezna prejeta datoteka. Ti dve vrsti se kasneje pokvarita na različne načine, prijava o praznem arhiviranem obrazcu pa se zapre v nekaj sekundah, če v dnevniku sprejema že piše »dynamic XFA, converted, 47 fields mapped, 2 warnings«.

Pretvorba naloženega dokumenta XFA v izvorna polja

Pretvorba se izvede na dokumentu, ki je že v pomnilniku. Funkcija FlattenLoadedXFA razčleni predlogo XFA in njene podatkovne pakete, razporedi obrazec ter ga znova zgradi kot polja AcroForm na dejanskih straneh 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;

Povratna vrednost in seznam opozoril sta dejanski izhod in ne le razhroščevalni šum, zato obdržite oba. Pretvorba po svoji naravi povzroči izgubo nekaterih informacij: skripti XFA, izračunana polja in dinamično obnašanje podobrazcev nimajo ustreznika v AcroForm, XFAFlattenWarnings pa poimenuje vsak element predloge, ki ni bil preslikan. Če arhivirate pretvorjeno datoteko brez seznama opozoril, boste morda nekoč gledali prazno polje za skupne seštevke v arhivirani kopiji brez zapisa o tem, zakaj je tako. Zastava Editable nadzoruje, ali nova polja ostanejo izpolnljiva. Podajte True, če bodo uporabniki po pretvorbi nadaljevali z delom na obrazcu, in zaklenite vrednosti, ko je cilj zamrznjen zapis.

Preverjanje pretvorbe je delno vizualno in delno strukturno, pri cheering potrebujete oba dela. Strukturni del je preprost: potrdite, da se število polj ujema z MappedCount. Vizualni del pa je tisti, ki zazna dejanske napake. Odprite izvorni obrazec v namiznem programu Acrobat, ki je še vedno edini pregledovalnik z mehanizmom XFA, poleg pretvorjene datoteke v navadnem bralniku ter primerjajte vrednosti in postavitev na vsaj enem izpolnjenem vzorcu za vsako predlogo. Datum, ki ga je mehanizem XFA prikazal kot 2026-06-11, se lahko v kopiji AcroForm pojavi kot surova, neoblikovana vrednost, kar lahko opazite le vizualno.

Ko je vhodni podatek paket XDP

Vsako opravilo se ne začne z izpolnjenim PDF-jem. Včasih prejmete samostojen paket XDP, izvožen iz orodja za oblikovanje obrazcev ali posredovan iz partnerskega sistema. Funkcija ApplyXFAAsAcroForm izpusti korak nalaganja in uporabi paket neposredno na trenutnem dokumentu:

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

Ista skupina klicev deluje tudi v nasprotni smeri, za redkejše primere, ko morate XFA ustvariti namesto prebrati. Funkcija AddXFAPacket pripne posamezne poimenovane pakete, kot sta 'xdp' ali 'config'. SetXFADocument namesti celotno vsebino enega toka v enem klicu. ClearXFAPackets počisti registracijo, da lahko začnete znova, AddXFASignaturePacket pa vgradi gradivo XAdES for delovne tokove, ki neposredno podpisujejo podatke obrazca XML. Ustvarjanje XFA v letu 2026 je specifična potreba, ki jo skoraj vedno zahteva kakšen podedovan sistem, ki zavrača vse ostalo, toda ko pogodba to zahteva, ti klici to spremenijo v preprosto konfiguracijsko izbiro namesto uporabe ločenega orodja.

Drugi pomen besede »sploščitev«

Beseda »sploščitev« pogosto povzroča zmedo v pogovorih, saj poimenuje povsem drugo operacijo: zapečenje videza polj AcroForm v tok vsebine strani, dokler ne ostane noben interaktiven predmet več. HotPDF danes nima API-ja za to funkcijo, kar je dobro vedeti že na začetku projekta. Namesto tega vam knjižnica ponuja zaklepanje na ravni polja ob njegovem ustvarjanju, podprto z dovoljenji 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

Zavedajte se, kaj s tem pridobite in česa ne. Polje samo za branje je še vedno predmet obrazca. Prikaže se na plošči s polji pregledovalnika, njegova vrednost je berljiva prek API-ja obrazca, orodje, ki ponovno zapiše datoteko, pa lahko zastavico samo za branje znova počisti. Zastavice dovoljenj dvigujejo raven zaščite, vendar so odvisne od tega, ali jih pregledovalnik upošteva, kar je omejitev, ki jo standard ISO 32000-1 jasno navaja. Če regulator zahteva, da arhivirani zapis sploh ne vsebuje predmetov obrazca, je pošten odgovor s HotPDF danes ponovna izgradnja dokumenta: preberite vrednosti in jih nato izrišite kot običajno vsebino TextOut na novi strani, namesto da prikazujete zastavice samo za branje kot sploščitev. Pri poti z dovoljenji si velja zapomniti, da mora biti CryptKeyLength nastavljen pred BeginDoc; ostalo pa je opisano v našem članku o šifriranju AES-256 in dovoljenjih.

Kaj XFA pomeni za skladnost arhiviranja

Standardoma PDF/A in PDF/X neposredno zavračata XFA. Delovni tok, ki napaja arhiv po standardu ISO 19005, mora zato najprej izvesti pretvorbo, pri čemer vrstni red ni predmet razprave: naložite, zaženite FlattenLoadedXFA, shranite in nato zaženite arhivsko ustvarjanje ali preverjanje na rezultatu AcroForm. Pretvorbe ne obravnavajte kot dokaz o skladnosti. Ta le popravi model obrazca, pisave, barve in metapodatke pa pusti nespremenjene, zato izhod pred uporabo preverite z orodjem veraPDF. Ko je obrazec pretvorjen v AcroForm, njegovo delovanje prejme lastne nadzorne mehanizme. Sprožilci JavaScript, dejanja pošiljanja in skripti za preverjanje so opisani v članku o poljih in dejanjih HotPDF AcroForm.

Tukaj prikazani API-ji za registracijo, pretvorbo in obrazce XFA so del komponente HotPDF za Delphi in C++Builder, katere dokumentacija spremlja nabor funkcij XFA, kot se je razvijal v zadnjih izdajah.