Excel / Excelize
Choose an adapter
Section titled “Choose an adapter”@alneas/data-engine/excel defines ExcelWorkbookData and the common
ExcelAdapter interface. It exports HTTP, custom Go WASM, CSV and mock adapters.
The mock output is not a usable XLSX file. CSV exports one sheet without Excel
formatting. HttpServerExcelAdapter needs a separately operated backend;
WasmExcelAdapter expects a custom generateExcel(JSON) Go WASM runtime.
For genuine XLSX generation without operating that backend or compiling Go, use
ExcelizeExcelAdapter from the separate @alneas/data-engine/excel/excelize
entry. Install the optional peer explicitly:
npm install @alneas/data-engine excelize-wasm@0.1.3The peer uses BSD-3-Clause; retain its notices when redistributing its assets.
Engine’s root and ordinary /excel entry neither import nor require it. The
Excelize entry loads the peer only when load() or generate() is called.
Its TypeScript declarations require the peer to be installed.
Node.js
Section titled “Node.js”import { createRequire } from 'node:module';import { writeFile } from 'node:fs/promises';import { ExcelizeExcelAdapter } from '@alneas/data-engine/excel/excelize';
const require = createRequire(import.meta.url);const adapter = new ExcelizeExcelAdapter({ wasmPath: require.resolve('excelize-wasm/excelize.wasm.gz'),});const workbook = { metadata: { title: 'Sales' }, sheets: [{ name: 'Sales', columns: [ { header: 'Item', key: 'item', width: 25 }, { header: 'Amount', key: 'amount', format: '#,##0.00' }, ], rows: [{ item: 'Apple', amount: 150 }], cells: [{ cell: 'B4', formula: '=SUM(B2:B3)' }], startRow: 1, }],};await writeFile('sales.xlsx', await adapter.generate(workbook));CommonJS consumers can use require('@alneas/data-engine/excel/excelize').
Use generate() to obtain bytes on the server. As with the existing adapters,
download() triggers a download only when a browser document is available.
Browser assets and initialization
Section titled “Browser assets and initialization”Copy node_modules/excelize-wasm/excelize.wasm.gz to your application’s public
assets as part of its build. Preserve the gzip archive bytes; do not serve it with
Content-Encoding: gzip, which would make the browser decompress the asset before
the upstream loader receives it. No separate wasm_exec.js script is required.
Do not rely on a relative node_modules URL being available in production.
import { ExcelizeExcelAdapter } from '@alneas/data-engine/excel/excelize';
const adapter = new ExcelizeExcelAdapter({ wasmPath: '/assets/excelize.wasm.gz',});// Optional warm-up; generate/download also initialize lazily.await adapter.load();await adapter.download(workbook, 'sales.xlsx');Include your application’s deployment base path in the asset URL. For a cross-origin
asset, configure CORS. Ensure the response is the WASM archive, not an HTML fallback.
Your bundler must resolve the peer’s browser module (main.js); the package’s
Node entry is CommonJS. Package verification checks browser bundling, and quality CI also tests actual
WASM loading, XLSX generation/readback and download in Chromium. Verify your
application’s production asset delivery and CSP setup separately.
CSP must permit WebAssembly compilation and the upstream loader’s JavaScript
implementation. Do not weaken an application’s CSP automatically to enable this
adapter. Edge/Workers execution is not covered by this adapter’s runtime tests.
All adapter instances and both module formats share one initialized runtime in a
JavaScript realm. Use the same exact wasmPath string throughout the application.
A different path is rejected after initialization, and a failed initialization
can be retried. Do not separately call excelize-wasm.init() in that realm: it
replaces the global Go runtime used by existing workbooks. The loader does not
load assets merely because a module is imported.
Workbook mapping and limits
Section titled “Workbook mapping and limits”- At least one worksheet is required. Names must be unique ignoring case and satisfy Excelize’s sheet-name rules. No extra default sheet is retained.
- Table headers start at
startRow. Without it, headers follow the largest row referenced bycells, or start at row 1 when there are no direct cells. Table data follows the header. Directcellsare applied after table data and can override it.null/undefinedleave a cell blank and do not clear an already written table cell. - Cell values support strings, finite numbers, booleans and
Dateobjects. Unsupported objects, arrays, bigint and non-finite numbers are rejected. A string beginning with=stays text; useformulaexplicitly for formulas. - A column with
type: 'date'acceptsDate,YYYY-MM-DD, or ISO timestamps with an explicit timezone. Values become Excel 1900-system date serials using UTC, including time fractions. Supported dates are 1900–9999. Date columns and directDatecells default toyyyy-mm-dd; an explicit format overrides it. Other type hints do not coerce values; supply actual numbers and booleans. - Column
styleformats the header. Columnformatformats its data cells. Cell styles support font, colors, alignment, wrapping, borders and number format. Colors use RGB with or without#. Styles are reused within a workbook. - Merges, column widths, row heights, grid-line visibility and document metadata
map to Excelize. Explicit
colWidthsoverride table-column widths. Omitted widths use Excel’s defaults; this adapter does not auto-fit columns. - Formulas are written and the workbook requests recalculation when opened. Generation does not evaluate formulas or populate cached results. Spreadsheet applications differ in formula support; the adapter is not an Excel calculation engine. Charts, images and existing workbook editing are outside this data model.
- The adapter supports XLSX only. Use
CsvExcelAdapterfor CSV.timeoutMsand HTTPheadersare rejected: WASM generation runs synchronously after loading and cannot be cancelled with a JavaScript timeout. Large workbooks need memory for the WASM runtime and the workbook/output buffers. Use a Worker or a backend at the application level if UI responsiveness requires it.
loadExcelize(wasmPath) returns the shared upstream runtime for advanced uses,
including OpenReader(bytes). Check upstream error results yourself for those
operations. The adapter converts returned upstream errors into rejected promises.
The existing adapters and invoice templates remain compatible. Japanese invoice
presets stay in @alneas/business-jp/excel; pass their workbook definitions to this
adapter. React consumers can pass it to an existing useExcelExport that accepts
ExcelAdapter, without changing the hook interface.
Verification
Section titled “Verification”bun run test:excelize tests the actual packed package with the installed peer in
an isolated consumer. It creates XLSX, reopens it with Excelize, checks Japanese
text, numbers/booleans, dates, formulas, styles, merges, dimensions, metadata,
multiple sheets, initialization sharing/retry and invalid inputs. It runs ESM/CJS
on Node and Bun, checks strict NodeNext declarations without Node types, and
builds the Excelize entry for browsers. bun run test:excelize:browser additionally
checks actual WASM/readback/download with Playwright Chromium and runs in quality
CI. It installs matching Playwright 1.63.0 browser binaries into the isolated
fixture and removes them afterwards. Select additional browsers with EXCELIZE_BROWSERS=chromium,firefox,webkit. test:consumer also verifies peer-free
engine/Excel imports and the missing-peer error. Both are included in verify
and the existing Node 24/26 quality workflow. No service or npm publication is
required for this adapter’s tests.