HotPDF skriver inbyggda PDF 2.0-dokument från Delphi och C++Builder, inklusive de tre PDF/A-4-arkivprofilerna och PDF/UA-2 tillgänglighetsutdata med namnrymdsbundna strukturelement. Att välja dem är en fråga om två egenskaper, men standarderna bakom de egenskaperna ändrades mer än versionsnumret antyder: PDF/A-4 släppte de överensstämmelsebrev som alla lärde sig med PDF/A-2, och PDF/UA-2 introducerade strukturnamnrymder som ett del 1-dokument aldrig hade
Den här artikeln täcker vad som faktiskt ändras i den genererade filen, och vilka misstag HotPDF förvandlar till ett undantag vid EndDoc i stället för till ett dokument som misslyckas med validering hos kunden
Hur PDF/A-4-identifiering skiljer sig från del 2 och 3
PDF/A-4 identifierar sig genom delnummer och revisionsår, utan överensstämmelsebrev för basdelen. Sätt PDFACompliance till '4' så emitterar HotPDF pdfaid:part=4 med pdfaid:rev=2020 och ingen pdfaid:conformance-post alls. Brevet försvann inte — del 4 har inga A/B/U-nivåer, eftersom de krav som tidigare skilde dem vecklades in i basdelen
Två tillägg behåller en bokstav. '4E' väljer PDF/A-4e för ingenjörsdokument och emitterar överensstämmelse E, som tillåter de 3D- och RichMedia-annoteringsvägar som de övriga profilerna förbjuder. '4F' väljer PDF/A-4f och emitterar överensstämmelse F, som tillåter en inbäddad fil av valfritt format. Alla tre tvingar fram en PDF 2.0-header, kräver de vanliga PDF/A-utdatamått och metadatakontroller och förbjuder kryptering — en krypterad arkivfil är en motsägelser standarden inte underhåller
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'invoice-archive.pdf';
Pdf.PDFACompliance := '4F'; // PDF/A-4f: associated files of any format
Pdf.BeginDoc;
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(50, 760, 0, 'Invoice 2026-0731');
Pdf.AddPDFAssociatedFile('invoice.xml', 'text/xml',
'Structured invoice data', 'Data', LoadInvoiceBytes);
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
AddPDFAssociatedFile bäddar in filen, bygger dess FileSpec med en /AFRelationship och registrerar den i både katalogens /AF-array och EmbeddedFiles-namnträdet. Båda registreringarna krävs; en fil listad i bara en av dem är den enskilt vanligaste anledningen till att en hybridfaktura godkänns en snabb ögonkastskontroll och misslyckas en riktig validator. Relationsträngen accepterar Source, Data, Alternative, Supplement eller Unspecified, och den aktiva profilen måste vara PDF/A-3, PDF/A-4e eller PDF/A-4f — basdel 4-profilen antar inte tillhörande filer. Det äldre AddPDFA3AssociatedFile-namnet fungerar fortfarande för befintlig kod
Vad PDF/UA-2 begär som PDF/UA-1 inte gjorde
PDF/UA-2 tvingar fram PDF 2.0 och emitterar pdfuaid:part=2 med pdfuaid:rev=2024, och det introducerar namnrymder i strukturträdet. Ett del 1-dokument hade ett platt ordförråd av standardroller. Ett del 2-dokument kan bära anpassade roller så länge var och en tillhör en deklarerad namnrymd, vilket är vad som gör domänspecifik taggning begriplig för hjälpteknik i stället för gissningar
Två metoder implementerar detta. RegisterStructureNamespace skapar eller återanvänder en indirekt /Type /Namespace-ordbok och listar den i StructTreeRoot /Namespaces, och returnerar ordboken så att du kan återanvända den. AddStructureElementNS skapar ett strukturelement vars /NS-post pekar på den ordboken, vilket är det som licensierar ett rollnamn utanför standardmängden. Upprepade anrop med samma URI återanvänder en ordbok i stället för att bygga upp dubbletter
var
Root: THPDFDictionaryObject;
begin
Pdf.PDFUACompliance := True;
Pdf.PDFUAPart := 2; // part 2 forces PDF 2.0
Pdf.Lang := 'en-US';
Pdf.BeginDoc;
Root := Pdf.AddStructureElement('Document', nil);
Pdf.AddStructureElementNS('WidgetGroup',
'https://example.com/ns/widgets', Root);
Pdf.EndDoc;
end;
Lang är inte dekoration här. Ett taggat dokument utan deklarerat naturligt språk lämnar en skärmläsare gissande om uttal, och PDF/UA behandlar utelämnandet som en defekt i stället för en preferens
Vilka strukturfel fångar EndDoc?
Fyra, och var och en motsvarar ett dokument som annars skulle nå en validator trasigt. Strukturoten måste innehålla exakt ett toppnivå-Document-element. Varje namnrymdsordbok måste vara indirekt, skriven som Namespace och bära en unik icke-tom URI. Varje strukturelements /NS-referens måste lösa till en ordbok faktiskt listad i rotens /Namespaces-array. Och en onamnrymdsbunden roll måste vara en PDF 2.0-standardroll eller lösa genom RoleMap
Dessa avfyras vid EndDoc eftersom det är det sista ögonblicket hela trädet existerar i minnet och det första ögonblicket det är komplett. Att fånga dem tidigare skulle betyda att förkasta giltiga mellanliggande tillstånd; att fånga dem senare skulle betyda att inte fånga dem alls. Den praktiska konsekvensen för din kod är att ett strukturfel ytar sig i slutet av genereringen med ett meddelande som namnger problemet, i stället för att ytra sig veckor senare som en veraPDF-rapport någon vidarebefordrar från en kund
PDF 2.0-rollerna värda att känna till
Den typade roll-enumen får DocumentFragment, Aside, Title, FENote, Sub, Em, Strong och Artifact. Tre av dem ändrar hur du taggar vanliga affärsdokument. Aside ger äntligen sidospalter och sitatcitat ett hem som inte är en felanvänd Sect. FENote markerar fotnoter och slutnoter som vad de är, så en läsare kan erbjuda dem i stället för att interfoliera dem med brödtext. Em och Strong ersätter den semantiska gissning som kom från att tagga betoning som span-nivå formatering
Strängöverlagringen accepterar dessutom den öppna Hn-formen, inklusive H7 och därutöver. PDF 1.7 stannade vid H6, vilket tvingade djupa tekniska dokument att platta ut sin disposition eller återanvända nivåer. Om du genererar standarddokument, lagtexter eller reservdelskataloger kan detta ensamt vara anledningen att flytta utdata till PDF 2.0
Vad du ska kontrollera innan du växlar produktionsutdata
PDF 2.0 är en headerändring med lång svans. Äldre arkivinläsningsverktyg, vissa tryck-RIP:er och ett förvånansvärt antal affärssystemvisare accepterar endast upp till PDF 1.7, och de misslyckas på headern i stället för på något du gjorde fel. Innan du växlar, bekräfta de konsumerande systemen, och kom ihåg att att välja en PDF/A-4-profil väljer PDF 2.0 oavsett om du bad om det eller inte
En säker sekvens är att behålla PDF/A-3 för dokument som går utåt till okända läsare, använda PDF/A-4f för interna arkiv där du kontrollerar inläsning, och anta PDF/UA-2 endast där tillgänglighetspolicyn namnger det. Om du arbetar genom arkivsidan först, täcker guiderna om PDF/A-, PDF/X- och PDF/UA-validering och om ZUGFeRD- och Factur-X-hybridfakturor på PDF/A-3 de profilval som betyder något innan versionsnumret gör det, och noterna om automatiserad preflight-rapportering visar hur du gör utslaget till del av ditt bygge i stället för ett manuellt steg
HotPDF skeppar hela PDF 2.0-författarytan som inbyggd VCL-kod för Delphi och C++Builder, så PDF/A-4- och PDF/UA-2-utdata behöver ingen extern motor eller redistributabel — HotPDF-komponentsidan listar de profiler och RAD Studio-versioner som stöds