All formats

XLS to JSONExcel 97-2003 (XLS)

Legacy binary Excel format.

Binary BIFF-based format used by Excel 97 through 2003. TabularJS decodes BIFF records and PTG tokens to reconstruct formulas and data, including references to other sheets and workbooks, named ranges and array formulas. Write-protected (read-only recommended) workbooks open normally.

An .xls file is a binary OLE2 compound document that contains a BIFF8 Workbook stream: a long list of records for strings, fonts, formats, sheets and cells. Formulas are not stored as text but as compiled tokens (PTG), so a reader has to rebuild =SUM(A1:A3) from bytes.

TabularJS does this in plain JavaScript, with no native modules and no Excel or LibreOffice installation, so the same code reads .xls files in Node.js and in the browser. Typical uses are imports of old ERP and accounting exports, archives that were never converted to .xlsx, and files people still save as "Excel 97-2003 Workbook".

Feature support

Data values
Formulas
Styles
Merged cells
Comments
Column metadata

What TabularJS extracts from XLS files

Convert XLS to JSON in Node.js

js
import tabularjs from 'tabularjs';

const result = await tabularjs('legacy-report.xls');

console.log(result.worksheets.map((w) => w.worksheetName));
// [ 'Flow', 'Temp &Injector', 'Detector', 'Gradient', 'RID' ]

const sheet = result.worksheets[1];
console.log(sheet.data[5][4]);         // '=IF((COUNTIF(B6,">"&D6)+COUNTIF(B6,"<"&C6))>0,$K$2,$K$3)'
console.log(sheet.cells.E6.formula);   // same formula, without the leading '='

Read XLS files in the browser

js
import tabularjs from 'tabularjs';

document.querySelector('input[type=file]').addEventListener('change', async (event) => {
  try {
    const result = await tabularjs(event.target.files[0]);
    console.log(result.worksheets[0].data);
  } catch (error) {
    // e.g. 'Workbook is encrypted with a password'
    console.error(error.message);
  }
});

JSON output

json
{
  "worksheets": [
    {
      "worksheetName": "Temp &Injector",
      "data": [
        ["Set Temperature", "Observed Value (°C)", "Acceptance criteria", "", "Results"],
        ["10°C", 10.21, 8, 12, "=IF((COUNTIF(B6,\">\"&D6)+COUNTIF(B6,\"<\"&C6))>0,$K$2,$K$3)"]
      ],
      "columns": [{ "width": 146, "title": "A", "type": "text" }],
      "rows": { "0": { "height": 25.15 } },
      "cells": {
        "E4": { "format": "0.0", "align": "right", "wrap": true },
        "E6": { "formula": "IF((COUNTIF(B6,\">\"&D6)+COUNTIF(B6,\"<\"&C6))>0,$K$2,$K$3)", "align": "right" }
      },
      "style": { "A1": 0, "B1": 1 },
      "mergeCells": { "A1": [10, 1] }
    }
  ],
  "style": ["font-family: Times New Roman; font-size: 11pt; text-align: right; ..."]
}

Trimmed output for a five-sheet laboratory workbook: one sheet, two of its rows (rows 4 and 6 of the sheet) and shortened CSS. The property names are the real ones.

Limitations

Frequently asked questions

How do I read an .xls file in JavaScript?

Install the package with npm install tabularjs, then call await tabularjs('report.xls') in Node.js, or pass the File from a file input in the browser. The result has one entry per sheet in result.worksheets, with the cell values in data.

Are .xls formulas returned as text or as values?

As text. TabularJS rebuilds the formula from its binary tokens and returns it as =SUM(A1:A3) in data and as SUM(A1:A3) in cells['A4'].formula. It does not calculate formulas.

Can TabularJS open password-protected .xls files?

Only write-protected ones. Excel encrypts "read-only recommended" and write-protected workbooks with a default password, which TabularJS decrypts. A workbook that needs a password to open is rejected with an error.

Do I need Excel, LibreOffice or a native module?

No. The CFB container, the BIFF records and the formula tokens are all decoded in JavaScript, so it runs anywhere Node.js or a modern browser runs.

Why TabularJS for Excel 97-2003 (XLS)?