Skip to content

Getting Started

ABCrimson edited this page Mar 7, 2026 · 17 revisions

Getting Started

Installation

npm install modern-xlsx
# or
pnpm add modern-xlsx
# or
yarn add modern-xlsx

Requires a runtime with WASM support: Node.js 24+, Bun, Deno, or modern browsers.

Initialize WASM

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.

Create a Workbook

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;

Apply Styles

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;

Write to File

// 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);

Read a File

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);

Browser & CDN Usage

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.

jsDelivr

<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>

unpkg

<script src="https://unpkg.com/modern-xlsx@1.0.0/dist/modern-xlsx.min.js"></script>

WASM Auto-Detection

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

Initialization Modes

// 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();

Web Worker Setup

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.


Encryption — Password-Protected Files

Reading Encrypted Files

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).

Writing Encrypted Files

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+.

Security Notes

  • 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"

CLI Tool

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 csv

Threaded Comments

Modern 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);

Next Steps

Clone this wiki locally