Teknisk artikel

Eksportér Excel-projektmapper til PDF/A fra Delphi

HotXLS eksporterer en projektmappe eller et enkelt regneark direkte til PDF/A fra Delphi og C++Builder, uden Excel og uden en PDF-printerdriver. Sæt UsePDFA og vælg en profil på TXLSPDFExport, så bærer den eksporterede fil en indlejret sRGB ICC-profil som sin output intent, identifikationsblokken pdfaid i sin XMP-metadata og en PDF-versionsheader, der passer til konformitetsniveauet

Kravet kommer som regel fra en journaliseringspolitik snarere end fra en udvikler. Regnskaber, laboratorieresultater, myndighedsindberetninger og alt, en offentlig instans skal opbevare i årtier, skal gemmes i et format, der gengives identisk om halvtreds år, og det er, hvad PDF/A, ISO 19005, findes for at garantere. Et regneark er en levende beregning; en arkiveret kopi af et regneark skal være et fastfrosset billede af én

Hvad gør en PDF til en arkiv-PDF?

Tre krav klarer det meste af arbejdet. Filen skal være selvstændig, så hver skrifttype, den bruger, er indlejret, og ingen ekstern ressource refereres. Dens farve skal være entydig, hvilket betyder en output intent, der navngiver den farverum, filen blev forberedt til. Og den skal identificere sig selv gennem XMP-metadata, der angiver delnummer og konformitetsniveau

HotXLS leverer alle tre. sRGB-profilen er indlejret som et stream-objekt med tre komponenter og DeviceRGB som sit alternativ, refereret fra en GTS_PDFA1 output intent, hvis betingelse og identifikator begge navngiver sRGB IEC61966-2.1. XMP-pakken bærer pdfaid-del- og konformitetsposterne. Profilbyttene er kompileret ind i biblioteket frem for indlæst ved runtime, så der er intet installationstrin og ingen risiko for, at en manglende fil gør en arkiveksport til en almindelig eksport

Diagram over de tre PDF/A-arkiveringskrav og det apparat, HotXLS skriver fra Delphi: indlejrede FontFile2-subsets, en GTS_PDFA1 sRGB output intent og pdfaid XMP-identifikation
En PDF/A-fil skal være selvforsynende, farveentydig og selvidentificerende, og HotXLS skriver det matchende apparat ud fra UsePDFA-egenskabsparet
uses
  lxHandleX, lxPDF;

var
  Book: TXLSXWorkbook;
  Exporter: TXLSPDFExport;
begin
  Book := TXLSXWorkbook.Create;
  Exporter := TXLSPDFExport.Create;
  try
    if Book.Open('quarterly-results.xlsx') <> 1 then
      Exit;

    Exporter.UsePDFA := True;
    Exporter.PDFAProfile := xlsPdfA2b;      // ISO 19005-2 niveau B
    Exporter.DocumentLanguage := 'en-GB';
    Exporter.TagMode := xlsPdfTagsAutomatic;

    if Exporter.SaveAsPDF(Book, 'quarterly-results-archive.pdf') <> 1 then
      raise Exception.Create('archival export failed');
  finally
    Exporter.Free;
    Book.Free;
  end;
end;

Hvilken profil bør du vælge?

Profil-enumerationen dækker PDF/A-1, PDF/A-2 og PDF/A-3, hver i en tilgængelig variant og en basisvariant. De praktiske forskelle er snævrere, end listen antyder

Niveau B, basisvarianten, garanterer, at det visuelle udseende er reproducerbart. Niveau A tilføjer strukturelle og semantiske krav, primært et tagget structure tree og en defineret læserækkefølge, så dokumentet er tilgængeligt for hjælpeteknologi. Del 2 lemper nogle af del 1's begrænsninger og tillader object streams og JPEG 2000; del 3 tillader derudover vilkårlige indlejrede filer, hvilket er, hvad elektroniske fakturaformater bruger til at bære maskinlæsbar XML sammen med den menneskeligt læsbare side

For et arkiveret regneark er PDF/A-2b den pragmatiske standard: det accepteres bredt af arkiver, det kræver ikke den tagging-disciplin, som niveau A pålægger et gitter af celler, og det tillader de kompakte strukturer, der forhindrer en 200-siders projektmappe-eksport i at svulme op. Vælg del 3, når arkivet også skal bære kildedataene som en vedhæftning, hvilket eksportøren understøtter via AddAttachment

Skrifttypereglen, der fanger de fleste

Hver glyf, en PDF/A-fil tegner, skal komme fra en indlejret skrifttype. Dette er den absolut hyppigste grund til, at en ellers korrekt eksport fejler validering, og fejltilstanden er subtil: filen ser korrekt ud på den maskine, der lavede den, fordi den maskine har skrifttypen installeret

