All formats

ODS to JSONOpenDocument (ODS)

LibreOffice & OpenOffice spreadsheets.

ISO-standardized spreadsheet format used by LibreOffice, OpenOffice, and Google Sheets exports. TabularJS reads the XML content directly.

An .ods file is a ZIP archive whose content.xml holds every sheet as <table:table>, <table:table-row> and <table:table-cell> elements. It is the native format of LibreOffice Calc and OpenOffice, and Google Sheets can download a spreadsheet as .ods.

TabularJS unzips the file, reads the cells and their value types, and returns the same worksheets structure it uses for Excel files. Formulas are rewritten from OpenDocument syntax (of:=SUM([.B2:.B3])) to the familiar =SUM(B2:B3).

Feature support

Data values
Formulas
Styles
Merged cells
Comments
Column metadata

What TabularJS extracts from ODS files

Convert ODS to JSON in Node.js

js
import tabularjs from 'tabularjs';

const result = await tabularjs('budget.ods');
const budget = result.worksheets.find((w) => w.worksheetName === 'Budget');

console.log(budget.data);
// [ [ 'Item', 'Cost', 'Paid on' ],
//   [ 'Hosting', 120, '2026-10-01' ],
//   [ 'Domain', 15, '2026-10-05' ],
//   [ 'Total', '=SUM(B2:B3)', '' ],
//   [ 'Prices include VAT', '', '' ] ]
console.log(budget.mergeCells); // { A5: [ 3, 1 ] }

Read ODS files in the browser

js
import tabularjs from 'tabularjs';

// Fetch an .ods file and parse it as a Blob
const response = await fetch('/files/budget.ods');
const blob = await response.blob();

// A Blob has no file name, so the format is detected from the content
const result = await tabularjs(blob);
console.log(result.worksheets.map((w) => w.worksheetName)); // [ 'Budget', 'Notes' ]

JSON output

json
{
  "worksheets": [
    {
      "worksheetName": "Budget",
      "data": [
        ["Item", "Cost", "Paid on"],
        ["Hosting", 120, "2026-10-01"],
        ["Domain", 15, "2026-10-05"],
        ["Total", "=SUM(B2:B3)", ""],
        ["Prices include VAT", "", ""]
      ],
      "columns": [{ "width": 100, "title": "A", "type": "text" }],
      "rows": {},
      "cells": {},
      "style": {},
      "mergeCells": { "A5": [3, 1] },
      "minDimensions": [3, 5],
      "freezeRows": 0,
      "freezeColumns": 0
    },
    { "worksheetName": "Notes", "data": [["Updated monthly"]] }
  ]
}

Trimmed output: only the first column definition is shown and the Notes sheet is shortened. This test file has no styles; a file saved by LibreOffice also has result.style with the CSS of each style, referenced by index from worksheet.style.

Limitations

Frequently asked questions

Can TabularJS read spreadsheets exported from Google Sheets?

Yes. Download the spreadsheet as OpenDocument (.ods) or as Microsoft Excel (.xlsx) and pass the file to tabularjs(). Both give the same worksheets structure.

Why does a formula look different from LibreOffice?

LibreOffice stores formulas in OpenFormula syntax, like of:=SUM([.B2:.B3]). TabularJS rewrites references and separators so you get =SUM(B2:B3), and references to other sheets such as [$Rates.A1] become Rates!A1.

How are ODS dates returned?

As the ISO date string stored in the file, such as 2026-10-01. Convert with new Date(value) when you need a Date object.

Does it need LibreOffice installed?

No. The ZIP archive is opened with JSZip and the XML is parsed in JavaScript, in Node.js or in the browser.

Why TabularJS for OpenDocument (ODS)?