npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

xlsx-writer-lite

v0.3.0

Published

A lightweight XLSX writing library

Readme

xlsx-writer

A lightweight TypeScript library for writing XLSX files. Supports plain arrays and object-with-columns modes, multi-sheet workbooks, CSS-like cell styling, and minimal dependencies (~9KB gzipped).

Installation

bun add xlsx-writer-lite
# or
npm install xlsx-writer-lite

Usage

import { writeWorkbook } from 'xlsx-writer-lite';

// Plain 2D array
const blob = await writeWorkbook([
  ['Name', 'Age', 'Active'],
  ['Alice', 30, true],
  ['Bob', 25, false],
]);

// Object mode with columns and header
const blob = await writeWorkbook(
  [
    { name: 'Alice', age: 30, joined: new Date('2024-01-15') },
    { name: 'Bob', age: 25, joined: new Date('2024-06-01') },
  ],
  [
    { id: 'name', label: 'Name', width: 20 },
    { id: 'age', label: 'Age', style: { textAlign: 'right' } },
    { id: 'joined', label: 'Joined', width: 14 },
  ],
  { header: true },
);

// Multiple sheets in one workbook
const blob = await writeWorkbook([
  {
    name: 'People',
    data: [{ name: 'Alice', age: 30 }],
    columns: [{ id: 'name' }, { id: 'age' }],
    header: true,
  },
  {
    name: 'Raw Data',
    data: [
      ['x', 'y'],
      [1, 2],
    ],
  },
]);

API

writeWorkbook(data, settings?)

Creates an XLSX file from a plain 2D array.

| Parameter | Type | Description | | ---------- | ---------------- | ------------------------------- | | data | CellValue[][] | Row-major 2D array of values | | settings | WriteSettings | Optional settings |

Returns: Promise<Blob> — XLSX file blob

writeWorkbook(data, columns, settings?)

Creates an XLSX file from an array of objects with column descriptors.

| Parameter | Type | Description | | ---------- | ------------------------ | ------------------------------ | | data | Record<string, unknown>[] | Array of data objects | | columns | ColumnConfig[] | Column definitions | | settings | WriteSettings | Optional settings |

Returns: Promise<Blob> — XLSX file blob

ColumnConfig:

| Field | Type | Required | Description | | ------------- | ----------- | -------- | ---------------------------------------- | | id | string | yes | Property key to read from each object | | label | string | no | Header label (defaults to id) | | width | number | no | Column width in Excel character units | | style | CellStyle | no | Style applied to every data cell | | headerStyle | CellStyle | no | Style applied to the header cell | | dateFormat | string | no | Excel format code for Date values in this column; overrides the sheet default |

WriteSettings:

| Field | Type | Default | Description | | ------------ | --------- | ---------- | ------------------------------------- | | header | boolean | — | Prepend a header row from labels/ids | | sheetName | string | "Sheet1" | Name of the worksheet tab | | dateFormat | string | m/d/yyyy | Default Excel format code for Date values (e.g. "dd/mm/yyyy hh:mm") | | dateUTC | boolean | false | Write Date values using their UTC reading instead of the local wall clock |

writeWorkbook(sheet, settings?) / writeWorkbook(sheets, settings?)

Creates an XLSX file from one worksheet configuration or an array of them — one Excel tab per config. Each sheet independently uses either 2D-array or object-with-columns data.

| Parameter | Type | Description | | ---------- | ------------------------------------- | --------------------------------- | | sheet(s) | WorksheetConfig \| WorksheetConfig[] | Worksheet definitions | | settings | WorkbookSettings | Optional workbook-level settings |

Returns: Promise<Blob> — XLSX file blob

WorksheetConfig:

| Field | Type | Required | Description | | ------------ | ------------------------------------------- | -------- | -------------------------------------------- | | data | CellValue[][] \| Record<string, unknown>[] | yes | Sheet data: 2D array, or objects (needs columns) | | name | string | no | Tab name (defaults to "Sheet1", "Sheet2", …) | | columns | ColumnConfig[] | no | Column definitions; required for object data | | header | boolean | no | Prepend a header row from labels/ids | | dateFormat | string | no | Default Excel format code for Date values in this sheet | | dateUTC | boolean | no | Write Date values using their UTC reading |

WorkbookSettings:

