losLab PDF biblioteka prenosi podatke obrazaca u PDF i van njega na tri različita načina: FDF i XFDF za vrednosti polja AcroForm-a, ista ta dva formata za komentare anotacija, kao i čitav XFA XDP paket upisan direktno u obrazac. Metode ExportFormDataToXFDF, ImportFormDataFromXFDF, ImportAnnotationsFromFDF, ExportAnnotationsToXFDF i SetXFAFromString su ulazne tačke, i svaka od njih ima varijantu za datoteke i varijantu za stringove
Razlog zašto postoji toliko mnogo metoda je taj što podaci PDF obrazaca nisu jedna jedinstvena stvar. Popunjen AcroForm ima vrednosti polja, može nositi i komentare recenzije, a stariji XFA obrazac ugrađuje čitav XML opis aplikacije koji nema nikakve veze ni sa jednim od prethodnih. losLab PDF biblioteka namerno drži ova tri segmenta na odvojenim API-jima, jer bi njihovo spajanje iznudilo pogrešan model podataka na barem dva od njih. Odluka o tome koja vam je porodica metoda potrebna je prvi korak u dizajnu, i obično se donosi onog trenutka kada saznate šta zapravo konzumira prijemni sistem na drugoj strani
Koja je razlika između FDF, XFDF i XFA podataka obrazaca?
FDF i XFDF nose iste informacije u dve različite sintakse, dok je XFA poseban svet. FDF je minijaturni dokument u PDF sintaksi (ISO 32000-2 §12.7.8): niz /Fields koji se sastoji od rečnika << /T (name) /V (value) >>, sa stringovima izbegnutim (escaped) tačno na način na koji se doslovni stringovi izbegavaju unutar PDF-a. XFDF je XML oblik istih podataka (ISO 19444), stablo <fields> koje Acrobat i većina pozadinskih sistema za obrasce čitaju i pišu izvorno. XFA nije ni jedno ni drugo: to je šablon XML arhitekture obrazaca (XML Forms Architecture) plus njegovi podaci, sačuvani kao XML paket podataka (XML Data Package - XDP) koji PDF referencira iz /AcroForm/XFA. Izaberite FDF ili XFDF kada vršite razmenu vrednosti polja, a za XFA se opredelite samo kada održavate dokument koji je prvobitno kreiran kao XFA obrazac
Unutar FDF-a i XFDF-a, losLab PDF biblioteka povlači drugu liniju razgraničenja: vrednosti polja naspram komentara anotacija. Porodica metoda za podatke obrazaca (ExportFormDataToFDF, ImportFormDataFromFDF, ExportFormDataToXFDF, ImportFormDataFromXFDF) čita i piše podstablo /Fields i ne dira ništa drugo. Porodica metoda za anotacije (ExportAnnotationsToFDF, ImportAnnotationsFromFDF, ExportAnnotationsToXFDF, ImportAnnotationsFromXFDF) umesto toga čita i piše podstablo /Annots, što je ono što Acrobat podrazumeva pod funkcijom Export Comments. Ove dve grupe se nikada ne preklapaju, tako da izvoz vrednosti polja neće pokupiti zalutale beleške sa recenzije, niti će uvoz komentara poremetiti vrednosti koje je korisnik već ukucao. Ono što kontrola (widget) radi kada se klikne ili ponovo izračuna je treća tema, pokrivena u pratećoj belešci o interaktivnim akcijama obrazaca i JavaScript-u
Kako popuniti PDF obrazac iz FDF-a ili XFDF-a u Delphi-ju?
Učitajte dokument, pozovite jednu metodu uvoza i sačuvajte. Metode ImportFormDataFromXFDF i ImportFormDataFromFDF pojedinačno analiziraju dolazne podatke obrasca, uparuju svaki unos sa poljem AcroForm-a po njegovom punom kvalifikovanom nazivu, postavljaju vrednost i vraćaju broj polja koja su zapravo ažurirana. Obe metode ažuriraju samo polja koja već postoje u ciljnom PDF-u. Nijedna ne kreira polje za naziv koji obrazac ne definiše, što sprečava da zalutala ili zlonamerna datoteka sa podacima tiho proširi vaš obrazac
var
Lib: TPDFlib;
FieldsSet: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.LoadFromFile('application-blank.pdf', '');
// XFDF produced by a case-management system, already UTF-8 on disk
FieldsSet := Lib.ImportFormDataFromXFDF('applicant-1042.xfdf');
if FieldsSet > 0 then
Lib.SaveToFile('application-filled.pdf');
finally
Lib.Free;
end;
end;
Dva detalja odlučuju da li će kompleksniji podaci preživeti put. Prvi je izbegavanje znakova (escaping): FDF čuva vrednosti kao doslovne PDF stringove, pa vrednost koja sadrži zagradu, kosu crtu unazad (backslash) ili neštampajući bajt stiže umotana u oktalno izbegavanje definisano u standardu ISO 32000-2 §7.3.4.2. losLab PDF biblioteka poništava to izbegavanje prilikom uvoza, tako da se zagrade i kose crte vraćaju kao doslovni znakovi koje je korisnik ukucao. Drugi detalj je kodiranje: metode zasnovane na datotekama pišu i čitaju XFDF i FDF kao UTF-8, što je ono što deklaracija XFDF obećava i što je svakoj ne-ASCII vrednosti polja (ime sa akcentima, simbol valute, CJK adresa) potrebno da bi prošla krug bez oštećenja. Ako sami gradite XFDF, deklarišite UTF-8 i pišite u UTF-8 formatu, i uvoz će biti usklađen sa vama
Hijerarhijska polja, izbori sa više vrednosti i bogat tekst (rich text)
Hijerarhijska imena polja su prvo mesto gde jednostavan eksporter puca. AcroForm adresira ugnežđeno polje sa punim nazivom razdvojenim tačkama kao što je Applicant.FullName, ali XFDF ne stavlja taj string sa tačkama u jedan atribut name. Standard ISO 19444 ga ugnežđuje kao <field name="Applicant"><field name="FullName">. losLab PDF biblioteka deli naziv sa tačkama na ugnežđene elemente <field> prilikom izvoza i ponovo sklapa ugnežđene elemente u pun naziv prilikom uvoza, tako da oba smera ostaju simetrična. Prilikom izvoza takođe preskače krajnja roditeljska polja (non-terminal parent fields), jer roditeljski čvor u AcroForm-u nosi samo nivo imenovanja i nema sopstvenu vrednost — njegovo emitovanje bi proizvelo prazan element <value></value> koji ne odgovara stvarnom obrascu. Okviri sa listom sa višestrukim izborom (multi-select list boxes) su druga zamka: polje izbora može držati nekoliko izabranih vrednosti odjednom, što XFDF izražava kao ponovljene elemente <value>, a FDF izražava kao niz /V. losLab PDF biblioteka deli polje na više vrednosti samo kada je reč o stvarnom višestrukom izboru, tako da obično višeredno tekstualno polje zadržava svoje prelome redova umesto da se razbije na lažne vrednosti
Bogat tekst (rich text) je treća zamka, i ona na kojoj ljudi najčešće greše. Polje sa formatiranjem čuva svoj markup u unosu RV kao XHTML podstablo, a XFDF ga nosi u <value-richtext>. losLab PDF biblioteka piše to podstablo kao živ XML fragment umesto da ga izbegava, tako da nizvodni alat čita stvarni bogat tekst umesto niza vidljivih tagova. Prilikom uvoza, ona čuva sirovo podstablo RV i dalje primenjuje običnu vrednost <value> na V. Tamo gde polje nudi oba, obična vrednost pobeđuje za V, a bogat tekst ide uporedo u RV, što je pravilo interoperabilnosti koje sprečava da uvoz bogatog teksta tiho prepiše vrednost koju je drugi alat već postavio. Kada vaš bogat tekst postoji da prenese strukturu dokumenta asistivnoj tehnologiji, tretirajte ga na isti način na koji biste tretirali redosled čitanja opisan u belešci o označenom PDF-u i strukturi pristupačnosti
var
Lib: TPDFlib;
const
XFDF =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">' +
'<fields>' +
' <field name="Applicant">' +
' <field name="FullName"><value>Alice Example</value></field>' +
' </field>' +
' <field name="Skills">' +
' <value>Delphi</value><value>PDF</value>' +
' </field>' +
' <field name="Notes">' +
' <value>See attachment</value>' +
' <value-richtext><body><p>See <b>attachment</b></p></body></value-richtext>' +
' </field>' +
'</fields></xfdf>';
begin
Lib := TPDFlib.Create;
try
Lib.LoadFromFile('intake.pdf', '');
// Applicant.FullName reassembles; Skills fills the /V + /I arrays;
// Notes gets V from <value> and RV from <value-richtext>
Lib.ImportFormDataFromXFDFString(XFDF);
Lib.SaveToFile('intake-filled.pdf');
finally
Lib.Free;
end;
end;
Kako dvosmerno prenositi komentare anotacija kao FDF ili XFDF?
Komentari putuju kroz porodicu metoda za anotacije, a podržani podskup je namerno mali. Metode ExportAnnotationsToXFDF i ImportAnnotationsFromXFDF, zajedno sa svojim FDF pandanima, prenose tekstualni stil markupa sa poljima koja zapravo čisto prolaze krug: podtip anotacije, njen pravougaonik, indeks stranice u bazi od 0, autora u polju T, temu u polju Subj, običan sadržaj Contents i boju, koja mapira PDF /C DeviceRGB trojku u XFDF atribut #RRGGBB i obrnuto. Uvoz prihvata samo poznate nazive elemenata i preskače svaki unos čija je stranica van opsega ili čiji pravougaonik nedostaje, tako da ručno izmenjeni ili strani XFDF ne može ubaciti neispravnu anotaciju u dokument. Ono što ovaj podskup još uvek ne prenosi vredi jasno reći: bogat tekst sadržaja (RC), popup prozori, quadpoints, linije mastila (ink lists), temena (vertices) i ugrađeni tokovi izgleda (appearance streams) za sada su van opsega, tako da geometrija isticanja i prilagođeni izgledi pečata neće preživeti ovu putanju. Da biste potvrdili šta je zapravo stiglo, prođite kroz anotacije stranica ili šire stablo elemenata pokriveno u članku o pretrazi teksta i enumeraciji elemenata stranice
var
Src, Dest: TPDFlib;
Xfdf: WideString;
begin
Src := TPDFlib.Create;
Dest := TPDFlib.Create;
try
Src.LoadFromFile('reviewed.pdf', '');
Xfdf := Src.ExportAnnotationsToXFDFString; // <annots> subset only
Dest.LoadFromFile('clean-copy.pdf', ''); // pages must line up by index
Dest.ImportAnnotationsFromXFDFString(Xfdf);
Dest.SaveToFile('clean-copy-commented.pdf');
finally
Dest.Free;
Src.Free;
end;
end;
Upisivanje kompletnog XFA XDP paketa pomoću SetXFAFromString
XFA je izuzetak, a metoda SetXFAFromString je način na koji upisujete celu stvar odjednom. Metoda uzima kompletan XML paket podataka (XML Data Package), odnosno <xdp:xdp> dokument sa njegovim paketima šablona i skupova podataka, i čuva ga kao tok (stream) referenciran iz /AcroForm/XFA. losLab PDF biblioteka kreira AcroForm kontejner na zahtev kada dokument nema nijedan, tako da ne morate dodavati privremeno polje samo da biste dali XFA-u gde da se zakači, i odbacuje svako parsirano XFA stanje koje je držala kako bi kasnije čitanje odražavalo paket koji ste upravo upisali, a ne zastareli keš. Pošto je XFA paket XML, a ne nužno UTF-8, biblioteka detektuje oznaku reda bajtova (BOM) za UTF-16 i ispravno dekodira paket pre parsiranja, što je važno za pakete koje proizvode alati koji podrazumevano koriste UTF-16
Kada je paket na mestu, metode GetXFAFormFieldValue i SetXFAFormFieldValue adresiraju pojedinačna polja preko njihove putanje Scripting Object Model-a. losLab PDF biblioteka prihvata standardne SOM korene, kao i same relativne putanje, tako da se form1.FullName, $data.form1.FullName i xfa.datasets.data.form1.FullName sve razrešavaju u isti čvor podataka, a strana šablona prihvata $template and xfa.template na isti način. Ta tolerancija je važna kada SOM putanje generiše drugi sistem koji uvek emituje pun kvalifikovani oblik
var
Lib: TPDFlib;
const
Xdp =
'<?xml version="1.0" encoding="UTF-8"?>' +
'<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">' +
' <template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">' +
' <subform name="form1">' +
' <field name="FullName"><ui><textEdit/></ui></field>' +
' </subform>' +
' </template>' +
' <xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">' +
' <xfa:data><form1><FullName>Alice Example</FullName></form1></xfa:data>' +
' </xfa:datasets>' +
'</xdp:xdp>';
begin
Lib := TPDFlib.Create;
try
Lib.SetXFAFromString(Xdp, 0); // creates the AcroForm container if none exists
// read back through the data DOM with an SOM path
if Lib.GetXFAFormFieldValue('form1.FullName') = 'Alice Example' then
Lib.SetXFAFormFieldValue('form1.FullName', 'Bob Example');
Lib.SaveToFile('xfa-packet.pdf');
finally
Lib.Free;
end;
end;
Iskren rezime je da vrednosti polja u potpunosti prolaze pun krug kroz FDF i XFDF, uključujući hijerarhiju, višestruki izbor i bogat tekst; komentari anotacija prolaze kao definisan podskup tekstualnog markupa sa jasnim prazninama; a XFA se piše i čita kao ceo paket sa dodatnim SOM pristupom po polju. Uskladite format sa klijentom, deklarišite UTF-8 za sve što pravite ručno i zapamtite da metode uvoza uvek dodiruju samo polja i anotacije koje već odgovaraju dokumentu. Metode za podatke obrazaca, anotacije i XFA opisane ovde deo su losLab PDF biblioteke za Delphi i C++Builder, čija referenca sadrži kompletnu listu parametara za svaku izvoznu i uvoznu ulaznu tačku