-
Notifications
You must be signed in to change notification settings - Fork 1
API Reference
Initialize the WASM module. Must be called once before any other operation.
import { initWasm } from 'modern-xlsx';
await initWasm();Read an XLSX file from disk. Node.js / Bun / Deno only.
Read an XLSX file from a buffer. Works in all environments.
Write a workbook to a Blob for browser downloads.
| Property | Type | Description |
|---|---|---|
password |
string |
Password for encrypted XLSX files |
| Property | Type | Description |
|---|---|---|
password |
string |
Password to encrypt the output XLSX file |
const wb = new Workbook();| Property | Type | Description |
|---|---|---|
sheetNames |
string[] |
Names of all sheets |
sheetCount |
number |
Number of sheets |
dateSystem |
'date1900' | 'date1904' |
Date epoch system |
styles |
StylesData |
Styles collection |
namedRanges |
DefinedNameData[] |
Named ranges |
docProperties |
DocPropertiesData | null |
Document metadata |
workbookViews |
WorkbookViewData[] |
View settings |
| Method | Returns | Description |
|---|---|---|
addSheet(name) |
Worksheet |
Add a new sheet |
getSheet(name) |
Worksheet | undefined |
Get sheet by name |
getSheetByIndex(i) |
Worksheet | undefined |
Get sheet by index |
removeSheet(nameOrIndex) |
boolean |
Remove a sheet |
createStyle() |
StyleBuilder |
Create a style builder |
addNamedRange(name, value, sheetId?) |
void |
Add named range |
getNamedRange(name) |
DefinedNameData | undefined |
Get named range |
removeNamedRange(name) |
boolean |
Remove named range |
getPrintTitles(sheet) |
{ rows?, cols? } | null |
Get print title config |
setPrintTitles(sheet, opts) |
void |
Set repeating rows/columns for printing |
getPrintArea(sheet) |
string | null |
Get print area |
setPrintArea(sheet, area) |
void |
Set print area range |
toBuffer(options?: WriteOptions) |
Promise<Uint8Array> |
Serialize to buffer (optionally encrypted) |
toFile(path, options?: WriteOptions) |
Promise<void> |
Write to file (optionally encrypted) |
toJSON() |
WorkbookData |
Get raw data |
All fields are string | null. Set via wb.docProperties = { ... }.
| Field | XML Source | Description |
|---|---|---|
title |
dc:title |
Document title |
subject |
dc:subject |
Document subject |
creator |
dc:creator |
Author |
keywords |
cp:keywords |
Keyword tags |
description |
dc:description |
Comments/description |
lastModifiedBy |
cp:lastModifiedBy |
Last editor |
created |
dcterms:created |
Creation timestamp |
modified |
dcterms:modified |
Last modified timestamp |
category |
cp:category |
Category |
contentStatus |
cp:contentStatus |
Status (e.g. "Draft") |
revision |
cp:revision |
Revision number |
application |
Application |
Generating application name |
company |
Company |
Company name |
manager |
Manager |
Manager name |
appVersion |
AppVersion |
Application version string |
hyperlinkBase |
HyperlinkBase |
Default hyperlink base URL |
| Property | Type | Description |
|---|---|---|
name |
string |
Sheet name (read/write) |
rows |
RowData[] |
All rows |
columns |
ColumnInfo[] |
Column definitions |
mergeCells |
string[] |
Merge ranges |
autoFilter |
AutoFilterData | null |
Auto filter config |
frozenPane |
FrozenPane | null |
Frozen pane config |
hyperlinks |
HyperlinkData[] |
Hyperlinks |
validations |
DataValidationData[] |
Validations |
comments |
CommentData[] |
Cell comments |
pageSetup |
PageSetupData | null |
Page setup |
pageMargins |
PageMarginsData | null |
Page margins |
sheetProtection |
SheetProtectionData | null |
Protection |
usedRange |
string | null |
Computed cell extent (e.g. "B2:D5") or null if empty |
tabColor |
string | null |
Sheet tab RGB hex color (read/write) |
tables |
TableDefinitionData[] |
Tables on this sheet |
headerFooter |
HeaderFooterData | null |
Headers and footers |
outlineProperties |
OutlinePropertiesData | null |
Outline summary position |
charts |
WorksheetChartData[] |
Charts on this sheet |
pivotTables |
readonly PivotTableData[] |
Pivot tables (read-only) |
threadedComments |
readonly ThreadedCommentData[] |
Threaded comments |
slicers |
readonly SlicerData[] |
Slicers (read-only) |
timelines |
readonly TimelineData[] |
Timelines (read-only) |
dimension |
string | null |
Sheet dimension range (e.g. "A1:D10") |
rowCount |
number |
Number of data rows |
| Method | Returns | Description |
|---|---|---|
cell(ref) |
Cell |
Get or create a cell |
setColumnWidth(col, width) |
void |
Set column width |
setRowHeight(row, height) |
void |
Set row height |
setRowHidden(row, hidden) |
void |
Hide/show row |
addMergeCell(range) |
void |
Add merge |
removeMergeCell(range) |
boolean |
Remove merge |
addHyperlink(ref, location, opts?) |
void |
Add link |
removeHyperlink(ref) |
boolean |
Remove link |
addValidation(ref, rule) |
void |
Add validation |
removeValidation(ref) |
boolean |
Remove validation |
addComment(ref, author, text) |
void |
Add comment |
removeComment(ref) |
boolean |
Remove comment |
getTable(name) |
TableDefinitionData | undefined |
Find table by name |
addTable(opts) |
void |
Add an Excel table |
removeTable(name) |
boolean |
Remove table by name |
groupRows(start, end, level?) |
void |
Set outline level on rows |
ungroupRows(start, end) |
void |
Remove outline from rows |
collapseRows(start, end) |
void |
Collapse grouped rows |
expandRows(start, end) |
void |
Expand collapsed rows |
groupColumns(start, end, level?) |
void |
Set outline level on columns |
ungroupColumns(start, end) |
void |
Remove outline from columns |
addChart(type, configure) |
void |
Add chart via callback builder |
addChartData(chart) |
void |
Add pre-built chart data model |
removeChart(index) |
void |
Remove chart by index |
addThreadedComment(cell, text, author) |
string |
Add threaded comment, returns comment ID |
replyToComment(commentId, text, author) |
string |
Reply to comment, returns reply ID |
| Property | Type | Description |
|---|---|---|
reference |
string |
Cell reference (e.g. "A1") |
type |
CellType |
Value type |
value |
string | number | boolean | null |
Cell value (read/write) |
formula |
string | null |
Formula (read/write) |
styleIndex |
number | null |
Style index (read/write) |
numberFormat |
string | null |
Resolved format code from style index |
dateValue |
Date | null |
Returns Date if cell contains a date-formatted number |
Fluent builder for creating cell styles:
const idx = wb.createStyle()
.font({ name: 'Arial', size: 12, bold: true, color: 'FF0000' })
.fill({ pattern: 'solid', fgColor: 'FFFF00' })
.border({ top: { style: 'thin', color: '000000' } })
.alignment({ horizontal: 'center', wrapText: true })
.protection({ locked: true })
.numberFormat('#,##0.00')
.build(wb.styles);| Function | Description |
|---|---|
aoaToSheet(data, opts?) |
Array-of-arrays to Worksheet |
jsonToSheet(data, opts?) |
JSON array to Worksheet |
sheetToJson(ws, opts?) |
Worksheet to JSON array |
sheetToCsv(ws, opts?) |
Worksheet to CSV string |
sheetToHtml(ws, opts?) |
Worksheet to HTML table |
sheetAddAoa(ws, data, opts?) |
Append array data |
sheetAddJson(ws, data, opts?) |
Append JSON data |
sheetToTxt(ws, opts?) |
Worksheet to tab-separated text |
sheetToFormulae(ws) |
Extract all values/formulas as ["A1=100", "A3='SUM(A1:A2)"]
|
| Function | Description |
|---|---|
dateToSerial(date) |
Date/Temporal to Excel serial |
serialToDate(serial) |
Excel serial to Date |
isDateFormatId(id) |
Check if built-in date format |
isDateFormatCode(code) |
Check if date format string |
| Function | Description |
|---|---|
encodeCellRef(row, col) |
(0, 0) → "A1"
|
decodeCellRef(ref) |
"A1" → { row: 0, col: 0 }
|
encodeRange(start, end) |
Addresses to range string |
decodeRange(range) |
Range string to addresses |
columnToLetter(col) |
0 → "A"
|
letterToColumn(letter) |
"A" → 0
|
encodeRow(row) |
0 → "1" (0-based to 1-based) |
decodeRow(str) |
"1" → 0 (1-based to 0-based) |
splitCellRef(ref) |
"$A$1" → { col: "A", row: "1", absCol: true, absRow: true }
|
| Function | Description |
|---|---|
formatCell(value, format) |
Format value with Excel format code |
formatCellRich(value, format) |
Format value, returns { text, color } with color metadata |
getBuiltinFormat(id) |
Get built-in format string by ID |
loadFormat(id, code) |
Register a custom format code at runtime |
loadFormatTable(table) |
Bulk-register format codes by ID (Record<number, string>) |
Draw a styled table on a worksheet from declarative options.
import { drawTable, Workbook } from 'modern-xlsx';
const wb = new Workbook();
const ws = wb.addSheet('Report');
const result = drawTable(wb, ws, {
headers: ['Name', 'Department', 'Salary'],
rows: [
['Alice', 'Engineering', 95000],
['Bob', 'Marketing', 72000],
],
columnWidths: [20, 18, 12],
headerColor: '2F5496',
alternateRowColor: 'D6E4F0',
freezeHeader: true,
autoFilter: true,
columns: [
{ align: 'left' },
{ align: 'center' },
{ align: 'right', numberFormat: '$#,##0' },
],
});
console.log(result.range); // "A1:C3"Create a table from a JSON array with auto-extracted headers.
import { drawTableFromData } from 'modern-xlsx';
drawTableFromData(wb, ws, [
{ name: 'Alice', age: 30, city: 'NYC' },
{ name: 'Bob', age: 25, city: 'LA' },
], {
headerMap: { name: 'Full Name', age: 'Age', city: 'City' },
autoWidth: true,
});| Type | Description |
|---|---|
DrawTableOptions |
Full options for drawTable (headers, rows, styling, merges, cellStyles) |
DrawTableFromDataOptions |
Extends DrawTableOptions with headerMap and optional headers override |
TableResult |
{ range, rowCount, colCount, firstDataRow, lastDataRow } |
TableColumn |
{ header?, width?, align?, numberFormat? } |
CellStyle |
{ font?, fill?, border?, alignment?, numberFormat? } |
See the Table Layout Engine guide for full options reference, recipes, and composition patterns.
| Function | Description |
|---|---|
encodeCode39(data) |
Code 39 barcode matrix |
encodeCode128(data) |
Code 128 barcode matrix |
encodeEAN13(data) |
EAN-13 barcode matrix |
encodeUPCA(data) |
UPC-A barcode matrix |
encodeITF14(data) |
ITF-14 barcode matrix |
encodeGS1128(data) |
GS1-128 barcode matrix |
encodeQR(data) |
QR Code matrix |
encodeDataMatrix(data) |
Data Matrix barcode matrix |
encodePDF417(data) |
PDF417 barcode matrix |
| Function | Description |
|---|---|
renderBarcodePNG(matrix, opts?) |
Render barcode matrix to PNG Uint8Array
|
Options: { scale?: number, margin?: number }
| Function | Description |
|---|---|
generateBarcode(wb, ws, opts) |
One-call barcode generation + XLSX embedding |
generateDrawingXml(anchors) |
Generate drawing XML for image anchors |
generateDrawingRels(rels) |
Generate drawing relationships XML |
DrawBarcodeOptions:
{
type: BarcodeType; // 'code39' | 'code128' | 'ean13' | 'upca' | 'itf14' | 'gs1128' | 'qr' | 'datamatrix' | 'pdf417'
data: string;
anchor: ImageAnchor;
scale?: number;
margin?: number;
}| Type | Description |
|---|---|
BarcodeMatrix |
{ rows: number[][]; width: number; height: number } |
BarcodeType |
Union of supported barcode format strings |
DrawBarcodeOptions |
Options for generateBarcode()
|
ImageAnchor |
{ from: { col, row }, to: { col, row } } |
RenderOptions |
{ scale?: number; margin?: number } |
Add a native Excel table to a worksheet.
ws.addTable({
name: 'SalesTable',
ref: 'A1:D10',
columns: [
{ name: 'Product' },
{ name: 'Region' },
{ name: 'Revenue', totalsRowFunction: 'sum' },
{ name: 'Count', totalsRowFunction: 'count' },
],
style: { name: 'TableStyleMedium9', showRowStripes: true },
totalsRowCount: 1,
});import { TABLE_STYLES, VALID_TABLE_STYLES } from 'modern-xlsx';
TABLE_STYLES.light; // ['TableStyleLight1', ..., 'TableStyleLight21']
TABLE_STYLES.medium; // ['TableStyleMedium1', ..., 'TableStyleMedium28']
TABLE_STYLES.dark; // ['TableStyleDark1', ..., 'TableStyleDark11']
VALID_TABLE_STYLES.has('TableStyleMedium9'); // true| Type | Description |
|---|---|
TableDefinitionData |
Full table definition (name, ref, columns, style, autoFilter, totals) |
TableColumnData |
Column with name, id, optional totalsRowFunction/calculatedColumnFormula |
TableStyleInfoData |
Style name + show flags (rowStripes, columnStripes, firstColumn, lastColumn) |
TotalsRowFunction |
'sum' | 'count' | 'average' | 'min' | 'max' | 'countNums' | 'stdDev' | 'var' | 'custom' | 'none' |
import { HeaderFooterBuilder } from 'modern-xlsx';
const hf = new HeaderFooterBuilder()
.left(HeaderFooterBuilder.date())
.center(HeaderFooterBuilder.bold('Sales Report'))
.right(`Page ${HeaderFooterBuilder.pageNumber()} of ${HeaderFooterBuilder.totalPages()}`)
.build();
ws.headerFooter = {
oddHeader: hf,
oddFooter: new HeaderFooterBuilder()
.center(HeaderFooterBuilder.fileName())
.build(),
};| Method | Code | Output |
|---|---|---|
pageNumber() |
&P |
Current page number |
totalPages() |
&N |
Total pages |
date() |
&D |
Current date |
time() |
&T |
Current time |
fileName() |
&F |
File name |
sheetName() |
&A |
Sheet name |
filePath() |
&Z |
File path |
bold(text) |
&B...&B |
Bold text |
italic(text) |
&I...&I |
Italic text |
fontSize(n, text) |
&n... |
Set font size |
fontName(name, text) |
&"name"... |
Set font |
color(hex, text) |
&K... |
Set color |
// Group rows 2-10 at outline level 1
ws.groupRows(2, 10);
// Nested group at level 2
ws.groupRows(3, 5, 2);
// Collapse/expand
ws.collapseRows(2, 10);
ws.expandRows(2, 10);
// Group columns A-C
ws.groupColumns(1, 3);
// Set summary position
ws.outlineProperties = { summaryBelow: true, summaryRight: true };// Repeat row 1 on every printed page
wb.setPrintTitles('Sheet1', { rows: { start: 1, end: 1 } });
// Repeat columns A-B
wb.setPrintTitles('Sheet1', { cols: { start: 1, end: 2 } });
// Both rows and columns
wb.setPrintTitles('Sheet1', {
rows: { start: 1, end: 2 },
cols: { start: 1, end: 1 },
});
// Set print area
wb.setPrintArea('Sheet1', 'A1:G50');
// Get current config
const titles = wb.getPrintTitles('Sheet1');
const area = wb.getPrintArea('Sheet1');ws.pivotTables; // readonly PivotTableData[]| Type | Description |
|---|---|
PivotTableData |
Full pivot table definition (name, dataCaption, location, fields, axes) |
PivotFieldData |
Pivot field with axis, items, subtotals, name |
PivotDataFieldData |
Data field with fld index, subtotal function, numFmtId |
PivotPageFieldData |
Page field reference |
PivotFieldRef |
Field reference with index |
PivotLocation |
Location reference with firstHeaderRow, firstDataRow, firstDataCol |
PivotItem |
Individual pivot item |
PivotAxis |
'axisRow' | 'axisCol' | 'axisPage' | 'axisValues' |
SubtotalFunction |
'sum' | 'count' | 'average' | 'max' | 'min' | 'product' | 'countNums' | 'stdDev' | 'stdDevP' | 'var' | 'varP' |
// Read
ws.threadedComments; // readonly ThreadedCommentData[]
// Write
const commentId = ws.addThreadedComment('A1', 'Discussion point', 'Alice');
ws.replyToComment(commentId, 'I agree', 'Bob');| Type | Description |
|---|---|
ThreadedCommentData |
Comment with id, ref, personId, text, timestamp, parentId |
PersonData |
Person with id, displayName, providerId |
ws.slicers; // readonly SlicerData[]| Type | Description |
|---|---|
SlicerData |
Slicer definition (name, caption, cacheName, columnName, sortOrder) |
SlicerCacheData |
Slicer cache with items |
SlicerItem |
Individual slicer item |
SortOrder |
'ascending' | 'descending' |
ws.timelines; // readonly TimelineData[]| Type | Description |
|---|---|
TimelineData |
Timeline definition (name, caption, cacheName, sourceName, level) |
TimelineCacheData |
Timeline cache with source and selection |
TimelineLevel |
'years' | 'quarters' | 'months' | 'days' |
# Show workbook info
npx modern-xlsx info report.xlsx
# Convert XLSX to JSON
npx modern-xlsx convert report.xlsx output.json
# Convert single sheet to CSV
npx modern-xlsx convert report.xlsx sheet1.csv --sheet 0 --format csvimport { ModernXlsxError } from 'modern-xlsx';
try {
ws.replyToComment('nonexistent-id', 'text', 'author');
} catch (e) {
if (e instanceof ModernXlsxError) {
console.log(e.code); // 'COMMENT_NOT_FOUND'
console.log(e.message); // 'Comment nonexistent-id not found'
}
}| Code | Description |
|---|---|
INVALID_CELL_REF |
Invalid cell reference string |
WASM_INIT_FAILED |
WASM module initialization failed |
SHEET_NOT_FOUND |
Sheet name or index not found |
COMMENT_NOT_FOUND |
Threaded comment ID not found |
INVALID_ARGUMENT |
Invalid argument value |
Create a Web Worker for off-thread XLSX operations. All WASM operations run in the worker thread.
| Option | Type | Description |
|---|---|---|
workerUrl |
string | URL |
URL to modern-xlsx.worker.js
|
wasmUrl |
string | URL |
Optional custom WASM binary URL |
| Method | Signature | Description |
|---|---|---|
readBuffer |
(data: Uint8Array, options?: { password?: string }) => Promise<WorkbookData> |
Read XLSX bytes (supports encrypted files) |
writeBuffer |
(data: WorkbookData, options?: { password?: string }) => Promise<Uint8Array> |
Write XLSX bytes (supports encryption) |
terminate |
() => void |
Terminate the worker |
const worker = createXlsxWorker({
workerUrl: '/modern-xlsx.worker.js',
});
// Read encrypted file in worker thread
const wb = await worker.readBuffer(data, { password: 'secret' });
// Write encrypted file in worker thread
const encrypted = await worker.writeBuffer(wb, { password: 'secret' });
worker.terminate();Parse and evaluate an Excel formula string.
import { evaluateFormula, createDefaultFunctions } from 'modern-xlsx';
const result = evaluateFormula('SUM(A1:A3)*2', {
currentSheet: 'Sheet1',
functions: createDefaultFunctions(),
getCell: (sheet, col, row) => { /* return cell value */ },
});Returns a pre-loaded registry of 54 built-in Excel functions (SUM, IF, VLOOKUP, etc.).
Parse a formula string into a typed AST.
const { ast, errors } = parseFormula('A1+B1*2');Convert an AST back to a formula string.
Adjust cell references when rows/columns are inserted or deleted.
Derive a child formula from a shared master formula by applying row/col offset.
Resolve a single cell reference to its value.
Resolve a range reference to a 2D array of values.
Tokenize a formula string into typed tokens.
type CellValue = number | string | boolean | null;
interface EvalContext {
getCell(sheet: string, col: number, row: number): CellValue;
currentSheet: string;
functions?: Map<string, FormulaFunction>;
}
type FormulaFunction = (
args: ASTNode[],
ctx: EvalContext,
evaluate: (node: ASTNode, ctx: EvalContext) => CellValue,
) => CellValue;
type RewriteAction =
| { type: 'insert_rows'; row: number; count: number }
| { type: 'delete_rows'; row: number; count: number }
| { type: 'insert_cols'; col: number; count: number }
| { type: 'delete_cols'; col: number; count: number };See the Formula Engine guide for full documentation and examples.
modern-xlsx v1.0.0
Getting Started
Guides
- Charts & Visualizations
- Formula Engine
- Table Layout Engine
- Tables & Print Layout
- Encryption
- Feature Comparison
Reference
Migration
Project