Skip to content

Headers and Footers

Adding a header takes two calls. doc.AddHeader() creates the header part and returns a Header you can fill with paragraphs and tables, but nothing shows it yet. A section has to point at it, which is what SetHeader does. Footers work the same way through AddFooter and SetFooter.

hdr := doc.AddHeader()
para := hdr.AddParagraph()
para.Properties().AddTabStop(2.5*measurement.Inch, wml.ST_TabJcCenter, wml.ST_TabTlcNone)
run := para.AddRun()
run.AddTab()
run.AddText("My Document Title")

doc.BodySection().SetHeader(hdr, wml.ST_HdrFtrDefault)

doc.BodySection() is the section covering everything after the last section break, so on a document with no breaks it is every page. The second argument picks which of the three header slots the section fills.

TypeApplies to
wml.ST_HdrFtrDefaultEvery page, unless a more specific type covers it.
wml.ST_HdrFtrFirstThe first page of the section, once SetTitlePage(true) is set.
wml.ST_HdrFtrEvenEven-numbered pages, once the evenAndOddHeaders setting is on.

The default type is the one to start with. The other two are ignored unless you also turn on the flag that enables them, and neither flag is set for you. SetTitlePage lives on Section; the even/odd flag does not have a typed setter and is covered in Odd and even headers.

Images belong to the header, not the document

A header is a separate part inside the .docx with its own relationships, so an image used in a header has to be registered against the header:

img, err := common.ImageFromFile("gophercolor.png")
iref, err := hdr.AddImage(img)
imgInl, _ := para.AddRun().AddDrawingInline(iref)
imgInl.SetSize(1*measurement.Inch, 1*measurement.Inch)

Header.AddImage and Footer.AddImage add the relationship to that part. Document.AddImage adds it to the main document part instead, and a relationship ID only resolves inside the part that owns it, so a header drawing built from a document-level reference points at nothing the header can see.

AddImage returns an error if the image has no data and no path, no format, or a zero width or height. common.ImageFromFile handles PNG, JPEG, GIF and EMF; for anything else you construct the common.Image yourself with a known format and size.

Positioning without a table

A header paragraph is a normal paragraph, so horizontal placement comes from tab stops. AddTabStop takes a position measured from the left margin, a justification, and a leader character. run.AddTab() then advances to the next stop:

para.Properties().AddTabStop(6*measurement.Inch, wml.ST_TabJcRight, wml.ST_TabTlcNone)
run = para.AddRun()
run.AddText("Some subtitle goes here")
run.AddTab()
run.AddText("Pg ")
run.AddField(document.FieldCurrentPage)
run.AddText(" of ")
run.AddField(document.FieldNumberOfPages)

That gives a left-aligned subtitle and a right-aligned page number on one line. For a layout with more than two or three columns, a table is easier to control; see Header with a table.

AddField writes a field code that Word computes when it opens the document. FieldCurrentPage and FieldNumberOfPages are the two you want here, and Page numbers covers when the numbers actually appear.

Limitations

SetHeader appends a reference rather than replacing one. Calling it twice on the same section with wml.ST_HdrFtrDefault leaves two default header references in the section, and which one Word honors is not something UniOffice controls. To change a header that is already attached, fetch it with GetHeader instead of adding another; see Headers in an existing document.

Headers attach to a section, so a document that later gains a section break needs the header set on each section it should appear in. Nothing propagates.

AddHeader on its own produces a header part in the saved file that no section points at. It costs a few bytes and is otherwise invisible, so a forgotten SetHeader shows up as a document with no header rather than an error.

Run the example

The example builds a header holding a centered title and a one-inch logo, a footer with a subtitle and a page counter, and five paragraphs of body text so there is something for the header to sit above.

git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/document/header-footer
go run main.go

If this is your first time using UniOffice, follow the getting started guide to create an API key and set up your development environment.

View the full source
Last updated on