| Field | Type | Description | | ---------------------- | -------------------------- | ------------------------------------------------- | | defaultSheetSettings | Partial<WorksheetConfig> | Defaults merged into every sheet config; per-sheet values win |

// Shared defaults across sheets
const blob = await writeWorkbook(
  [
    { name: 'Q1', data: q1Rows, columns },
    { name: 'Q2', data: q2Rows, columns },
  ],
  { defaultSheetSettings: { header: true, dateFormat: 'dd/mm/yyyy' } },
);

Dates and Timezones

Excel serial dates are timezone-naive wall-clock values. By default, Date values are written as the local wall clock — the same date and time the user's browser displays. Set dateUTC: true (per call or per sheet) to write the UTC reading instead, which is useful for server timestamps that should render identically for every user.

Helper Functions

columnLetter(index)

Converts a 0-based column index to an Excel column letter.

import { columnLetter } from 'xlsx-writer-lite';

columnLetter(0);   // → "A"
columnLetter(25);  // → "Z"
columnLetter(26);  // → "AA"

jsDateToExcelDate(date, utc?)

Converts a JavaScript Date to an Excel serial date number. Uses the date's local wall clock by default; pass true as the second argument for its UTC reading.

import { jsDateToExcelDate } from 'xlsx-writer-lite';

jsDateToExcelDate(new Date(2025, 0, 15)); // → 45672
jsDateToExcelDate(new Date('2025-01-15T00:00:00Z'), true); // → 45672

Cell Types

| JavaScript Type | Excel Cell Type | Notes | | --------------- | --------------- | ------------------------------------- | | string | Shared string | Deduplicated in shared string table | | number | Number | Written as-is | | boolean | Boolean | true → 1, false → 0 | | Date | Number + format | Serial date with m/d/yyyy format | | null | Empty | Cell omitted (unless styled) |

Cell Styles

Styles use a rigid CSS subset — the same CellStyle shape as xlsx-reader-lite

interface CellStyle {
  fontWeight?: 'bold';
  fontStyle?: 'italic';
  textDecoration?: string;      // "underline", "line-through", "underline line-through"
  fontSize?: string;            // "11pt"
  fontFamily?: string;          // "Calibri"
  color?: string;               // "#FF0000"
  backgroundColor?: string;     // "#FFFF00"
  borderTop?: string;           // "1px solid #000000"
  borderRight?: string;
  borderBottom?: string;
  borderLeft?: string;
  textAlign?: 'left' | 'center' | 'right' | 'justify';
  verticalAlign?: 'top' | 'middle' | 'bottom';
  whiteSpace?: 'normal' | 'nowrap' | 'pre-wrap';
}

Border Shorthand

Borders use CSS shorthand "<width> <style> <color>":

| CSS Value | Excel Style | | ------------------ | ------------------ | | 1px solid #000 | thin | | 2px solid #000 | medium | | 3px solid #000 | thick | | 1px dashed #000 | dashed | | 1px dotted #000 | dotted | | 3px double #000 | double | | 2px dashed #000 | mediumDashed | | 2px dotted #000 | mediumDashDotDot |

Style Example

const blob = await writeWorkbook(
  [{ product: 'Widget', total: 1500 }],
  [
    {
      id: 'product',
      label: 'Product',
      width: 25,
      headerStyle: {
        fontWeight: 'bold',
        backgroundColor: '#4472C4',
        color: '#FFFFFF',
        borderBottom: '2px solid #000000',
      },
    },
    {
      id: 'total',
      label: 'Total',
      style: { textAlign: 'right' },
      headerStyle: {
        fontWeight: 'bold',
        backgroundColor: '#4472C4',
        color: '#FFFFFF',
        borderBottom: '2px solid #000000',
      },
    },
  ],
  { header: true },
);

Browser Usage

For CDN/browser usage, use the bundled version:

<script type="module">
  import { writeWorkbook, downloadBlob } from './index.bundle.js';

  const blob = await writeWorkbook([
    ['Name', 'Score'],
    ['Alice', 95],
  ]);

  downloadBlob(blob, 'report.xlsx');
</script>

Bundle Size

| Build | Size | | ------------------ | ------ | | Library (ESM) | ~17 KB | | Bundled (all deps) | ~21 KB | | Bundled + gzipped | ~9 KB |

License

MIT