API Reference
This page covers every public function, option, and type in the XLFill library. For guided walkthroughs, see the Getting Started guide.
Top-level functions
Section titled “Top-level functions”These are the simplest way to use XLFill. One function call, done.
func Fill(templatePath, outputPath string, data map[string]any, opts ...Option) errorRead a template file, fill it with data, write the output file.
xlfill.Fill("template.xlsx", "report.xlsx", data)FillBytes
Section titled “FillBytes”func FillBytes(templatePath string, data map[string]any, opts ...Option) ([]byte, error)Read a template file, fill it, return the result as bytes. Useful when you need the output in memory.
bytes, err := xlfill.FillBytes("template.xlsx", data)FillReader
Section titled “FillReader”func FillReader(template io.Reader, output io.Writer, data map[string]any, opts ...Option) errorFill from an io.Reader, write to an io.Writer. Perfect for HTTP handlers — no temp files needed:
func handler(w http.ResponseWriter, r *http.Request) { tmpl, _ := os.Open("template.xlsx") defer tmpl.Close() xlfill.FillReader(tmpl, w, data)}Validate
Section titled “Validate”func Validate(templatePath string, opts ...Option) ([]ValidationIssue, error)Check a template for structural and expression errors without requiring data. Returns a list of issues found. Use this in CI pipelines or during development to catch problems early.
issues, err := xlfill.Validate("template.xlsx")if err != nil { log.Fatal(err) // template couldn't be opened or parsed at all}for _, issue := range issues { fmt.Println(issue) // [ERROR] Sheet1!B2: invalid expression syntax "e.Name +": ...}What it checks:
- Expression syntax — validates all
${...}in cell values and formulas - Command attributes — validates
items,condition,select,headers,dataexpressions - Bounds — verifies each command’s
lastCellfits within its parent area
Describe
Section titled “Describe”func Describe(templatePath string, opts ...Option) (string, error)Parse a template and return a human-readable tree showing the area hierarchy, commands with attributes, and expressions found in cells. Useful for understanding what the engine “sees” when it reads your template.
output, err := xlfill.Describe("template.xlsx")fmt.Print(output)Sample output:
Template: template.xlsxSheet1!A1:C2 area (3x2) Commands: Sheet1!A2 each (3x1) items="employees" var="e" Sheet1!A2:C2 area (3x1) Expressions: A2: ${e.Name} B2: ${e.Age} C2: ${e.Salary}Filler (advanced)
Section titled “Filler (advanced)”For repeated fills or fine-grained control, create a Filler:
filler := xlfill.NewFiller( xlfill.WithTemplate("template.xlsx"), xlfill.WithClearTemplateCells(true), xlfill.WithRecalculateOnOpen(true),)
err := filler.Fill(data, "output.xlsx")
// Validate and Describe also available on Fillerissues, err := filler.Validate()description, err := filler.Describe()Options
Section titled “Options”All options work with both the top-level functions and NewFiller.
Template source
Section titled “Template source”| Option | Description |
|---|---|
WithTemplate(path) | Set template file path |
WithTemplateReader(r io.Reader) | Set template from a reader |
Expression configuration
Section titled “Expression configuration”| Option | Description |
|---|---|
WithExpressionNotation(begin, end) | Custom delimiters (default: ${, }) |
Output control
Section titled “Output control”| Option | Description |
|---|---|
WithClearTemplateCells(bool) | Clear unexpanded ${...} cells (default: true) |
WithKeepTemplateSheet(bool) | Keep template sheet in output (default: false) |
WithHideTemplateSheet(bool) | Hide template sheet instead of removing (default: false) |
WithRecalculateOnOpen(bool) | Tell Excel to recalculate formulas on open |
Extensibility
Section titled “Extensibility”| Option | Description |
|---|---|
WithCommand(name, factory) | Register a custom command |
WithAreaListener(listener) | Add a cell transform hook |
WithPreWrite(fn) | Callback before writing output |
CellRef
Section titled “CellRef”A reference to a single cell:
type CellRef struct { SheetName string Col int // 0-based column index Row int // 1-based row number}AreaRef
Section titled “AreaRef”A rectangular range of cells:
type AreaRef struct { SheetName string FirstCellRef CellRef LastCellRef CellRef}The dimensions of a processed area:
type Size struct { Width int Height int}Command interface
Section titled “Command interface”Implement this to create custom commands:
type Command interface { Name() string ApplyAt(cellRef CellRef, ctx *Context, transformer Transformer) (Size, error) Reset()}AreaListener interface
Section titled “AreaListener interface”Implement this for cell transform hooks:
type AreaListener interface { BeforeTransformCell(src, target CellRef, ctx *Context, tx Transformer) bool AfterTransformCell(src, target CellRef, ctx *Context, tx Transformer)}ValidationIssue
Section titled “ValidationIssue”Returned by Validate():
type Severity intconst ( SeverityError Severity = iota // template will fail at runtime SeverityWarning // template may produce unexpected results)
type ValidationIssue struct { Severity Severity CellRef CellRef Message string}String() formats as [ERROR] Sheet1!A2: message or [WARN] Sheet1!A2: message.
Data input
Section titled “Data input”The data parameter accepts map[string]any. Values can be:
| Type | Example | Template access |
|---|---|---|
| Primitives | string, int, float64, bool | ${name}, ${count} |
| Maps | map[string]any | ${employee.Name} |
| Slices | []any, []Employee | Used in jx:each(items="...") |
| Structs | Any Go struct | ${emp.Name} — fields by name |
| Byte slices | []byte | Used in jx:image(src="...") |
Nested access works via dot notation: ${employee.Address.City}.
What’s next?
Section titled “What’s next?”Having trouble with a template? See the debugging toolkit:
Curious about how XLFill performs at scale?