EatSheet.xlsx
npm
A1
=HELP("eatsheet")

Docs

Open a workbook, show it, read its cells. EatSheet reads XLSX, CSV and TSV.
Quick start
npm install eatsheet
import { openWorkbook } from 'eatsheet/worker';
import 'eatsheet/eatsheet.css';

const container = document.querySelector('#sheet'); // give it a fixed height and overflow: auto
const book = await openWorkbook(fileOrUrl);          // a File, Blob, URL, Response or ArrayBuffer

const draw = async () => (container.innerHTML = (await book.render(0, { offset: container.scrollTop })).html);
container.addEventListener('scroll', () => requestAnimationFrame(draw));
await draw();
That's a complete viewer. Only the rows in view are rendered. Pass another index to render() to switch sheets, and call book.close() when you're done. Browsers need Chrome 103+, Firefox 113+ or Safari 16.4+. Node.js 20.12+ works for server-side reading.
Reading cells
import { read, renderSheet } from 'eatsheet';

const book = await read(fileOrUrl, { headers: { Authorization: token } });
const sheet = book.sheet('Summary') ?? book.sheets[0];

sheet.cell('B2');   // { address, row, col, type, value, style, formula?, cached?, status?, reason? }
for (const cell of sheet.cells('A1:D20')) console.log(cell.address, cell.value);

const html = renderSheet(sheet, { startRow: 1, rowCount: 100, startCol: 1, colCount: 50 });
Topic
How it works
Inputs
A URL or URL, File/Blob, Response, ArrayBuffer or typed array. Downloads stream with a 25 MB default cap.
Values
A cell's type is number, string, boolean, error or empty. Dates stay Excel serial numbers, and style.numFmt decides how they display.
Formulas
value is the current result and cached is the one saved in the file. status says how the value was obtained.
Limits
The full Excel grid, 5,000,000 stored cells per sheet by default, and 4,096 sheets per workbook.
Timeouts
Each openWorkbook call has 30 seconds by default, then rejects with TIMEOUT. Pass timeout to change it.
Diagnostics
inspect(book) lists sheets and warns about anything EatSheet could not render or calculate.
Error code
Meaning
UNSUPPORTED_BROWSER
The browser lacks native decompression
LEGACY_XLS
An old binary .xls file
MALFORMED_FILE
Corrupt or not a spreadsheet
UNSAFE_FILE
Encrypted, or contains unsafe content
LIMIT_EXCEEDED
Too large for the configured limits
NETWORK
The download failed
INVALID_ARGUMENT
Bad input, such as an invalid cell reference
WORKER_FAILED / CLOSED
The worker could not start, or the workbook was closed
TIMEOUT
A worker call took longer than its timeout
Supported
Not yet
Fonts, fills, borders, alignment, wrapping, merged cells, hidden rows and columns, widths and heights, Excel number formats, most conditional formatting, and shared formulas across sheets.
Writing or editing files, charts, images and drawings, .xls, .xlsb and .ods files, encrypted workbooks, colours in number formats, print layout.
Calculated functions: SUM AVERAGE MIN MAX COUNT COUNTA PRODUCT IF AND OR NOT CONCATENATE CONCAT LEN LEFT RIGHT MID ROUND ABS INT MOD. Any other formula shows the result saved in the file.
Coming from SheetJS
EatSheet
XLSX.read(data)
await read(data)
wb.SheetNames
book.sheets.map(s => s.name)
wb.Sheets[name]
book.sheet(name)
ws['B2']?.v
sheet.cell('B2')?.value
ws['!merges']
sheet.merges
XLSX.utils.sheet_to_html(ws)
renderSheet(sheet)