HotXLS indlejrer TrueType-delmængder for de skrifttyper, den bruger, men fallback-stien til Base 14 findes til de tilfælde, hvor en skrifttype ikke kan opløses, og en Base 14-fallback er per definition ikke indlejret. Til arkivoutput skal du konfigurere en eksplicit Unicode-skrifttypefil, så fallback-stien aldrig bliver taget. Mekanikken bag delmængdedannelse og fallback-kæden er beskrevet i TrueType-skrifttype-delmængdedannelse; den praktiske regel er at teste eksporten på en maskine, der ikke har dine virksomhedsskrifttyper installeret

Diagram over PDF/A skrifttypereglen i HotXLS Delphi-eksporter: opløste skrifttyper bliver indlejrede TrueType-subsets, der validerer alle steder, mens base-14-fallbacken aldrig indlejres og fejler på maskiner uden skrifttypen
En ikke-opløselig font falder tilbage til en base-14-font, der aldrig indlejres, så konfigurér en eksplicit Unicode-fontfil og test på en maskine uden dine virksomhedsfonte

Hvad eksportøren garanterer, og hvad den ikke gør

At være præcis her betyder mere end at lyde selvsikker. Eksporten producerer PDF/A's identifikationsapparat — output intent, indlejret ICC-profil, pdfaid-metadata, en passende versionsheader — og den leder tekst gennem indlejringsstien. Den kører ikke en fuld validator over sit eget output, så den håndhæver ikke ethvert forbud i specifikationen, såsom reglerne om transparens, om visse annotationstyper og om optional content

For en regnearkseksport optræder disse konstruktioner sjældent, hvilket er grunden til, at den praktiske succesrate er høj. Men høj er ikke det samme som garanteret, og for en ægte arkivpipeline er den korrekte arkitektur at eksportere og derefter validere med et uafhængigt værktøj, hvor en valideringsfejl behandles som en pipeline-fejl frem for en advarsel. En sammenlignelig ansvarsfordeling for PDF-dokumenter er beskrevet i PDF/A-preflight-validering

Layout er en del af arkivets troværdighed

Et arkiveret regneark, der er teknisk konformt og visuelt ulæseligt, har fejlet i sit egentlige formål. Sideopsætning vejer tungere i en arkiveksport end i en almindelig udskrift, fordi ingen senere vil kunne omflyde det

Tre indstillinger betaler sig selv hjem. Tilpas-til-bredde forhindrer den klassiske fejl, hvor en tabel på 14 kolonner ender som syv sider med to kolonner hver. Gentagne overskriftsrækker holder hver side læsbar isoleret set. Og eksplicitte udskriftsområder udelukker arbejdsnoterne, der ligger til højre for de reelle data. Det fulde sæt af udskrifts- og sideopsætningskontroller er dækket i beskyttelse, sideopsætning og udskrivning

// Arkivklar sideopsætning, anvendt før eksporten
Sheet := Book.Sheets[0];
Sheet.PageLandscape := True;
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0;                  // så mange sider høj som nødvendigt
Sheet.SetPrintArea('A1:N480');
Sheet.PrintTitleRows := '$1:$3';

// Metadata hører også til i arkivet
Book.Title := 'Quarterly results 2026 Q2';
Book.Author := 'Finance';

En tjekliste før den første batch kører

Bekræft, at filen identificerer sig selv: unzip ikke noget, åbn bare PDF'en i en teksteditor, og kig efter pdfaid-del- og konformitetsposterne og GTS_PDFA1-output intent'en. Bekræft skrifttyperne: tjek, at hver skrifttype i dokumentet rapporterer som indlejret. Bekræft udseendet: sammenlign de eksporterede sider med en udskrevet kopi, fordi en tilpas-til-side-indstilling, der stiltiende krymper tekst til fire punkter, er konform og ubrugelig

Kør derefter en uafhængig validator over en repræsentativ stikprøve, og gem rapporten. Arkiver beder i stigende grad om valideringsbeviset, ikke kun filen, og at generere det på eksporttidspunktet er langt billigere end at rekonstruere det år senere. For den almindelige, ikke-arkivorienterede eksportsti og dens gengivelsesindstillinger, se PDF-eksport af regneark

Arkiveksport, sideopsætning og gengivelsesmotoren bag dem leveres i ét bibliotek til Delphi og C++Builder; den komplette funktionsliste findes på HotXLS Delphi spreadsheet component-siden

Diagram over export-then-validate-arkitekturen for HotXLS Delphi PDF/A-output: eksportøren skriver identifikationsapparatet, og en uafhængig validator ruter filen til arkivet eller rejser en pipelinefejl
Eksportøren bygger identifikationsapparatet, mens en uafhængig validator beviser overensstemmelsen, og en fejlet validering stopper batchen i stedet for at logge en advarsel