-
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) |
"$A1ドル" → { 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 csv
import { 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