Getting Started
TabularJS is a JavaScript library that converts spreadsheet files to JSON. It supports 16+ formats including Excel (.xls, .xlsx), OpenDocument (.ods), CSV, TSV, SYLK, DIF, dBase, Lotus 1-2-3, and HTML tables. It works in both Node.js and the browser, with only two small runtime dependencies (JSZip and an HTML table parser).
Installation
Section titled “Installation”npm install tabularjsLoad TabularJS directly from a CDN in your HTML:
<script src="https://cdn.jsdelivr.net/npm/tabularjs/dist/index.min.js"></script>Source Code
Section titled “Source Code”MIT licensed: github.com/jspreadsheet/tabularjs
Quick Start
Section titled “Quick Start”Browser
Section titled “Browser”Pass a File object from a file input or drag-and-drop event. TabularJS parses it on the client side and returns JSON.
<html><script src="https://cdn.jsdelivr.net/npm/tabularjs/dist/index.min.js"></script>
<input type="file" id="fileInput" /><pre id="output"></pre>
<script>document.getElementById('fileInput').addEventListener('change', async (e) => { const file = e.target.files[0]; if (file) { const result = await tabularjs(file); document.getElementById('output').textContent = JSON.stringify(result, null, 2); }});</script></html>Node.js
Section titled “Node.js”Pass a file path string. TabularJS reads the file from disk and returns the same JSON structure.
import tabularjs from 'tabularjs';
const result = await tabularjs('path/to/file.xlsx');console.log(result.worksheets[0].data);Raw bytes
Section titled “Raw bytes”Pass a Uint8Array, ArrayBuffer or Node Buffer when the file does not come from disk or a file input (a fetch response, a database, an upload stream). The format is detected from the content; use extension to force it.
import tabularjs from 'tabularjs';
const response = await fetch('/reports/q3');const bytes = new Uint8Array(await response.arrayBuffer());
const result = await tabularjs(bytes);const csv = await tabularjs(bytes, { extension: 'csv' });When a file name has no extension or an unknown one, TabularJS also falls back to detecting the format from the content.
Command Line
Section titled “Command Line”Parse a spreadsheet file directly from the terminal:
node -e "import('tabularjs').then(m => m.default('file.xlsx').then(r => console.log(JSON.stringify(r, null, 2))))"Or create a reusable script:
import fs from 'fs';import tabularjs from 'tabularjs';
const filePath = process.argv[2];
if (!filePath) { console.log('Usage: node script.js <path-to-file>'); process.exit(1);}
if (!fs.existsSync(filePath)) { console.error(`Error: File not found: ${filePath}`); process.exit(1);}
const result = await tabularjs(filePath);console.log(JSON.stringify(result, null, 2));Output Structure
Section titled “Output Structure”Every file format produces the same JSON structure, ready to pass to Jspreadsheet:
{ "worksheets": [ { "worksheetName": "Q1 Report", "data": [ ["Name", "Revenue", "Growth"], ["North", 42000, "=B2*1.1"], ["South", 48500, "=Data!B3*1.1"] ], "columns": [ { "title": "A", "width": 120, "type": "text" }, { "title": "B", "width": 90 }, { "title": "C", "width": 90 } ], "rows": { "0": { "height": 24 } }, "cells": { "A1": { "align": "center" } }, "style": { "A1": 0, "B1": 1 }, "mergeCells": { "A5": [3, 1] }, "comments": { "B2": "Includes returns" }, "minDimensions": [3, 3] } ], "style": [ "font-weight: bold; text-align: center", "text-align: right" ], "definedNames": { "Totals": "Sheet1!$B$2:$B$3" }}Formulas are kept as text in data (with the leading =), so references to other sheets, named ranges and array constants come through as Excel wrote them.
Worksheet
Section titled “Worksheet”| Property | Type | Description |
|---|---|---|
worksheetName |
string | Sheet name (formats with a single table may omit it) |
data |
any[][] | 2D array of cell values: strings, numbers, booleans and formulas ("=SUM(A1:A3)") |
columns |
object[] | One entry per column: title, plus width, type, mask and others when the format has them |
rows |
object | Row metadata keyed by row index, e.g. { "0": { "height": 24 } } |
cells |
object | Per-cell properties keyed by address ("A1"): format, align, wrap… XLS and SYLK also copy each formula here as formula |
style |
object | Style of each cell, keyed by address: an index into the result’s style list |
mergeCells |
object | Merged ranges keyed by the top-left address, value [colspan, rowspan] |
comments |
object | Cell comments keyed by address |
minDimensions |
[number, number] | [columns, rows] of the used range |
worksheetState |
string | "hidden" or "veryHidden"; omitted for visible sheets |
gridline |
boolean | false when the sheet hides its gridlines |
media |
object[] | Images, charts and shapes (XLSX, ODS) |
Result
Section titled “Result”| Property | Type | Description |
|---|---|---|
worksheets |
object[] | One worksheet per sheet in the file |
style |
string[] | Shared CSS styles referenced by each worksheet’s style (XLS, XLSX, ODS) |
definedNames |
object | Named ranges, name to reference (XLSX, ODS) |
Rich formats like XLSX, XLS and ODS fill most of these properties. Text formats like CSV only emit data and columns. The full TypeScript definitions ship with the package (tabularjs/dist/index.d.ts).
Framework Examples
Section titled “Framework Examples”Step-by-step guides for integrating TabularJS in your framework of choice.
- React: Hooks + file input
- Vue: Composition API
- Angular: Standalone component
- JavaScript: Vanilla / CDN
Integration with Jspreadsheet
Section titled “Integration with Jspreadsheet”TabularJS output is directly compatible with Jspreadsheet. Pass the result to jspreadsheet() to render uploaded files as live, editable spreadsheets.
Vanilla JavaScript
Section titled “Vanilla JavaScript”<html><script src="https://cdn.jsdelivr.net/npm/jsuites/dist/jsuites.min.js"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsuites/dist/jsuites.min.css" /><script src="https://cdn.jsdelivr.net/npm/jspreadsheet-ce/dist/index.min.js"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jspreadsheet-ce/dist/jspreadsheet.min.css" /><script src="https://cdn.jsdelivr.net/npm/tabularjs/dist/index.min.js"></script>
<div id="spreadsheet"></div><input type="file" id="fileInput" />
<script>document.getElementById('fileInput').addEventListener('change', async (e) => { const file = e.target.files[0]; if (file) { const result = await tabularjs(file); // tabs: true shows every worksheet of the file jspreadsheet(document.getElementById('spreadsheet'), { ...result, tabs: true }); }});</script></html>React with Jspreadsheet
Section titled “React with Jspreadsheet”import { useRef } from 'react';import jspreadsheet from 'jspreadsheet-ce';import tabularjs from 'tabularjs';
export default function App() { const spreadsheet = useRef(null); const inputRef = useRef(null);
const handleFile = async (e) => { const file = e.target.files[0]; if (file) { const result = await tabularjs(file); jspreadsheet(spreadsheet.current, result); } };
return ( <> <div ref={spreadsheet}></div> <input ref={inputRef} type="file" onChange={handleFile} style={{ display: 'none' }} /> <button onClick={() => inputRef.current.click()}> Load File </button> </> );}Supported Formats
Section titled “Supported Formats”| Format | Extension | Formulas | Styles | Merged Cells |
|---|---|---|---|---|
| Excel 97-2003 | .xls | Yes | Yes | Yes |
| Excel 2007+ | .xlsx | Yes | Yes | Yes |
| OpenDocument | .ods | Yes | Yes | Yes |
| HTML Tables | .html, .htm | Partial | Yes | Yes |
| XML Spreadsheet 2003 | .xml | Yes | No | Yes |
| SYLK | .slk, .sylk | Yes | No | No |
| CSV | .csv | No | No | No |
| TSV | .tsv, .tab | No | No | No |
| Plain Text | .txt | No | No | No |
| DIF | .dif | No | No | No |
| dBase | .dbf | No | No | No |
| Lotus 1-2-3 | .wks, .wk1, .wk3, .wk4, .123 | No | No | No |
See the full supported formats gallery for per-format details and examples.
TypeScript
Section titled “TypeScript”TabularJS ships with TypeScript definitions. Import it normally and you get full type safety:
import tabularjs from 'tabularjs';
const result = await tabularjs('data.xlsx');
// result is fully typedresult.worksheets.forEach((sheet) => { console.log(sheet.data);});Testing
Section titled “Testing”TabularJS includes 540 test cases covering all supported formats:
npm test
