Servoy plugin for PDF/A-3b conversion and ZUGFeRD / Factur-X e-invoice embedding.
- Servoy 2024.3 or newer
- Java 21
mvn clean packageOutput: target/hvo-pdf-plugin-1.0.0.jar
Copy the JAR to your Servoy installation:
<servoy>/application_server/plugins/hvo-pdf-plugin-1.0.0.jar
Restart Servoy Developer / Application Server after deploying.
Converts a PDF to PDF/A-3b. Optionally embeds a ZUGFeRD or Factur-X XML as an associated file.
| Parameter | Type | Description |
|---|---|---|
pdfBytes |
byte[] |
Source PDF as byte array (e.g. from plugins.file.readFile()) |
xmlBytes |
byte[] |
ZUGFeRD / Factur-X XML as byte array, or null for plain PDF/A-3b conversion |
Returns byte[] — PDF/A-3b document.
Same as above, with additional options.
| Parameter | Type | Description |
|---|---|---|
pdfBytes |
byte[] |
Source PDF |
xmlBytes |
byte[] |
XML to embed, or null |
options |
Object |
Options object (see below) |
Options object fields:
| Field | Type | Default | Description |
|---|---|---|---|
xmlFilename |
String | zugferd-invoice.xml |
Filename of the embedded XML attachment |
creator |
String | HVO PDF Plugin |
XMP creator metadata entry |
title |
String | (empty) | XMP document title |
afRelationship |
String | Data |
Data | Source | Alternative | Supplement |
Returns byte[] — PDF/A-3b document.
Checks the PDF/A conformance status of a PDF by reading its XMP metadata.
| Parameter | Type | Description |
|---|---|---|
pdfBytes |
byte[] |
PDF document as byte array |
Returns String — JSON with the following fields:
| Field | Type | Description |
|---|---|---|
isPdfA |
Boolean | true if PDF/A metadata is present |
part |
Number | PDF/A part (1, 2 or 3), or null |
conformance |
String | Conformance level (A, B, U), or null |
label |
String | Human-readable summary, e.g. PDF/A-3B or Kein PDF/A |
outputIntents |
Number | Number of OutputIntents (must be > 0 for valid PDF/A) |
embeddedFiles |
String[] | Names of all embedded files |
pageCount |
Number | Number of pages |
error |
String | Error message if an exception occurred, otherwise null |
Note: only checks metadata declarations, not a full ISO-19005 validation. Use veraPDF for full validation.
Reads PDF metadata and document info as JSON.
| Parameter | Type | Description |
|---|---|---|
pdfBytes |
byte[] |
PDF document as byte array |
Returns String — JSON with fields: seitenzahl, version, titel, autor, thema, schluesselwoerter, ersteller, produzent, erstelldatum, aenderdatum, pdfa, pdfaLevel.
Normalizes an image for PDF/A embedding: converts to RGB, removes alpha channel, scales to max 500×500 px, outputs as JPEG. Accepts PNG, JPEG, GIF, BMP, WebP.
| Parameter | Type | Description |
|---|---|---|
imageBytes |
byte[] |
Input image as byte array |
Returns byte[] — RGB JPEG, no alpha, max 500×500 px.
Merges multiple PDFs into one.
| Parameter | Type | Description |
|---|---|---|
pdfArray |
Object |
JavaScript array of PDF byte arrays |
Returns byte[] — merged PDF document.
// Convert invoice to PDF/A-3b and embed ZUGFeRD XML
var pdfBytes = plugins.file.readFile('C:/temp/rechnung.pdf');
var xmlBytes = plugins.file.readFile('C:/temp/zugferd.xml');
var pdfa3 = plugins.hvopdf.convertToPdfA3(pdfBytes, xmlBytes, {
xmlFilename: 'factur-x.xml',
creator: 'My Company',
title: 'Invoice 2026-001',
afRelationship: 'Data'
});
plugins.file.writeFile('C:/temp/rechnung_zugferd.pdf', pdfa3);
// Verify PDF/A status
var info = JSON.parse(plugins.hvopdf.checkPdfA(pdfa3));
application.output(info.label); // "PDF/A-3B"
application.output(info.embeddedFiles); // ["factur-x.xml"]
// Read PDF metadata
var meta = JSON.parse(plugins.hvopdf.getPdfInfo(pdfBytes));
application.output('Pages: ' + meta.seitenzahl);
application.output('Author: ' + meta.autor);
// Merge PDFs
var merged = plugins.hvopdf.mergePdfs([
plugins.file.readFile('C:/temp/seite1.pdf'),
plugins.file.readFile('C:/temp/seite2.pdf')
]);
plugins.file.writeFile('C:/temp/gesamt.pdf', merged);MIT