Tato lokalizovaná verze se věnuje tématu Building a Compliance and Signing Workbench in Delphi with PDFlibPas a bere aktualizovaný anglický článek jako technický základ pro týmy pracující s Delphi, PDF a dokumentovým softwarem
Stránka převádí aktualizovaný výchozí článek na konkrétní kontrolní body pro návrh, implementaci a ověření
Co bylo synchronizováno z anglického článku
Anglický výchozí text byl rozšířen o praktický kontext, technická rozhodnutí a konkrétní příklady, takže tato stránka funguje jako pracovní průvodce, nikoli jako krátké shrnutí
Důležité části aktualizovaného výchozího článku:
- Nejprve použijte malé reprodukovatelné vstupní soubory
- Názvy produktů, API, souborů a literálové hodnoty ponechte beze změny
- Uložte výstup validátoru a informace o verzích spolu s vytvořeným vzorkem
Praktická implementační rozhodnutí
Začněte typem souboru, očekávaným výstupem a chybovým stavem, který má vidět uživatel. Potom svažte každé volání API s ověřitelným výsledkem, aby validace, logování i podpora mohly zopakovat zákaznický scénář
- Nejprve použijte malé reprodukovatelné vstupní soubory
- Názvy produktů, API, souborů a literálové hodnoty ponechte beze změny
- Uložte výstup validátoru a informace o verzích spolu s vytvořeným vzorkem
Kód a body API
Ukázky kódu zůstávají beze změny, aby je vývojář mohl porovnat přímo s projekty Delphi, C++Builder a Lazarus/FPC
var
PDF: TPDFlib;
ListID, I: Integer;
begin
PDF := TPDFlib.Create;
try
ListID := PDF.CheckFileCompliance('invoice-fixed.pdf', '', 1, 0); // 1 = PDF/A
if ListID = 0 then
begin
if PDF.LastErrorCode <> 0 then
raise Exception.Create('Preflight could not read the file')
else
Writeln('No PDF/A findings');
end
else
begin
for I := 0 to PDF.GetStringListCount(ListID) - 1 do
Writeln(PDF.GetStringListItem(ListID, I));
PDF.ReleaseStringList(ListID);
end;
finally
PDF.Free;
end;
end;ProcessID := PDF.NewSignProcessFromFile('invoice-fixed.pdf', '');
if ProcessID = 0 then
raise Exception.Create('Cannot open source for signing');
PDF.SetSignProcessField(ProcessID, 'ApprovalSig');
PDF.SetSignProcessPFXFromFile(ProcessID, 'company.pfx', PfxPassword);
PDF.SetSignProcessInfo(ProcessID, 'Invoice approval', 'Berlin', 'billing@example.com');
PDF.SetSignProcessCustomSubFilter(ProcessID, 'ETSI.CAdES.detached'); // PAdES baseline
PDF.SetSignProcessDigestAlgorithm(ProcessID, 2); // SHA-256
PDF.SetSignProcessReserveContentsBytes(ProcessID, 8192); // room for a later timestamp
PDF.EndSignProcessToFile(ProcessID, 'invoice-signed.pdf');
if PDF.GetSignProcessResult(ProcessID) <> 1 then
Writeln('Sign failed, code ', PDF.GetSignProcessResult(ProcessID));
PDF.ReleaseSignProcess(ProcessID);var
Doc: TPDFlibSignDoc;
Names: TStringList;
FS: TFileStream;
I: Integer;
SourceSize, RangeStart, GapStart, TailStart, TailLen: Int64;
begin
// Capture the size before Open: the audit object holds a share lock on the file
FS := TFileStream.Create('invoice-signed.pdf', fmOpenRead or fmShareDenyNone);
SourceSize := FS.Size;
FS.Free;
Doc := TPDFlibSignDoc.Create;
Names := TStringList.Create;
try
if not Doc.Open('invoice-signed.pdf', '', False) then Exit;
Doc.GetSignatureFieldNames(Names);
for I := 0 to Names.Count - 1 do
if Doc.GetSignatureValueObjNum(Names[I]) > 0 then // > 0 means the field is signed
begin
RangeStart := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 11)));
GapStart := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 12)));
TailStart := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 13)));
TailLen := StrToInt64(string(Doc.GetSignatureValueByName(Names[I], 14)));
if (RangeStart = 0) and (TailStart + TailLen = SourceSize) then
Writeln(Names[I], ': signature covers the file to EOF')
else
Writeln(Names[I], ': earlier revision, or unusual ByteRange layout');
end;
Doc.Close;
finally
Names.Free;
Doc.Free;
end;
end;Kontrola před vydáním
Výstupní soubor ověřte stejnými nástroji, jaké použije zákazník nebo archiv. Zaznamenejte verzi komponenty, testovací data, verzi validátoru a pozorovaný výsledek, aby šla pozdější regrese přesně dohledat
Doplňující technický rozbor
Tento rozšířený oddíl navazuje na článek Technický článek: PDFlibPas Compliance and Signing Workbench in Delphi v češtině a záměrně rozebírá stejný pracovní tok z pohledu týmu, který potřebuje mít jistotu, že rozhodnutí v generátoru, validátoru i v provozním logu zůstanou dohledatelné i po delší době. Anglický základ na navazující stránce přes hreflang ukazuje, proč není dostačující jen přeložit nadpisy; důležité je rozvést důvody, proč se má soubor považovat za hotový až ve chvíli, kdy jsou pravidla, výstup i kontrolní záznamy skutečně sladěné
U implementačních článků je klíčové oddělit návrh od ověření. Nejprve se určí typ souboru, očekávané chování a chyba, která má být vidět, potom se každé API volání sváže s výsledkem, který lze ověřit ve stejném scénáři znovu. To je praktické u PDF i tabulkových procesorů: kódové ukázky zůstávají beze změny, ale okolní text musí vysvětlit, proč se má logovat verze komponenty, identifikace šablony, vstupní data a stav validace spolu
Stejně důležité je zachovat pojmenování produktů, API, souborů a literálových hodnot přesně tak, jak se objevují v anglickém zdroji. Tím se drží společný referenční rámec pro vývoj, support i kontrolu kvality a zmenšuje se riziko, že by se z lokální verze stala jen volná parafráze bez konkrétního technického obsahu. Pokud je v článku uveden kód, jeho komentáře i tokeny mají zůstat nedotčené, protože právě ty spojují text s reálným projektem
Při čtení této stránky je užitečné přemýšlet i o tom, jak bude článek použit po zveřejnění. Dobrá validační poznámka popíše, co se testovalo, jaký nástroj vyhodnotil výsledek, které verze byly zapojené a kde je uložený důkaz o shodě nebo o selhání. Když později vznikne regresní problém, archivovaný report a související vstupní soubor jsou mnohem cennější než samotný dojem, že „to tehdy prošlo“.
Pro tuto lokalizovanou větev tedy platí jednoduché pravidlo: udržet hlavní rozhodnutí, ověřovací body a kontext kódu pohromadě tak, aby článek zůstal použitelný nejen při prvním čtení, ale i při pozdějším ladění, auditu a porovnání mezi verzemi. To je rozdíl mezi krátkým shrnutím a pracovním dokumentem, který má hodnotu i po několika releasích.
- Nejprve použijte malé reprodukovatelné vstupní soubory
- Názvy produktů, API, souborů a literálové hodnoty ponechte beze změny
- Ukládejte verzi komponenty, výsledky validátoru i vstupní data společně
- Kódové bloky a jejich komentáře zachovejte přesně tak, jak jsou ve zdroji