Announcing gooxml

We are pleased to announce gooxml, a AGPLv3 OOXML library written in go supporting:

  • Constructing documents, spreadsheets and presentations in code
  • Fonts, styling, images, etc.

Origins

We need to be able to create documents and spreadsheets and would like to do it from go. Afer investigation, we discovered that there are several go libraries that support creating XLSX files and a few others that support “template” DOCX creation via replacing tokens. There wasn’t, however, a full featured library that allowed creation of all of the OOXML document types covering the vast majority of the OOXML standard. So we built one.

The OOXML standard is very large and apparently open to interpretation1. gooxml provides an easy to use API for common use cases OOXML document construction while enabling falling back to raw OOXML document manipulation should the library’s API not cover a specific use case yet.

Installation

gooxml is go get’able and can be installed via:

go get baliance.com/gooxml/

Example Doc Creation

For an example of what API usage looks like, consider creating a document with a title, header and footer including page numbering. If you’re familiar with OOXML, you’ll notice the API uses similar naming and structure where it makes sense.

package main

import (
	"baliance.com/gooxml/document"
	"baliance.com/gooxml/measurement"
	wml "baliance.com/gooxml/schema/schemas.openxmlformats.org/wordprocessingml"
)

func main() {
	doc := document.New()

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

	// Headers and footers are not immediately associated with a document as a
	// document can have multiple headers and footers for different sections.
	doc.BodySection().SetHeader(hdr, wml.ST_HdrFtrDefault)

	ftr := doc.AddFooter()
	para = ftr.AddParagraph()
	para.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)
	doc.BodySection().SetFooter(ftr, wml.ST_HdrFtrDefault)

	lorem := `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin lobortis, lectus dictum feugiat tempus.`

	for i := 0; i < 5; i++ {
		para = doc.AddParagraph()
		run = para.AddRun()
		run.AddText(lorem)
	}

	doc.SaveToFile("header-footer.docx")
}

Raw Document Manipulation

The raw XML based types reside in the schema/ directory. These types are accessible from the wrapper types via a X() method that returns the raw type.

For example, the library currently doesn’t have an API for setting a document background color. However it’s easy to do manually via editing the CT_Background element of the document.

dox := document.New()
doc.X().Background = wordprocessingml.NewCT_Background()
doc.X().Background.ColorAttr = &wordprocessingml.ST_HexColor{}
doc.X().Background.ColorAttr.ST_HexColorRGB = color.RGB(50, 50, 50).AsRGBString()
gooxml provides validation and attempts to prevent creation of documents which won't work in common editors using the standard API. If you use the .X() methods and raw OOXML manipulation, you can easily create documents that are unusable. If you need to perform some action that the API doesn't support, please file an issue on GitHub.

  1. So far, Word on OSX appears to be the most particular regarding what it will display. We’ve seen 100% validating documents that work in Windows Word, LibreOffice, Apple Pages and Google Docs fail to open in Mac Word. [return]