PDF Library for Delphi spaja dva AcroForm dokumenta uz izričitu politiku za polja koja dijele naziv. MergeDocumentEx prima identifikator izvornog dokumenta i jednu od tri strategije: dfsReject odbija spajanje, dfsMerge zadržava dijeljeni naziv i sinkronizira vrijednosti, a dfsAutoNumber deterministički preimenuje dolazna polja. Pretraga naziva odvija se prije nego što se ijedan broj objekta pomakne, pa odbijeno spajanje ostavlja oba dokumenta potpuno upotrebljivima
Svatko tko je sastavljao paket PDF prijava naišao je na ovo. Tri obrasca, svaki s poljem imenom Signature, Date ili Total, spajaju se u jednu datoteku. U AcroForm-u, potpuno kvalificirani naziv polja identitet je polja, pa dva polja s istim nazivom uopće nisu dva polja: popunjavanje jednog popunjava i drugo, a potpis primijenjen na jedno pokriva doseg koji nitko nije namjeravao
Zašto se sudar naziva odlučuje prije spajanja?
Starija MergeDocument spaja dva korijenska polja AcroForm-a i ne nudi izbor. Gore od toga, kada je rezultat neupotrebljiv, otkriće se dogodi nakon što su brojevi objekata prenumerirani, a stabla stranica sašivena, čime pozivatelj ostaje s dokumentom u stanju u kojem nijedan izvornik nije bio
MergeDocumentEx preokreće redoslijed. Prikuplja nazive polja najviše razine iz oba dokumenta, uspoređuje ih i primjenjuje strategiju prije nego što se bilo što pomakne. Odbijanje je stoga čisto ništa: ciljni dokument ostaje netaknut, izvorni dokument ostaje netaknut, i oba ostaju otvorena i upotrebljiva, što test spajanja provjerava čitanjem vrijednosti polja natrag iz izvora nakon odbijenog spajanja
Usporedba koristi poredan skup naziva osjetljiv na velika/mala slova, pa je trošak proporcionalan zbroju broja polja pomnoženom logaritamskim faktorom, a ne umnošku dvaju brojeva. Osjetljivost na velika/mala slova ovdje je ispravan izbor jer su nazivi PDF polja osjetljivi na velika/mala slova; njihovo preslikavanje spojilo bi polja koja specifikacija tretira kao različita
Tri strategije i kada je svaka ispravna
dfsReject je strategija za automatizirane pipelineove koji ne smiju proizvesti dvosmislene dokumente. Spajanje vraća nulu, a LastErrorCode prijavljuje 705, namjenski kod koji omogućuje da se dupli nazivi razlikuju od svakog drugog neuspjeha spajanja i usmjere na specifičan lijek, obično preimenovanje polja uzvodno
dfsMerge namjerno zadržava dijeljeni naziv i sinkronizira ciljnu vrijednost i zadanu vrijednost u izvorno polje, pa usklađeni preglednik tretira nekoliko widgeta kao jedno logički imenovano polje, što je standardno AcroForm ponašanje za polje s više widget napomena. Ono što ne radi jest spajanje različitih rječnika polja u jedan objekt. Svako polje zadržava vlastitu povezanost sa stranicom, izgled i akcije, jer bi njihovo spajanje tiho odbacilo oblikovanje i ponašanje koje pripada dolaznom dokumentu
dfsAutoNumber preimenuje dolazne duplikate dodavanjem brojčanog sufiksa počevši od _2, uzimajući prvi slobodan. Rezultat je reproducibilan: ovisi samo o prisutnim nazivima, nikada o brojevima objekata polja, pa spajanje istog para dokumenata dvaput daje iste nazive oba puta. To svojstvo važno je kada se kod nizvodno, uvoz FDF-a ili mapiranje baze podataka referencira na polja po nazivu
uses
PDFlibrary;
var
Lib: TPDFlib;
TargetDoc, SourceDoc: Integer;
begin
Lib := TPDFlib.Create;
try
TargetDoc := Lib.SelectedDocument;
Lib.LoadFromFile('application-part1.pdf', '');
SourceDoc := Lib.NewDocument;
Lib.LoadFromFile('application-part2.pdf', '');
Lib.SelectDocument(TargetDoc);
if Lib.MergeDocumentEx(SourceDoc, dfsReject) = 0 then
begin
if Lib.LastErrorCode = 705 then
begin
// Oba dokumenta i dalje su netaknuta - pokušajte ponovno s politikom
Log('duplicate field names; retrying with auto-numbering');
Lib.MergeDocumentEx(SourceDoc, dfsAutoNumber);
end;
end;
Lib.SaveToFile('application-complete.pdf');
finally
Lib.Free;
end;
end;
Uočite dvokoračni obrazac u tom kodu, koji je moguć samo zato što odbijanje nije destruktivno. Prvo pokušajte strogu politiku, provjerite grešku, zatim odlučite. Sa spajanjem koje zakaže na pola puta, fallback bi morao krenuti ispočetka ponovnim učitavanjem obiju datoteka
Kako spojeni obrazac izgleda nakon toga
Pod dfsMerge, ciljno polje imenom Shared koje nosi „Target value” i izvorno polje s istim nazivom proizvode dva polja, oba imenom Shared, oba izvještavaju ciljnu vrijednost, jer se ciljna vrijednost i zadana vrijednost sinkroniziraju u dolazno polje. To je namjeravana semantika za dijeljeni naziv: jedno logičko polje, nekoliko widgeta, jedna vrijednost
Pod dfsAutoNumber, isti ulaz proizvodi Shared i Shared_2 kao odvojena polja s neovisnim vrijednostima. Birajte između njih postavljanjem jednog pitanja: treba li popunjavanje jedne kontrole popuniti i drugu? Za ime potpisnika ponovljeno na svakom dijelu paketa, da, i dfsMerge je ispravan. Za ukupan iznos koji na svakom obrascu znači nešto drugo, ne, i automatsko numeriranje je ispravno
// Nakon spajanja, nabrojite što ste zapravo dobili
for I := 1 to Lib.FormFieldCount do
Log(Format('%d: %s = %s',
[I, Lib.GetFormFieldTitle(I), Lib.GetFormFieldValue(I)]));
Praktične napomene za sastavljanje paketa obrazaca
Uspješno spajanje troši izvorni dokument: uklanja se s popisa dokumenata knjižnice, zbog čega DocumentCount padne s dva na jedan. Nemojte nastaviti koristiti identifikator izvora nakon toga. Verzija dokumenta podiže se na višu od dvije, pa spajanje PDF 2.0 obrasca u dokument 1.7 daje datoteku 2.0
Redoslijed je važan za nazive. Spajanje A u B i spajanje B u A daju drugačije automatski numerirane rezultate, budući da dokument koji provodi spajanje zadržava svoje nazive nepromijenjenima. Kada paket ima kanonski primarni obrazac, njega učinite ciljem
Polja potpisa zaslužuju vlastito razmatranje. Potpis primijenjen prije spajanja pokriva samo reviziju koju je potpisao, pa ga spajanje poništava u praktičnom smislu da se datoteka promijenila od potpisivanja. Prvo sastavite, pa potpišite sastavljeni dokument, umjesto spajanja potpisanih dijelova. Kada se spajanje odnosi na sadržaj stranice, a ne na obrasce, brži put opisan u brzom PDF spajanju s pomicanjem bajtnih referenci bolji je alat
Naposljetku, planirajte podatkovnu stranu paketa zajedno sa spajanjem. Ako vrijednosti polja dolaze iz vanjskog sustava, prije odabira automatskog numeriranja odlučite adresira li taj sustav polja po nazivu, jer se Shared_2 neće podudarati s mapiranjem koje očekuje Shared. Formati uvoza i izvoza opisani su u razmjeni podataka obrazaca FDF, XFDF i XFA, a ponašanje skriptiranja na razini polja koje preimenovanje također može zahvatiti opisano je u interaktivnim akcijama obrazaca i JavaScriptu
Spajanje obrazaca, razmjena podataka i potpisivanje izvode se u istoj knjižnici za Delphi, C++Builder i Free Pascal; cjelokupni popis značajki nalazi se na stranici PDF Library for Delphi