-
Notifications
You must be signed in to change notification settings - Fork 1
Getting Started
npm install modern-xlsx
# or
pnpm add modern-xlsx
# or
yarn add modern-xlsxRequires a runtime with WASM support: Node.js 24+, Bun, Deno, or modern browsers.
Before any operation, initialize the WASM module once:
import { initWasm } from 'modern-xlsx';
await initWasm();This loads and compiles the ~939 KB WASM binary. Call it once at application startup.
import { Workbook } from 'modern-xlsx';
const wb = new Workbook();
const ws = wb.addSheet('Sheet1');
// Set values
ws.cell('A1').value = 'Name';
ws.cell('B1').value = 'Age';
ws.cell('A2').value = 'Alice';
ws.cell('B2').value = 30;const headerStyle = wb.createStyle()
.font({ bold: true, size: 12, color: '1F4E79' })
.fill({ pattern: 'solid', fgColor: 'D6E4F0' })
.alignment({ horizontal: 'center' })
.build(wb.styles);
ws.cell('A1').styleIndex = headerStyle;
ws.cell('B1').styleIndex = headerStyle;// Node.js / Bun / Deno
await wb.toFile('output.xlsx');
// Any environment (returns Uint8Array)
const buffer = await wb.toBuffer();
// Browser (returns Blob)
import { writeBlob } from 'modern-xlsx';
const blob = writeBlob(wb);import { readFile, readBuffer } from 'modern-xlsx';
// From file path
const wb = await readFile('data.xlsx');
// From buffer
const wb = await readBuffer(uint8Array);
// Access data
const ws = wb.getSheet('Sheet1');
console.log(ws?.cell('A1').value);modern-xlsx ships a self-contained IIFE browser bundle (modern-xlsx.min.js, ~29 KB) that exposes the full API on window.ModernXlsx. No bundler required.
<script src="https://cdn.jsdelivr.net/npm/modern-xlsx@1.0.0/dist/modern-xlsx.min.js"></script>
<script>
(async () => {
await ModernXlsx.initWasm();
const wb = new ModernXlsx.Workbook();
const ws = wb.addSheet('Sheet1');
ws.cell('A1').value = 'Hello from CDN!';
const blob = ModernXlsx.writeBlob(wb);
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'hello.xlsx';
a.click();
URL.revokeObjectURL(url);
})();
</script><script src="https://unpkg.com/modern-xlsx@1.0.0/dist/modern-xlsx.min.js"></script>The IIFE bundle automatically detects the correct WASM binary URL using detectWasmUrl(). It derives the URL relative to the script's src attribute, so the .wasm file is loaded from the same CDN path as the .js file — no manual configuration needed.
If you self-host the files, place modern-xlsx.wasm alongside modern-xlsx.min.js:
/static/
modern-xlsx.min.js
modern-xlsx.wasm
// Async init (recommended for browsers)
await ModernXlsx.initWasm();
// Async init with custom WASM URL
await ModernXlsx.initWasm('https://my-cdn.example.com/modern-xlsx.wasm');
// Synchronous init from pre-loaded buffer (Node.js / tests)
const wasmBytes = fs.readFileSync('modern-xlsx.wasm');
ModernXlsx.initWasmSync(wasmBytes);
// Lazy auto-init on first use
await ModernXlsx.ensureReady();For large files, offload XLSX processing to a Web Worker to keep the UI responsive:
<script src="https://cdn.jsdelivr.net/npm/modern-xlsx@1.0.0/dist/modern-xlsx.min.js"></script>
<script type="module">
const worker = ModernXlsx.createXlsxWorker({
workerUrl: 'https://cdn.jsdelivr.net/npm/modern-xlsx@1.0.0/dist/modern-xlsx.worker.js',
});
// Read file in worker thread
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async (e) => {
const file = e.target.files[0];
const buffer = new Uint8Array(await file.arrayBuffer());
const data = await worker.readBuffer(buffer);
console.log('Sheets:', Object.keys(data.sheets));
});
// Clean up when done
// worker.terminate();
</script>The worker script (modern-xlsx.worker.js) initializes WASM internally on first use. All parsing and serialization run off the main thread.
import { readFile, readBuffer } from 'modern-xlsx';
// From file path
const wb = await readFile('protected.xlsx', { password: 'secret123' });
// From buffer
const wb = await readBuffer(uint8Array, { password: 'secret123' });Supports both Agile Encryption (Excel 2010+) and Standard Encryption (Excel 2007).
const wb = new Workbook();
const ws = wb.addSheet('Sheet1');
ws.cell('A1').value = 'Confidential Data';
// Write to file with encryption
await wb.toFile('encrypted.xlsx', { password: 'secret123' });
// Write to buffer with encryption
const buffer = await wb.toBuffer({ password: 'secret123' });Encrypted files use AES-256-CBC with SHA-512 (Agile Encryption) — the same format as Excel 2010+.
- Key material is automatically zeroized from memory after use
- Password verification uses constant-time comparison (timing-safe)
- HMAC-SHA-512 integrity check detects file tampering
- Empty string passwords are treated as "no encryption"
modern-xlsx includes a CLI for quick file inspection and conversion:
# Show workbook info (sheet names, dimensions, row counts)
npx modern-xlsx info report.xlsx
# Convert XLSX to JSON
npx modern-xlsx convert report.xlsx output.json
# Export single sheet as CSV
npx modern-xlsx convert report.xlsx sheet1.csv --sheet 0 --format csvModern Excel threaded comments with reply threads:
const ws = wb.addSheet('Discussion');
ws.cell('A1').value = 'Topic';
// Start a comment thread
const commentId = ws.addThreadedComment('A1', 'What do we think about this?', 'Alice');
// Reply to the thread
ws.replyToComment(commentId, 'Looks good to me!', 'Bob');
ws.replyToComment(commentId, 'Agreed, let\'s proceed.', 'Charlie');
// Read all threaded comments
console.log(ws.threadedComments);- Table Layout Engine — Generate styled tables from declarative options
- Styling Guide — Full styling reference
- API Reference — Complete API docs
- Examples — Browser, Web Worker, and framework examples
- Performance — Optimization tips
modern-xlsx v1.0.0
Getting Started
Guides
- Charts & Visualizations
- Formula Engine
- Table Layout Engine
- Tables & Print Layout
- Encryption
- Feature Comparison
Reference
Migration
Project