XLSX to JSON Converter — Turn Excel Sheets into JSON

Analysts and developers who move spreadsheet rows into APIs load a workbook here when the target system wants JSON instead of cells. Typical moments are a CMS migration, a batch of QA fixtures, or an export heading for a REST endpoint that cannot read .xlsx. The converter parses the file in your browser and prints the selected tab as pretty JSON in the records, matrix, or nested shape you choose, with no Excel or Python install.

Workbook conversion Parsed locally with JSZip.

No workbook loaded yet.

No conversion yet.

How It Works

The reader checks the first two bytes for the PK zip signature, which separates a modern workbook from the older binary .xls format; a missing signature stops the run with an error. JSZip then opens xl/workbook.xml to list sheets, follows the relationships part to the worksheet XML, and resolves each cell through sharedStrings.xml or an inline string. Sparse gaps are padded with empty strings so rows keep a stable width.

Styles come from styles.xml: a number format marked as a date (builtin ids 14 to 22 and 45 to 47, or a custom code with y or d) rewrites the stored serial as an ISO date string, with the 1900 epoch offset accounted for. Header keys are trimmed; blanks become columnN and duplicates get a _2 suffix. The parse-numbers pattern converts numeric cells to real JSON numbers while a leading-zero guard keeps 007 as text. Output is JSON.stringify with two-space indentation, all of it client-side.

Before and After

Records: sheet rows become objects
[['name','qty'],
 ['widget',42]]

becomes:

[
  {
    "name": "widget",
    "qty": 42
  }
]
Nested: dotted headers become objects
user.name, user.age
Ada, 36

becomes:

[
  {
    "user": {
      "name": "Ada",
      "age": 36
    }
  }
]

Use Cases

Developer Production Workflow
Seeding test fixtures from sample rows instead of typed JSON Preparing a CMS bulk import from an export Turning a spreadsheet into REST payloads per tab
Committing QA expected values as JSON beside test code Piping an analytics export into a JSON dashboard Migrating legacy spreadsheet records into a JSON archive
Checking a client workbook against a schema Splitting a multi-tab workbook into one file per sheet Reviewing column types by toggling parse numbers

Common Mistakes and Troubleshooting

  • Picking records when row 1 is blank or a title banner. Keys become column1, column2, and so on; move headers up or use matrix.
  • Expecting formulas or colors to survive. Only computed values cross into the JSON; styling is dropped.
  • Loading a legacy .xls file. Those workbooks have no zip signature, so conversion stops with an error; save as .xlsx first.
  • Assuming merged cells fill every column. Excel keeps the value in the top-left cell only; the rest arrive as empty strings.
  • Converting a huge sheet in one pass. Parsing runs on the main thread and can freeze the tab; split the workbook first.
  • Seeing 42 in one export and "42" in another. The parse-numbers checkbox controls that difference; keep it consistent across runs.

Best Practices

  • Clean the header row before exporting: one unique, non-empty name per column, which removes columnN or id_2 repairs.
  • Use records when an API or JavaScript process reads the data, and matrix when the consumer expects a raw grid for math.
  • Turn parse numbers off when leading zeros matter; zip codes, account numbers, and SKUs like 007 keep padding only as strings.
  • Keep one sheet per JSON file: convert each tab separately and name each download after its sheet, matching one-array-per-upload importers.
  • Validate the output with the JSON validator before importing; truncated downloads fail there instead of inside the importer.

Frequently Asked Questions

Which output shape should I pick: records, matrix, or nested?

Records is the pick for APIs: row 1 becomes keys, later rows become objects. Matrix keeps the raw grid with no header logic, which suits coordinate math. Nested reads dotted headers like user.name, building one object level per dot.

Do formulas, colors, and cell formatting survive?

Only cell values move into the JSON. A formula becomes its last computed value, since the workbook caches that result beside the formula text. Colors, fonts, and borders are presentation, so none appear in the output.

How are numbers and dates typed in the output?

With parse numbers on, a cell like 42 or 3.14 becomes a real JSON number. A leading-zero value like 007 stays a string so its padding survives. Date cells are detected through the style sheet and rewritten as ISO strings like 2024-05-14.

How do I convert a workbook with several sheets?

After the first conversion, the sheet dropdown lists every tab under the workbook’s own name. Choosing another sheet re-renders output and stats without reloading. The download button saves the selected tab, so three sheets give three JSON files.

Does the workbook get uploaded to a server?

No. The file is read into page memory, unzipped with JSZip, and parsed by local JavaScript. No request carries your rows or sheet names; the only network traffic is the page loading. Closing the tab releases everything.

Why did my headers turn into column1 or id_2?

A blank header cell becomes columnN by position, so an empty first header becomes column1 rather than an empty key. Duplicates are deduplicated: the second id becomes id_2, the third id_3. Clean the header row first for exact key names.

Should I use the CSV converter instead?

Pick CSV when the toolchain downstream is flat: an importer speaking delimited text with no nested objects. The XLSX to CSV sibling covers quoting, delimiters, and empty-row control. Choose JSON when an API, a fixture, or JavaScript reads the result.