Skip to main content

XLSX Templates

XLSX templates produce data-driven spreadsheets. Keep them native for analysts who'll keep editing, or convert to PDF for a frozen report. Velkin fills Handlebars placeholders in the workbook's OOXML, mirroring the DOCX pipeline.

Asset extension.xlsx
EngineHandlebars.js 4.7.8 (goja VM), preprocessed per cell
RendererNative fill, or LibreOffice (soffice) → PDF
Endpointsrender-xlsx (native), render-pdf (converted)

How it works

An .xlsx is OOXML in a ZIP. Velkin renders the parts that hold visible text:

  • xl/sharedStrings.xml — the shared string table most cell text lives in. A {{tag}} typed into a cell usually lands here.
  • xl/worksheets/sheet*.xml — sheet data, including cells stored as inline strings (t="inlineStr").

As with DOCX, tags split across formatting runs inside a shared string are rejoined before substitution.

Cell placeholders

Type Handlebars tags into cells:

AB
1Customer{{customer.name}}
2Total{{total}}

Dotted paths work for nested data ({{customer.address.city}}).

Loops are cell-level

No automatic row expansion

Unlike DOCX, XLSX templates do not promote {{#each}} to repeat whole rows. Excel renumbers and reflows duplicated rows, which produces noisy, broken output, so row-level promotion is intentionally disabled.

Express repetition at the cell-text level instead — build the repeated string inside a single cell, or pre-shape your data so each value maps to a known cell. For genuinely variable-length tables, the DOCX format (which does support row loops) is usually the better fit today.

A cell-level loop builds one string in one cell:

{{#each items}}{{description}}: {{amount}} {{/each}}

Formulas

Formulas authored in the template are preserved — Velkin only substitutes the text it finds in the string tables, it doesn't touch the formula definitions. A cell whose value is computed by a formula recalculates when the workbook is opened (or during PDF conversion).

Helpers & partials

The report's helpers.hbs works in cell text just like in the other formats: it's JavaScript, so register helpers and partials with Handlebars.registerHelper / Handlebars.registerPartial — see Helpers & Partials. As with DOCX, Handlebars escaping is disabled here because the workbook XML is already entity-encoded.

Native vs PDF output

  • render-xlsx returns the filled-in .xlsx — editable, formulas intact.
  • render-pdf converts the filled workbook to PDF with LibreOffice. The print area, page setup, and scaling configured in the workbook drive the resulting layout.

In the Studio, preferredOutput (native / pdf) only picks which endpoint the download button calls — see Output formats.