Skip to main content

10 · Styling and branding

Scenario

Output workbooks should match your company's brand — sheet tab colors, font choices, number formats, merged title rows.

Author styles directly in the template

xl3 preserves all template styling. The data block expands rows, but each rendered row inherits the styled template row's font, fill, borders, number format, alignment, etc. Footer rows below the data block keep their styling and shift down as the block expands.

You don't write a "style" directive — Excel styling lives in the template .xlsx itself.

Sheet tabColor

Set the tab color in Excel (right-click the sheet tab → Tab Color). xl3 preserves it verbatim per ADR-0032 #3. Output sheets keep the template's tab color.

Number formats and TEXT()

Two ways to control how a number renders:

1. Cell numFmt on the template cell. Author the template cell with a number format like #,##0.00 or [$₩-ko-KR]#,##0. The formatted output cell carries the same format.

2. TEXT() in the expression. Force a string-typed cell with the exact format you want:

{{ TEXT([Amount], "$#,##0.00") }}
{{ TEXT([Date], "yyyy-mm-dd") }}
{{ TEXT([Pct], "0.0%") }}

Use TEXT() when you need the formatted string in a concatenation: {{ "Total: " & TEXT(SUM([Amount]), "$#,##0") }}.

Supported TEXT() formats follow the core Excel format table. Formats outside the core table are implementation-defined per ADR-0021.

Merged cells

xl3 preserves merges in the template:

  • Merges above the data block stay where they are.
  • Merges below the data block shift down as the data block expands.
  • Merges inside the data block (across cells of one template row) are preserved on every rendered row.

Vertical merges that cross the data-block boundary are implementation-defined per ADR-0021 — avoid them in portable templates.

Headers in merged cells: supported

Vendor templates (거래명세서, 발주서, 정산서) often merge header cells across multiple columns to label a group of fields with one heading. xl3 reads these natively as of 0.5.0 (per ADR-0033): a horizontally- merged header forms one logical column at the merge master, and slave cells in the same row are transparent.

Example: a header row with B1:D1 = "품목" (merged across 3 columns) and E1 = "수량" reads as two source columns 품목 and 수량. Data for 품목 is read from column B; columns C and D are skipped because their cells are merge slaves of B.

Multi-row header bands (2D merges that span both rows and columns) also work — point source_table at the last row of the band so data starts immediately below it. For a J11:M12 band, use source_table = J12:N (not J11:N, which would treat row 12 as a phantom data row carrying the merge master's text).

If the original source genuinely has two columns named the same thing (not because of a merge), xl3/source/duplicate-name still fires. The narrowing only applies to merge slaves.

pageSetup (orientation, margins, print area), views (zoom, frozen panes), and defaultRowHeight are all preserved per ADR-0032 #3. Author them in the template; they carry through to the output.

Notes

  • Workbook properties (themes, defined names, print areas) are preserved verbatim. Set them once in the template; every output inherits.
  • Spec reference: ADR-0032 "Niche limits and workbook pass-through behaviors"; spec/evaluation.md "Cell Evaluation" for cell-level styling.