PDF Library for Delphi združi dva dokumenta AcroForm z izrecnim pravilnikom za polja, ki si delijo ime. MergeDocumentEx sprejme identifikator izvornega dokumenta in eno od treh strategij: dfsReject zavrne združitev, dfsMerge obdrži skupno ime in uskladi vrednosti, dfsAutoNumber pa vhodna polja deterministično preimenuje. Pregled imen se zgodi, preden se premakne katera koli številka objekta, tako da zavrnjena združitev oba dokumenta pusti povsem uporabna
Vsak, kdor je sestavil paket vlog PDF, je naletel na to. Trije obrazci, vsak s poljem, imenovanim Signature, Date ali Total, se združijo v eno datoteko. V AcroForm je polno kvalificirano ime polja identiteta polja, zato dve polji z istim imenom sploh nista dve polji: izpolnitev enega izpolni drugo, podpis, uveljavljen na enem, pa pokrije obseg, ki ga ni nihče nameraval
Zakaj se trk imen razreši pred združitvijo?
Starejši MergeDocument spoji obe korenski polji AcroForm in ne ponudi nobene izbire. Slabše je, da se, kadar je rezultat neuporaben, odkritje zgodi šele po tem, ko so bile številke objektov preštevilčene in drevesa strani sešita skupaj, kar klicatelju pusti dokument v stanju, v katerem ni bil noben od izvirnikov
MergeDocumentEx obrne vrstni red. Zbere imena polj najvišje ravni iz obeh dokumentov, jih primerja in uveljavi strategijo, preden se karkoli premakne. Zavrnitev je zato čist brezoperacijski korak: ciljni dokument je nedotaknjen, izvorni dokument je nedotaknjen, oba pa ostaneta odprta in uporabna, kar test združitve potrdi tako, da po zavrnjeni združitvi znova prebere vrednost polja iz izvora
Primerjava uporablja urejeno množico imen, občutljivo na velikost črk, zato je strošek sorazmeren s skupnim številom polj, pomnoženim z logaritemskim faktorjem, in ne z zmnožkom obeh števil. Občutljivost na velikost črk je tu pravilna izbira, ker so imena polj PDF občutljiva na velikost črk; njihovo zvijanje bi združilo polja, ki jih specifikacija obravnava kot ločena
Tri strategije, in kdaj je vsaka pravilna
dfsReject je strategija za avtomatizirane cevovode, ki ne smejo ustvariti dvoumnih dokumentov. Združitev vrne nič, LastErrorCode pa javi 705, namensko kodo, tako da je podvojena imena mogoče ločiti od vsakega drugega neuspeha združitve in jih usmeriti na specifičen popravek, običajno preimenovanje polj še pred združitvijo
dfsMerge namerno obdrži skupno ime in uskladi ciljno vrednost ter privzeto vrednost v izvorno polje, tako da skladen pregledovalnik več pripomočkov obravnava kot eno logično poimenovano polje, kar je standardno vedenje AcroForm za polje z več pripombami pripomočkov. Ne stori pa tega, da bi različne slovarje polj zlil v en sam objekt. Vsako polje obdrži svojo lastno povezavo s stranjo, videz in dejanja, ker bi njihovo strnitev tiho zavrgla oblikovanje in vedenje, ki pripada vhodnemu dokumentu
dfsAutoNumber vhodne podvojitve preimenuje z dodajanjem numerične pripone, ki se začne pri _2, in vzame prvo prosto. Rezultat je ponovljiv: odvisen je samo od prisotnih imen, nikoli od številk objektov polja, tako da združitev istega para dokumentov dvakrat oba krat da ista imena. Ta lastnost je pomembna, kadar se nadaljnja koda, uvoz FDF ali preslikava podatkovne zbirke na polja sklicuje po imenu
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 sta še vedno nedotaknjena - ponovi s pravilnikom
Log('duplicate field names; retrying with auto-numbering');
Lib.MergeDocumentEx(SourceDoc, dfsAutoNumber);
end;
end;
Lib.SaveToFile('application-complete.pdf');
finally
Lib.Free;
end;
end;
Opazite dvostopenjski vzorec v tej kodi, ki je mogoč samo zato, ker zavrnitev ni destruktivna. Najprej poskusite strog pravilnik, preglejte napako, nato odločite. Pri združitvi, ki spodleti na pol poti, bi morala rezervna rešitev začeti znova s ponovnim nalaganjem obeh datotek
Kako je videti združen obrazec pozneje
Pod dfsMerge ciljno polje z imenom Shared, ki nosi "Target value", in izvorno polje z istim imenom ustvarita dve polji, obe imenovani Shared, obe javljata ciljno vrednost, ker sta ciljna vrednost in privzeta vrednost usklajeni v vhodno polje. To je nameravana semantika za skupno ime: eno logično polje, več pripomočkov, ena vrednost
Pod dfsAutoNumber isti vhod ustvari Shared in Shared_2 kot ločeni polji z neodvisnimi vrednostmi. Med obema izbirajte tako, da si zastavite eno samo vprašanje: ali naj izpolnitev enega kontrolnika izpolni tudi drugega? Za ime podpisnika, ponovljeno na vsakem delu paketa, da, in dfsMerge je pravilen. Za skupno vsoto, ki na vsakem obrazcu pomeni nekaj drugega, ne, in samodejno oštevilčenje je pravilno
// Po združitvi naštejte, kaj ste dejansko dobili
for I := 1 to Lib.FormFieldCount do
Log(Format('%d: %s = %s',
[I, Lib.GetFormFieldTitle(I), Lib.GetFormFieldValue(I)]));
Praktične opombe za sestavljanje paketov obrazcev
Uspešna združitev porabi izvorni dokument: ta je odstranjen s seznama dokumentov knjižnice, zato DocumentCount pade z dveh na enega. Izvornega identifikatorja pozneje ne uporabljajte več. Različica dokumenta se dvigne na višjo od obeh, tako da združitev obrazca PDF 2.0 v dokument 1.7 da datoteko 2.0
Za imena je vrstni red pomemben. Združitev A v B in združitev B v A dasta različne samodejno oštevilčene rezultate, saj dokument, ki izvaja združitev, obdrži svoja imena nespremenjena. Kadar ima paket kanoničen primarni obrazec, tega naredite cilj
Polja podpisov si zaslužijo svoj lasten premislek. Podpis, uveljavljen pred združitvijo, pokrije samo revizijo, ki jo je podpisal, zato ga združitev izniči v praktičnem smislu, da se je datoteka od podpisa spremenila. Najprej sestavite in podpišite sestavljeni dokument, namesto da bi združevali podpisane dele. Kadar gre pri združitvi za vsebino strani in ne za obrazce, je hitrejša pot, opisana v hitri združitvi PDF s premikanjem bajtnih sklicev, boljše orodje
Nazadnje podatkovno stran paketa načrtujte skupaj z združitvijo. Če vrednosti polj prihajajo iz zunanjega sistema, se pred izbiro samodejnega oštevilčenja odločite, ali ta sistem naslavlja polja po imenu, ker se Shared_2 ne bo ujemal s preslikavo, ki pričakuje Shared. Uvozne in izvozne oblike so opisane v izmenjavi podatkov obrazcev FDF, XFDF in XFA, vedenje skriptiranja na ravni polja, na katero lahko prav tako vpliva preimenovanje, pa je opisano v interaktivnih dejanjih obrazca in JavaScript
Združevanje obrazcev, izmenjava podatkov in podpisovanje tečejo v isti knjižnici za Delphi, C++Builder in Free Pascal; celoten seznam funkcij je na strani PDF Library for Delphi