Expressions
Expressions are the values inside ${...} in your template cells. They’re evaluated against the current data context and replaced with the result.
Field access
Section titled “Field access”The most common use — access fields on your data:
${employee.Name}${dept.Manager.Email}${company.Address.City}This works with Go structs, maps, or any nested combination.
Arithmetic
Section titled “Arithmetic”Do math directly in the template:
${price * quantity}${subtotal + tax}${total / count}${score * 100 / maxScore}Comparisons and logic
Section titled “Comparisons and logic”${age >= 18} // true or false${status == "active"} // string comparison${price > 100 && inStock} // logical AND${!expired} // negationTernary expressions
Section titled “Ternary expressions”Conditional values without needing a jx:if command:
${age >= 18 ? "Adult" : "Minor"}${score > 90 ? "A" : score > 80 ? "B" : "C"}${active ? "Yes" : "No"}Great for status columns, pass/fail indicators, and conditional labels.
Indexing
Section titled “Indexing”Access items by position:
${items[0].Name} // first item${matrix[row][col]} // 2D access${months[quarterStart]} // dynamic indexString concatenation
Section titled “String concatenation”${firstName + " " + lastName}${prefix + phoneNumber}Mixed text and expressions
Section titled “Mixed text and expressions”A single cell can contain plain text alongside expressions:
Employee: ${e.Name} (${e.Department})Total: ${amount} USDReport generated for ${company.Name}XLFill replaces only the ${...} parts and keeps the surrounding text.
Built-in variables
Section titled “Built-in variables”These are available in every expression automatically:
| Variable | Type | Description |
|---|---|---|
_row | int | Current output row number (1-based) |
_col | int | Current output column index (0-based) |
Row ${_row}: ${e.Name}Useful for row numbering, conditional formatting logic, or debugging.
Built-in functions
Section titled “Built-in functions”hyperlink(url, display)
Section titled “hyperlink(url, display)”Creates a clickable Excel hyperlink:
${hyperlink("https://example.com", "Click here")}${hyperlink(e.ProfileURL, e.Name)}The cell becomes a real Excel hyperlink — blue, underlined, clickable.
Custom delimiters
Section titled “Custom delimiters”If ${...} conflicts with content in your spreadsheet (rare, but possible), change the delimiters:
xlfill.Fill("template.xlsx", "output.xlsx", data, xlfill.WithExpressionNotation("<<", ">>"),)Then use <<e.Name>> in your template instead.
Expression engine
Section titled “Expression engine”Under the hood, expressions are powered by expr-lang/expr, a fast and safe expression evaluator for Go. It supports a rich syntax including:
- All Go operators
- String functions
- Array/slice functions
- Type coercion
- And more — see the expr-lang documentation for the full reference
Expressions are compiled once and cached, so even templates with thousands of rows evaluate quickly (~5 million evaluations per second).
What’s next?
Section titled “What’s next?”Expressions fill individual cells with values. But to control structure — loops, conditions, grids — you need commands. Let’s see how they work.