PDF export
The PDF export produces a fully formatted .pdf document that mirrors the rendered report. It is the recommended format for printable document exchange and archival workflows. PDF export is included in the core combit.ListLabel32.CrossPlatform package and selected with LlExportTarget.Pdf.
The resulting file preserves layout, fonts, colors, and vector graphics from the report project. Multi-page reports are exported as multi-page PDFs with the page sizes defined in the project.
Two PDF engines
Three export targets produce a .pdf document. They differ in the engine that writes it, not in the report that is rendered.
| Target | Engine | Use it for |
|---|---|---|
Pdf |
Enhanced where available, standard otherwise | The default. Everything the deployment can offer. Where only the standard engine is available, a PDF/A level other than PDF/A-2b, an e-invoice or encryption fails the export instead of being dropped. |
PdfStandard |
Standard SkiaSharp backend, chosen explicitly | Pinning the engine, so the output does not depend on what is deployed on the machine. |
PdfEnhanced |
Enhanced native PDF engine, chosen explicitly | PDF/A levels other than PDF/A-2b, encryption and permissions, embedded ZUGFeRD/Factur-X e-invoices, interactive form fields. |
PdfEnhanced needs its own native library. On Windows it ships with combit.ListLabel32.CrossPlatform, so the enhanced engine is always available on x64 and x86. On Linux and macOS, reference the package for the platform, which also brings the native SkiaSharp assets:
| Platform | Package |
|---|---|
| Linux | combit.ListLabel32.CrossPlatform.NativeAssets.Linux |
| macOS | combit.ListLabel32.CrossPlatform.NativeAssets.macOS |
The library is found next to the application, in the runtimes/<rid>/native folder a NuGet package places it in, or on the system's library search path.
| Runtime identifier | File |
|---|---|
win-x64 |
combit.ListLabel32.ConversionToolsExt.x64.dll |
win-x86 |
combit.ListLabel32.ConversionToolsExt.x86.dll |
linux-x64, linux-musl-x64 |
libcombit-listlabel32-conversiontoolsext.so |
osx-x64, osx-arm64 |
libcombit-listlabel32-conversiontoolsext.dylib |
On Linux, the enhanced engine is available for x64 only, on glibc-based distributions such as Debian or Ubuntu (linux-x64) and on musl-based ones such as Alpine (linux-musl-x64). Linux on ARM64 (linux-arm64, linux-musl-arm64), including ARM64 container images, has the standard engine only. There, as on every other platform not listed, Pdf always uses the standard engine and PdfEnhanced fails.
- With
Pdf, that library is used when it can be loaded and the standard engine is used when it cannot. The choice is written to the log at debug level, naming the engine and, where the native one was taken, its version. - With
PdfEnhanced, a library that cannot be loaded fails the export with a ListLabelException naming the expected file and the runtime identifier it looked for. The export is refused before the report is rendered. PdfStandardnever touches that library.
Important
The two engines are not interchangeable in their output. Text measurement differs - the enhanced
engine applies kerning, the standard one does not - so the same report can break lines differently
under each. With Pdf that means output depends on what is deployed on the machine that runs the
export. Where documents have to match each other, or a stored reference, name PdfStandard or
PdfEnhanced explicitly instead of leaving the choice open.
Note
Fonts resolve differently, too. The enhanced engine looks an installed font up by its family
and style name, which does not reach the named instances of a variable font: Windows lists
Bahnschrift Light, Cascadia Code SemiBold, Segoe UI Variable Text and the Sitka optical
sizes as families of their own, but a variable font carries one family name and defines its
instances separately. A report set in one of those comes out of PdfEnhanced in the platform's
default sans-serif instead, while PdfStandard renders it as designed. Everything a business
document is normally set in - Arial, Calibri, Segoe UI, Times New Roman, Verdana, Tahoma, Georgia,
Courier New - resolves in both. The substitution is logged at debug level, and layout is unaffected
because the substituted font's own metrics are used for measuring.
Note
"No additional native library" is not the same as "no native dependency". The standard backend has
native components of its own - the native SkiaSharp assets, plus the system font and image libraries
on Linux - which every export target needs, PDF or not. See Deployment.
On Windows and macOS the SkiaSharp assets ship with combit.ListLabel32.CrossPlatform, on Linux
with the package listed above. What PdfEnhanced adds is one further library on top of those.
Supported export options
All options are set on ExportConfiguration.ExportOptions using the LlExportOption keys listed below. Values are always strings.
Options for both engines
Document metadata
The following options populate the corresponding fields in the PDF document properties.
| Option | Purpose |
|---|---|
PdfTitle |
Title shown in the PDF properties. |
PdfSubject |
Subject shown in the PDF properties. |
PdfKeywords |
Comma- or semicolon-separated list of keywords. |
PdfAuthor |
Author shown in the PDF properties. |
PdfCreator |
Creator/application name shown in the PDF properties. |
If a metadata option is not set, the corresponding PDF property is left empty.
Resolution
Sets the resolution in DPI at which content is rasterized when it cannot be written as PDF vector graphics:
- PDF objects and PDF table fields, on both engines.
- Charts and SVG drawings, on the enhanced engine only. The standard engine writes them as vector graphics.
Images are embedded at their own resolution and are not affected.
- Value: a positive integer DPI value up to
"2400", for example"300". A higher value is reduced to"2400"; any other value is ignored and the default applies. - Default:
"400". - Increasing the resolution improves the quality of rasterized elements at the cost of file size. A single rasterized element is limited to 64 million pixels; beyond that its resolution is reduced.
Options for the standard engine
Beyond the options above, PdfStandard - and Pdf where the native library cannot be loaded - reads one more:
| Option key | Purpose |
|---|---|
PDF.Conformance |
PDF/A level. This engine writes one of them. |
| Name | Meaning | PDF version written |
|---|---|---|
pdfa2b |
PDF/A-2b (ISO 19005-2, Level B) | 1.4 |
Level U is not offered by this engine. It requires every glyph to map back to Unicode, and the standard engine cannot guarantee that for shaped text such as Indic conjuncts or typographic ligatures. Use the enhanced engine where text has to be reliably extractable.
Any other pdfa* level fails the export with a ListLabelException before the report is rendered, rather than quietly producing a plain PDF - use PdfEnhanced for those, or Pdf to take the enhanced engine wherever its library is deployed. The pdf1x values have no effect here; this engine always writes PDF 1.4, which PDF/A-2 allows. Spelling is as forgiving as below, so "PDF/A-2b" selects the same thing as "pdfa2b".
An e-invoice - PDF.ZUGFeRDXmlPath or the PdfZUGFeRDXmlStream stream - fails the export the same way: this engine cannot embed one, and an invoice PDF without its XML would look finished without being one. So does encryption - PDF.Encryption.EncryptFile set to true, or an owner or user password without EncryptFile being set to false - because the alternative is an unprotected document that was meant to be protected. The permission options on their own ask for no encryption and are ignored.
Options for the enhanced engine
The following options are honored by the enhanced engine only. PdfStandard, and Pdf on a machine where the native library cannot be loaded and the standard engine is used instead, read PDF.Conformance as described above and fail the export where the other options ask for encryption or an e-invoice. Most are set through the string indexer of ExportConfiguration.ExportOptions, having no LlExportOption member in the cross-platform build; the ZUGFeRD options are the exception and have one each:
| Option key | Purpose |
|---|---|
PDF.Conformance |
PDF version and PDF/A level, as one of the names listed below. Unrecognized values mean PDF 1.7 without PDF/A; a value that names PDF/A without a level, such as "PDF/A-2", fails the export. |
PDF.Encryption.EncryptFile |
Encrypt the document. Implied when a password is set. |
PDF.OwnerPassword, PDF.UserPassword |
Owner and user password. Either may be omitted. |
PDF.Encryption.EnablePrinting, ...EnableChanging, ...EnableCopying, ...EnableFillingForms, ...EnableAnnotating |
Permissions of the encrypted document. All are allowed unless explicitly set to "0". |
PDF.ZUGFeRDXmlPath |
Path to the e-invoice XML to embed. Selects pdfa3b unless a PDF/A-3 level is already set, an embedded attachment requiring PDF/A-3. To pass the XML in memory instead, see below. |
PDF.ZUGFeRDConformanceLevel, PDF.ZUGFeRDVersion |
Profile and version of the embedded e-invoice. Auto-detected from the XML when unset. |
PDF.Conformance takes the same names as the classic export, and this engine writes all of them:
| Name | Meaning | PDF version written |
|---|---|---|
pdf14 |
PDF 1.4, and explicitly no PDF/A | 1.4 |
pdf15 |
PDF 1.5 | 1.5 |
pdf16 |
PDF 1.6 | 1.6 |
pdf17 |
PDF 1.7 | 1.7 |
pdf20 |
PDF 2.0 | 2.0 |
pdfa2b |
PDF/A-2b (ISO 19005-2, Level B) | 1.7 |
pdfa2u |
PDF/A-2u (ISO 19005-2, Level U) | 1.7 |
pdfa3b |
PDF/A-3b (ISO 19005-3, Level B) | 1.7 |
pdfa3u |
PDF/A-3u (ISO 19005-3, Level U) | 1.7 |
Spelling is forgiving - anything that reduces to the same letters and digits works, so "PDF/A-2b" and "pdfa2b" are the same value, and so are "PDF 2.0" and "pdf20".
Level A is not offered: it requires a tagged, structurally described document, which this exporter does not produce. Use Level U where text has to be reliably extractable, or Level B where it does not.
Note
PDF/A forbids encryption. Do not combine a pdfa* value with the encryption options below.
The e-invoice XML can also be supplied in memory, through the one option that takes a stream:
exportConfiguration.ExportOptions.Add(LlExportOption.PdfZUGFeRDXmlStream, invoiceXmlStream);
The stream and PDF.ZUGFeRDXmlPath are the same option seen two ways, so set one or the other, not both.
ExportConfiguration exportConfiguration = new ExportConfiguration(
LlExportTarget.PdfEnhanced,
"output/invoice.pdf",
projectFile);
// "PDF/A-3b" selects the same thing.
exportConfiguration.ExportOptions["PDF.Conformance"] = "pdfa3b";
listLabel.Export(exportConfiguration);
Interactive input objects
The report designer's input objects - edit, checkbox and combo box - are exported as interactive
PDF form fields, and only by the enhanced engine - so by PdfEnhanced, or by Pdf where the
native library is available. A reader can fill the resulting document in, and the values can be
extracted from it or submitted.
| Object | Becomes | Carried over |
|---|---|---|
| Edit | Text field, multi-line when the object is | Name, default value, tooltip, alignment, multiline, read-only, required, filling, frame |
| Checkbox | Checkbox, checked when its default value evaluates to true | Name, default state, tooltip, read-only, filling, frame |
| Combo box | Choice field carrying its options, editable when the object is | Name, default value, the choice list, tooltip, alignment, editable, read-only, required, filling, frame |
| Button | not exported | - |
The same applies to the input fields of a table.
Important
Every other export target ignores these objects entirely - they are not drawn, and they take up
no space. A report that relies on them looks incomplete in the PdfStandard, image, XLSX, DOCX,
HTML, JSON and CSV exports - and in Pdf wherever the native library is missing.
Restrictions of the form fields
- Buttons are not exported. A push button is only useful with an action behind it - submit, save, send, sign - and the PDF engine offers no way to attach one, so a button would be an inert rectangle. It is left out rather than exported as decoration.
- The field font is one of four. PDF form fields use the standard form fonts, so a field's text is rendered in Helvetica, Courier, Times or ZapfDingbats - whichever is closest to the requested face - and not in the report's font. Size and colour are kept.
- A field always has a background. The engine cannot express "no background", so a field without a filling gets a white one.
- Field validation is not exported. The designer's verification rules need a script action in the PDF, which the engine does not offer.
- The frame's style is not carried over, only its colour and width; and a checkbox's visual type is left to the reader, which draws the mark itself.
Restrictions
- PDF encryption, owner/user passwords and ZUGFeRD/Factur-X attachments need the enhanced engine: they work with
PdfEnhanced, and withPdfonly where the native library can be loaded.PdfStandarddoes not support them and fails the export when either is requested.PdfUseSimpleFramesfrom the classic exporter is not part of any of the cross-platform PDF exports. - The cross-platform exporter is designed for headless, server-side use; interactive PDF features (form actions, JavaScript) are not authored by the exporter.