Set Doc Info Metadata
There are two ways to set the /Info dictionary, and they operate at different
scopes. The package-level setters such as model.SetPdfAuthor change a default
applied to every writer created afterwards. PdfWriter.SetDocInfo replaces the
whole dictionary on one writer.
| Approach | Scope | Use it when |
|---|---|---|
model.SetPdfAuthor, SetPdfTitle, SetPdfProducer, … | Process-wide default, read when a writer is constructed | Every document your program writes should carry the same producer or author. |
PdfWriter.SetDocInfo(info) | One writer, overwrites the entire dictionary | Per-document values, or you need custom keys. |
The globals are guarded by a mutex and only read at NewPdfWriter time, so they
have to be set before you build the writer. SetDocInfo overwrites whatever the
globals put there.
Doing it
pdfWriter, err := pdfReader.ToWriter(&model.ReaderToWriterOpts{SkipInfo: true})
if err != nil {
return err
}
info := &model.PdfInfo{
Author: core.MakeString("UniPDF Tester"),
Subject: core.MakeString("PDF with a custom information dictionary"),
}
if err := info.AddCustomInfo("custom_info", "This is an optional custom info"); err != nil {
return err
}
pdfWriter.SetDocInfo(info)
return pdfWriter.WriteToFile("output.pdf")SkipInfo: true stops ToWriter from copying the source document’s /Info over
the writer’s defaults. Without it, the input file’s metadata comes along and you
are editing that rather than starting clean.
The string fields are *core.PdfObjectString, built with core.MakeString.
CreationDate and ModifiedDate are *model.PdfDate, from
model.NewPdfDateFromTime. Trapped is a *core.PdfObjectName.
AddCustomInfo returns an error if the name collides with one of the nine
standard keys, since those belong in the typed fields. It is the only way to get
a non-standard key into the dictionary.
Limitations
SetDocInfo is a replacement, not a merge. Anything you leave nil on the
PdfInfo is absent from the output, including values the globals had supplied.
To edit rather than replace, read the existing dictionary with
PdfReader.GetPdfInfo first, modify it, and pass that back.
Writing /Info does not touch the XMP packet. If the document also carries XMP,
the two will now disagree, which is a PDF/A conformance failure. Use
xmputil.Document.SetPdfInfo to push the same values into the pdf: XMP model.
PdfAppender.SetDocInfo is the equivalent when you are appending an incremental
update instead of writing a fresh file.
Run the example
The example writes two files from one input. gen_pdf_default_author.pdf gets the
author set through model.SetPdfAuthor before the writer exists;
gen_pdf_custom_info.pdf gets a PdfInfo with its own author, subject and one
custom key. Note that customPdfWriter := defaultPdfWriter copies a pointer, not
the writer, so the second SetDocInfo applies to the same writer - the example
works because the first file is written before the info is replaced.
git clone https://github.com/unidoc/unipdf-examples.git
cd unipdf-examples/metadata
go run pdf_metadata_set_docinfo.go template.pdfIf this is your first time using UniPDF, follow the getting started guide to create an API key and set up your development environment.