HotXLS exports a workbook or a single worksheet directly to PDF/A from Delphi and C++Builder, without Excel and without a PDF printer driver. Set UsePDFA and pick a profile on TXLSPDFExport, and the exported file carries an embedded sRGB ICC profile as its output intent, the pdfaid identification block in its XMP metadata, and a PDF version header appropriate for the conformance level
The requirement usually arrives from a records retention policy rather than from a developer. Financial statements, laboratory results, regulatory filings and anything a public body must keep for decades have to be stored in a format that renders identically in fifty years, and that is what PDF/A, ISO 19005, exists to guarantee. A spreadsheet is a live calculation; an archived copy of a spreadsheet has to be a fixed picture of one
What makes a PDF an archival PDF?
Three requirements do most of the work. The file must be self-contained, so every font it uses is embedded and no external resource is referenced. Its color must be unambiguous, which means an output intent naming the color space the file was prepared for. And it must identify itself, through XMP metadata declaring the part number and the conformance level
HotXLS supplies all three. The sRGB profile is embedded as a stream object with three components and DeviceRGB as its alternate, referenced from a GTS_PDFA1 output intent whose condition and identifier both name sRGB IEC61966-2.1. The XMP packet carries the pdfaid part and conformance entries. The profile bytes are compiled into the library rather than loaded at runtime, so there is no deployment step and no chance of a missing file turning an archival export into an ordinary one
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 level 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;
Which profile should you pick?
The profile enumeration covers PDF/A-1, PDF/A-2 and PDF/A-3, each in an accessible variant and a basic variant. The practical differences are narrower than the list suggests
Level B, the basic variant, guarantees that the visual appearance is reproducible. Level A adds structural and semantic requirements, principally a tagged structure tree and a defined reading order, so the document is accessible to assistive technology. Part 2 relaxes some part 1 restrictions and permits object streams and JPEG 2000; part 3 additionally allows arbitrary embedded files, which is what electronic invoicing formats use to carry machine-readable XML alongside the human-readable page
For an archived spreadsheet, PDF/A-2b is the pragmatic default: it is broadly accepted by archives, it does not require the tagging discipline that level A imposes on a grid of cells, and it permits the compact structures that keep a 200-page workbook export from bloating. Choose part 3 when the archive must also carry the source data as an attachment, which the exporter supports through AddAttachment
The font rule that catches most people
Every glyph a PDF/A file draws must come from an embedded font. This is the single most common reason an otherwise correct export fails validation, and the failure mode is subtle: the file looks right on the machine that made it, because that machine has the font installed
HotXLS embeds TrueType subsets for the fonts it uses, but the base-14 fallback path exists for cases where a font cannot be resolved, and a base-14 fallback is not embedded by definition. For archival output, configure an explicit Unicode font file so the fallback path is never taken. The mechanics of subsetting and of the fallback chain are described in TrueType font subsetting; the practical rule is to test the export on a machine that does not have your corporate fonts installed
What the exporter guarantees, and what it does not
Being precise here matters more than sounding confident. The export produces the identification apparatus of PDF/A — output intent, embedded ICC profile, pdfaid metadata, an appropriate version header — and it routes text through the embedding path. It does not run a full validator over its own output, so it does not enforce every prohibition in the specification, such as the rules on transparency, on certain annotation types and on optional content
For a spreadsheet export those constructs rarely appear, which is why the practical success rate is high. But high is not the same as guaranteed, and for a genuine archival pipeline the correct architecture is to export and then validate with an independent tool, treating validation failure as a pipeline error rather than a warning. A comparable division of responsibility for PDF documents is described in PDF/A preflight validation
Layout is part of archival fidelity
An archived spreadsheet that is technically conformant and visually unreadable has failed at its actual job. Page setup carries more weight in an archival export than in an everyday print, because nobody will be able to reflow it later
Three settings pay for themselves. Fit-to-width prevents the classic failure where a table 14 columns wide arrives as seven pages of two columns each. Repeating header rows keep every page readable in isolation. And explicit print areas exclude the working notes that live off to the right of the real data. The full set of print and page-setup controls is covered in protection, page setup and printing
// Archive-ready page setup, applied before the export
Sheet := Book.Sheets[0];
Sheet.PageLandscape := True;
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0; // as many pages tall as needed
Sheet.SetPrintArea('A1:N480');
Sheet.PrintTitleRows := '$1:$3';
// Metadata belongs in the archive too
Book.Title := 'Quarterly results 2026 Q2';
Book.Author := 'Finance';
A checklist before the first batch runs
Confirm the file identifies itself: unzip nothing, just open the PDF in a text editor and look for the pdfaid part and conformance entries and the GTS_PDFA1 output intent. Confirm the fonts: check that every font in the document reports as embedded. Confirm the appearance: compare the exported pages against a printed copy, because a fit-to-page setting that silently shrinks text to four points is conformant and useless
Then run an independent validator over a representative sample and keep the report. Archives increasingly ask for the validation evidence, not just the file, and generating it at export time is far cheaper than reconstructing it years later. For the everyday, non-archival export path and its rendering options, see worksheet PDF export
Archival export, page setup and the rendering engine behind them ship in one library for Delphi and C++Builder; the complete feature list is on the HotXLS Delphi spreadsheet component page