Typed-xlsx
Schema Builder

Cell Styling

Static and dynamic CellStyle, header styles, border variants, number formats, and column widths.

Every column accepts an optional style for data cells and a separate headerStyle for the header row. Both accept either a static CellStyle object or a callback that receives the current row and returns a CellStyle.

The CellStyle type

import type { 
CellStyle
} from "@chronicstone/typed-xlsx";
const
style
:
CellStyle
= {
font
: {
name
: "Calibri",
size
: 11,
bold
: false,
italic
: false,
underline
: false,
strike
: false,
color
: {
rgb
: "000000" },
},
fill
: {
color
: {
rgb
: "FFFFFF" },
},
border
: {
top
: {
style
: "thin",
color
: {
rgb
: "CCCCCC" } },
right
: {
style
: "thin",
color
: {
rgb
: "CCCCCC" } },
bottom
: {
style
: "thin",
color
: {
rgb
: "CCCCCC" } },
left
: {
style
: "thin",
color
: {
rgb
: "CCCCCC" } },
},
alignment
: {
horizontal
: "left",
vertical
: "center",
wrapText
: false,
},
numFmt
: "General",
};

Every field is optional — pass only what you want to override.

Static styles

Static styles are applied to every data cell in the column regardless of row content.

import { 
createExcelSchema
, type
CellStyle
} from "@chronicstone/typed-xlsx";
const
moneyStyle
:
CellStyle
= {
numFmt
: "$#,##0.00",
alignment
: {
horizontal
: "right" },
}; const
dateStyle
:
CellStyle
= {
numFmt
: "dd/mm/yyyy",
alignment
: {
horizontal
: "center" },
}; const
schema
=
createExcelSchema
<{
amount
: number;
createdAt
:
Date
}>()
.
column
("amount", {
accessor
: "amount",
style
:
moneyStyle
,
}) .
column
("createdAt", {
accessor
: "createdAt",
style
:
dateStyle
,
}) .
build
();

Dynamic styles

Pass a function to compute the style from the row. The function receives (row, rowIndex, subRowIndex).

import { 
createExcelSchema
} from "@chronicstone/typed-xlsx";
type
Order
= {
status
: "paid" | "pending" | "overdue";
amount
: number;
}; const
statusColors
:
Record
<
Order
["status"], string> = {
paid
: "166534",
pending
: "A16207",
overdue
: "B42318",
}; const
schema
=
createExcelSchema
<
Order
>()
.
column
("status", {
accessor
: "status",
style
: (
row
) => ({
font
: {
bold
:
row
.
status
=== "overdue",
color
: {
rgb
:
statusColors
[
row
.
status
] },
},
fill
: {
color
: {
rgb
:
row
.
status
=== "overdue" ? "FEF2F2" : "FFFFFF" },
}, }), }) .
column
("amount", {
accessor
: "amount",
style
: (
row
) => ({
numFmt
: "$#,##0.00",
font
: {
bold
:
row
.
status
=== "overdue" },
}), }) .
build
();

Header styles

Use headerStyle to style the column header independently from its data cells.

import { 
createExcelSchema
, type
CellStyle
} from "@chronicstone/typed-xlsx";
const
darkHeader
:
CellStyle
= {
fill
: {
color
: {
rgb
: "1E3A5F" } },
font
: {
bold
: true,
color
: {
rgb
: "FFFFFF" } },
alignment
: {
horizontal
: "center" },
}; const
schema
=
createExcelSchema
<{
name
: string;
amount
: number }>()
.
column
("name", {
accessor
: "name",
headerStyle
:
darkHeader
})
.
column
("amount", {
accessor
: "amount",
headerStyle
:
darkHeader
,
style
: {
numFmt
: "$#,##0.00" } })
.
build
();

Border styles reference

border.{top,right,bottom,left}.style accepts any of:

"thin" · "medium" · "thick" · "dashed" · "dotted" · "double" · "hair" · "dashDot" · "dashDotDot"

Number format strings

numFmt follows standard Excel format syntax. Common patterns:

FormatExample output
"#,##0"1,234
"#,##0.00"1,234.56
"$#,##0.00"$1,234.56
"0%"75%
"0.00%"75.00%
"dd/mm/yyyy"31/12/2024
"d mmm yyyy"31 Dec 2024
"yyyy-mm-dd"2024-12-31
"hh:mm:ss"14:30:00
"#,##0.00\" €\""1,234.56 €

Column width

Width is set in character units alongside the style fields.

import { 
createExcelSchema
} from "@chronicstone/typed-xlsx";
const
schema
=
createExcelSchema
<{
name
: string;
notes
: string }>()
.
column
("name", {
accessor
: "name",
width
: 25 })
.
column
("notes", {
accessor
: "notes",
width
: 60,
style
: {
alignment
: {
wrapText
: true } } })
.
build
();

Use autoWidth: true to let the engine compute width from the column data. Combine minWidth and maxWidth to bound the auto-computed value.

Copyright © 2026 Cyprien Thao. Released under the MIT License.