Skip to content
PDF Output

PDF Output

A unihtml.Document is not the PDF. It is a handle on some HTML plus the settings you want applied to it, and there are three ways to turn it into pages. They behave differently enough that picking the wrong one is the most common reason UniHTML output disappoints, so this is the decision to make first.

Just the HTML, nothing else in the file:

err := doc.WriteToFile("out.pdf")

Rendered pages you add to a document you are assembling:

pages, err := doc.GetPdfPages(ctx)

The HTML placed inline, like any other creator component:

err := c.Draw(doc)

What each one does

Measured against a running server, not inferred.

Document.WriteToFileGetPdfPages + c.AddPagec.Draw(document)
Page size from SetPageSizeAppliedAppliedIgnored
MarginsAppliedAppliedIgnored
OrientationAppliedAppliedIgnored
Link annotationsKeptKeptDropped
TrimLastPageContentNo effectNo effectApplied
Creator content in the same fileNoYes, whole pagesYes, in the flow
Takes a context.ContextNoYesNo

The annotation row is the one that surprises people. c.Draw wraps each rendered page with creator.NewBlockFromPage, which flattens it into a content stream, and annotations do not survive that. A page full of <a href> still looks right, blue and underlined, and nothing in it is clickable. Three links survive WriteToFile and GetPdfPages; zero survive c.Draw.

Choosing

Use WriteToFile when the PDF is nothing but the converted HTML. It is a single call and it needs no creator.Creator, which makes it the shortest program that does anything useful.

Use GetPdfPages when you are building a larger document and the HTML contributes whole pages to it. This is also the path to use whenever the markup has links, or whenever the page geometry matters. You get []*model.PdfPage back and add them with c.AddPage.

Use c.Draw when creator content has to sit next to the HTML on the same page: a generated heading above it, a signature block below it. That inline placement is the only thing it gives you that the others do not, and it costs annotations and page control.

A trap when mixing c.Draw with page settings

SetPageSize, SetMargins, SetPageWidth, SetPageHeight and SetPos all switch the document to absolute positioning. On the c.Draw path that changes where the rendered block lands: instead of flowing at the current cursor, it is pinned to the coordinates from SetPos, which default to (0, 0). An A5 document drawn onto a Letter page ends up in the top-left corner with the rest of the sheet empty.

Either leave the geometry alone and let c.Draw flow the content, or set the geometry and take the pages with GetPdfPages. Doing both produces the corner case above.

Where to look

GuideCovers
Extract PagesGetPdfPages, adding rendered pages to a creator, and context timeouts.
Draw into a Documentc.Draw, and trimming the last page so following content sits against it.
ChaptersAdding HTML to a creator.Chapter so it gets a numbered heading and an outline bookmark.
LinksKeeping <a href> clickable, and which path throws the annotations away.
Last updated on