TabularJS
Getting started

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 zero dependencies.

Installation

NPM

bash
npm install tabularjs

CDN

Load TabularJS directly from a CDN in your HTML:

html
<script src="https://cdn.jsdelivr.net/npm/tabularjs/dist/index.min.js"></script>

Source Code

MIT licensed: github.com/jspreadsheet/tabularjs

Quick Start

Browser

Pass a File object from a file input or drag-and-drop event. TabularJS parses it on the client side and returns JSON.

index.htmlhtml
<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

Pass a file path string. TabularJS reads the file from disk and returns the same JSON structure.

server.jsjs
import tabularjs from 'tabularjs';

const result = await tabularjs('path/to/file.xlsx');
console.log(result.worksheets[0].data);

Command Line

Parse a spreadsheet file directly from the terminal:

bash
node -e "import('tabularjs').then(m => m.default('file.xlsx').then(r => console.log(JSON.stringify(r, null, 2))))"

Or create a reusable script:

parse.jsjs
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

Every file format produces the same JSON structure:

json
{
  "worksheets": [
    {
      "data": [
        ["Name", "Revenue", "Growth"],
        ["Q1", 42000, "=B2*1.1"],
        ["Q2", 48500, "=B3*1.1"]
      ],
      "styles": {},
      "mergeCells": {},
      "comments": {}
    }
  ]
}
PropertyTypeDescription
worksheetsArrayArray of worksheet objects, one per sheet in the file
dataArray[]2D array of cell values (strings, numbers, formulas)
stylesObjectCell style definitions (when supported by the format)
mergeCellsObjectMerged cell ranges (when supported by the format)
commentsObjectCell comments (when supported by the format)

Type Definitions

TabularJS ships with TypeScript definitions. The full document shape is:

ts
interface TabularDocument {
  worksheets: Worksheet[];
  meta?: {
    format: string;       // 'xlsx', 'csv', 'html', ...
    source?: string;      // filename when known
  };
}

interface Worksheet {
  name: string;
  data: Cell[][];
  mergeCells?: Record<string, [number, number]>;
  styles?: Record<string, CellStyle>;
  columns?: ColumnMeta[];
  comments?: Record<string, string>;
}

type Cell = string | number | boolean | null | {
  value: string | number | boolean | null;
  formula?: string;
};

Rich formats like XLSX and ODS populate styles, mergeCells, and formula objects. Text formats like CSV only emit data.

Framework Examples

Step-by-step guides for integrating TabularJS in your framework of choice.

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

index.htmlhtml
<html>
<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);
        jspreadsheet(document.getElementById('spreadsheet'), result);
    }
});
</script>
</html>

React with Jspreadsheet

App.jsxjsx
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

FormatExtensionFormulasStylesMerged Cells
Excel 97-2003.xlsYesYesYes
Excel 2007+.xlsxYesYesYes
OpenDocument.odsYesYesYes
HTML Tables.html, .htmPartialYesYes
XML Spreadsheet 2003.xmlYesNoYes
SYLK.slk, .sylkYesNoNo
CSV.csvNoNoNo
TSV.tsv, .tabNoNoNo
Plain Text.txtNoNoNo
DIF.difNoNoNo
dBase.dbfNoNoNo
Lotus 1-2-3.wks, .wk1, .wk3, .wk4, .123NoNoNo

TypeScript

TabularJS ships with TypeScript definitions. Import it normally and you get full type safety:

parse.tsts
import tabularjs from 'tabularjs';

const result = await tabularjs('data.xlsx');

// result is fully typed
result.worksheets.forEach((sheet) => {
    console.log(sheet.data);
});

Testing

TabularJS includes 312+ test cases covering all supported formats:

bash
npm test

Next Steps