Yritysasiakirjaratkaisuja kehitettäessä kohtaat väistämättä PDF-tiedostoja, jotka on luotu valtavalla valikoimalla työkaluja, huippuluokan Adobe-ohjelmistoista bugisiin avoimen lähdekoodin kirjastoihin tai virtuaalisiin tulostinohjaimiin. Yksi pahamaineisimmista rakenteellisista ongelmista, joita kohtaat, on "hybridiviitteinen" PDF.
Tässä artikkelissa selitämme, mitä hybridiviitteet ovat, miksi tietyt toimistosovellukset luovat niitä ja kuinka näitä rakenteita jäsennetään ja korjataan ohjelmallisesti käyttämällä Delphiä ja vankkoja PDF-kirjastoja.
PDF-ristiinviittaustaulukon kehitys
Objektien (fontit, kuvat, sivut) paikantamiseksi nopeasti jäsentämättä koko tiedostoa PDF käyttää ristiinviittaustaulukkoa (XRef). Aiemmissa PDF-määrityksissä (PDF 1.4 ja vanhemmat) tämä oli kirjaimellinen ASCII-tekstitaulukko tiedoston lopussa.
PDF 1.5:stä alkaen Adobe esitteli ristiinviittausvirrat (XRefStm), jotka pakkasivat ristiinviittaustiedot binäärivirraksi, mikä pienensi tiedostokokoja merkittävästi. Taaksepäin yhteensopivuuden ylläpitämiseksi vanhempien PDF-lukijoiden kanssa jotkin generaattorit alkoivat kuitenkin tuottaa hybridiviite-PDF-tiedostoja. Nämä tiedostot sisältävät sekä vanhan tyylin ASCII XRef -taulukon että uuden tyylin XRef-virran.
Hybridiviitteiden ongelma
Hybriditiedostot ovat teoreettisesti kelvollisia, mutta monet PDF-generaattorit (erityisesti vanhojen Office-pakettien "Tallenna PDF-muodossa" -liitännäiset) kirjoittavat ne väärin. Yleinen ohjelmointivirhe on väärän tavusiirtymän kirjoittaminen `startxref`-osoittimelle tai hajanaisten objektivirtojen luominen, joissa XRef-taulukko osoittaa väärään sukupolven numeroon.
Jos Delphi-sovelluksesi yrittää lukea huonosti muotoillun hybridi-PDF-tiedoston tiukkaa jäsennintä käyttäen, jäsennin epäonnistuu poikkeuksella "Vioittunut XRef-taulukko" (Corrupt XRef table) tai "Virheellinen objektinumero" (Invalid Object Number).
Hybridivaihtoehtojen käsittely PDFiumilla
PDFium-moottori (alunperin Foxitin kehittämä ja Googlen avoimen lähdekoodin julkaisema) sietää erittäin hyvin väärin muotoiltuja PDF-tiedostoja. Kun se havaitsee rikkinäisen XRef-taulukon, se skannaa tiedostoa automaattisesti taaksepäin EOF:stä paikantaakseen vaihtoehtoisen XRefStm:n.
Kun työskentelet PDFiumin kanssa Delphissä, sinun ei tarvitse jäsentää trailer-sanakirjoja manuaalisesti. Sinun tulisi kuitenkin tarkistaa rakenteelliset varoitukset, jotta voit varoittaa käyttäjää tai kirjata ongelman lokiin.
uses
System.SysUtils, pdfium_lib;
procedure LoadAndCheckHybridPDF(const FileName: string);
var
Doc: FPDF_DOCUMENT;
LastError: ULONG;
begin
FPDF_InitLibrary();
try
Doc := FPDF_LoadDocument(PAnsiChar(AnsiString(FileName)), nil);
if Doc = nil then
begin
LastError := FPDF_GetLastError();
case LastError of
FPDF_ERR_FILE: Writeln('File not found or could not be opened.');
FPDF_ERR_FORMAT: Writeln('File not in PDF format or corrupted.');
FPDF_ERR_PASSWORD: Writeln('Password required or incorrect password.');
FPDF_ERR_SECURITY: Writeln('Unsupported security scheme.');
FPDF_ERR_XFDF: Writeln('Invalid XRef or Hybrid Reference structure.');
else
Writeln('Unknown error occurred loading PDF.');
end;
Exit;
end;
Writeln('PDF loaded successfully despite hybrid or structural anomalies.');
// Proceed with processing...
FPDF_CloseDocument(Doc);
finally
FPDF_DestroyLibrary();
end;
end;
PDF-tiedoston korjaaminen ja uudelleenrakentaminen
Jos työnkulkusi edellyttää PDF-tiedoston siirtämistä tiukempaan jatkojärjestelmään (kuten vanhempaan laitteisto-RIP:iin), sinun on "litistettävä" hybridirakenne. Luotettavin tapa korjata rikkinäinen hybridi-PDF Delphissä on ladata se suvaitsevaiseen moottoriin ja suorittaa Tallenna nimellä -toiminto. Tämä pakottaa jäsentimen rakentamaan muistissa olevasta objektipuusta puhtaan, yhtenäisen XRef-taulukon.
// Conceptual example using a high-level wrapper
procedure RebuildPdfStructure(const InputFile, OutputFile: string);
var
Doc: TlxPDFDocument;
begin
Doc := TlxPDFDocument.Create;
try
// Tolerant engine ignores the broken hybrid XRef and walks the objects
Doc.LoadFromFile(InputFile);
// Saving rewrites the file with a clean PDF 1.7 XRef stream
Doc.SaveToFile(OutputFile);
Writeln('PDF structure successfully rebuilt.');
finally
Doc.Free;
end;
end;
Hybridiviitteiden vioittumisen ymmärtäminen ja ennakointi varmistaa, että asiakirjojen käsittelyputkesi pysyvät joustavina, jopa vuosikymmeniä vanhojen perinteisten tiedostojen edessä.
Huomautus: PDFium Component VCL -komponentti tukee täysin hybridiviitteiden ratkaisemista ja automaattisia rakenteellisia korjauksia.