Convert a PDF to PDF/A in Go
Convert produces a PDF/A conformant rewrite. It runs pre-emptive fixups, then a verify/fix loop, and rasterizes pages as a last resort when no in-place fixer can repair them. The output spills to a temp file when it is large, so always Close() the result.
cr, err := gopdfrab.Convert(path, gopdfrab.PDFA1B)
if err != nil {
log.Fatal(err)
}
defer cr.Close() // releases the output (a large one spills to a temp file)
if err := cr.Save("out.pdf"); err != nil {
log.Fatal(err)
}
fmt.Println(cr.Iterations) // how many verify/fixup passes it took
fmt.Println(cr.Result.Valid) // true if the output is fully PDF/A conformantConversion is also available on an already-open document, on in-memory data, across a batch of files, and the result always exposes any residual issues that survived every remediation pass.
// Converting an open document
cr, err := doc.Convert(gopdfrab.PDFA1B)
defer cr.Close()
// Converting in-memory data
cr, err = gopdfrab.ConvertBytes(data, gopdfrab.PDFA1B)
// Converting multiple files concurrently
results, err := gopdfrab.ConvertAll(paths, gopdfrab.PDFA1B)
if err != nil {
log.Fatal(err)
}
for _, r := range results {
if r.Err != nil {
log.Println(r.Path, r.Err)
continue
}
fmt.Println(r.Path, r.Result.Result.Valid) // r.Result is a ConvertResult
}
// Inspecting residual issues after conversion
residual := cr.Residual()
for _, iss := range residual {
c := iss.Check()
fmt.Println(c.Clause(), c.Name())
fmt.Println(iss.Page(), iss.Messages())
} The loop is the important part. Fixing one problem can expose or create another — embedding a font changes the resource dictionary, which the object-model checks then see for the first time — so conversion re-verifies after each pass and repeats until the document converges or Options.MaxIterations is reached. A result is only reported valid if an independent verification pass says so.
Anything that could not be repaired is reported rather than hidden. Check Residual() before treating a conversion as complete: a document that needed an unembeddable font, or that lost an unrecoverable object during damage recovery, will say so there.
Converting a PDF to PDF/A, step by step
- Open or name the document — Call Convert with a path, or ConvertDocument with a document you already opened. Both take the target profile — PDFA1B today.
- Let the verify/fix loop run — Conversion applies pre-emptive fixups, then re-verifies and fixes repeatedly until the document converges or Options.MaxIterations is reached. Pages no in-place fixer can repair are rasterized as a last resort.
- Check the residual issues — Read Residual() before treating the conversion as complete. Anything that could not be repaired — an unembeddable font, an object lost during damage recovery — is reported there rather than hidden.
- Confirm the appearance survived — A page blanked during conversion still verifies clean, so run the fidelity check when visual equivalence matters. It renders both sides and reports a per-page comparison.
- Write the output and close the result — Save writes to a file and WriteTo streams to any io.Writer. The output spills to a temp file when it is large, so always Close() the result.
See fidelity for that, streaming and batching for writing the output, and the browser converter to try it on a file first.