Skip to content

Add Notes

A footnote and an endnote are the same construct pointed at two different places. The note body lives in its own part of the document package, and the place it is anchored is a run inside a paragraph carrying nothing but a reference to that body. UniOffice puts each behind a single call on Paragraph, and the object that call returns is how you add anything past the first line of text.

CallBody partStyles it createsWhere Word puts the body
para.AddFootnote(text)word/footnotes.xmlFootnoteText, FootnoteReferenceBottom of the page holding the mark
para.AddEndnote(text)word/endnotes.xmlEndnoteText, EndnoteReferenceEnd of the document

Nothing else differs. The two run the same code with different targets, and they keep separate id sequences, so a document can hold footnote 1 and endnote 1 at once. Pick by where you want the reader to look: down the page, or at the back.

Adding a note

doc := document.New()
defer doc.Close()

para := doc.AddParagraph()
para.AddRun().AddText("This paragraph has a footnote.")

fn := para.AddFootnote("This is a footnote.")
fn.AddParagraph().AddRun().AddText("And this is its second paragraph.")

para.AddRun().AddText(" Text after the mark.")
para.AddEndnote("This is an endnote.")

doc.SaveToFile("add_footnote_endnote.docx")

The mark is a run appended to the end of the paragraph as it stands when the call is made. That is the whole of the placement control you get: text added before the call sits in front of the mark, text added afterwards sits behind it. There is no call that drops a mark next to a word in a paragraph that is already finished.

The string argument is a convenience. It becomes the last run of the note’s first paragraph, behind an auto-number run and a space. Everything beyond that goes through the returned Footnote or Endnote, whose AddParagraph copies the style of the paragraph before it, so extra paragraphs stay in FootnoteText or EndnoteText without being told to.

The first note of its kind sets the rest up: it creates the part, registers the content type and relationship, adds the paragraph and character styles at 10 point with a superscript mark, and writes the separator and continuation separator entries Word expects. There is no setup call to make first.

Numbering

You do not set the number a reader sees. AddFootnote assigns the note an id one past the highest id already in the part, starting at 1, and writes the same id into the reference run so the two stay connected. The visible number comes from the auto-number run at the head of the note body, which Word fills from the order the marks appear in the text.

Ids and printed numbers are therefore two different things, and they part company as soon as marks are added out of order or a note is removed. Treat the id as a handle for finding the note again, not as its number.

Limitations

A note body holds paragraphs. Footnote and Endnote expose Paragraphs, AddParagraph, RemoveParagraph and X(), and nothing for tables, so a table inside a note means assembling the schema types through X() yourself.

Footnotes() and Endnotes() dereference the part without checking for it, so calling either on a document that has no notes panics with a nil pointer. HasFootnotes() and HasEndnotes() are the guard, and the examples that use them are not being decorative.

Both slices also include the separator and continuation separator entries, which are not notes. Their length is two more than the note count, and calling AddParagraph on one of them panics, because those entries deliberately carry no paragraph properties for the copy to read.

Run.AddFootnoteReference is not how you place a mark. It writes the auto-number element used inside a note body; the anchor element carrying the id is written only by AddFootnote and AddEndnote.

Run the example

The example builds a four-paragraph document with two footnotes and two endnotes. addFootnote and addEndnote are the parts worth reading: each takes a slice of strings, hands the first to AddFootnote or AddEndnote, and appends the rest as further paragraphs on the returned note. Output is add_footnote_endnote.docx.

git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/document/endnotes_footnotes_insert
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