How to convert Excel to JSON
- Drop an
.xlsx,.xls,.xlsm,.xlsbor.odsfile into the box above. It is read in your browser and never uploaded. - Pick the sheet, or All sheets to get one array per sheet name.
- Check the report's header line. If the detected header row is wrong, choose the right one from the list, which shows the start of each row.
- Copy the JSON or download it as a
.jsonfile.
What you get
An array of objects, one per data row, with the header row supplying the keys. That is the shape almost every API, seed script and chart library expects:
[
{ "region": "North", "q1": 10, "q2": 12, "updated": "2024-03-15" },
{ "region": "South", "q1": 7, "q2": 9, "updated": "2024-03-16" }
]
Values keep their spreadsheet types. Numbers become JSON numbers, TRUE and FALSE become
booleans, and text stays a string, including text that looks like a number. A code
stored as the text 00721 is not quietly turned into 721.
Choosing All sheets gives an object keyed by sheet name, with each
sheet's rows as an array.
Three things most Excel to JSON converters get wrong
Dates arrive as serial numbers
Excel stores 15 March 2024 as 45366, the number of days since the end of
1899, and only the cell's format marks it as a date. A converter that reads stored
values gives you 45366. Your code then has to convert it, which means
knowing that Excel counts a 29 February 1900 that never existed, and that files from old
Mac versions of Excel count from 1904 instead. Here every date-formatted cell becomes an
ISO 8601 string such as "2024-03-15", which JavaScript's
Date, Python's datetime.fromisoformat and every database read
the same way. Cells with a time become "2024-03-15 12:00:00", time-only
cells become "18:00:00", and 1904-system workbooks are corrected.
The first row is not always the header
Spreadsheets made for people often start with a title, a date line and a blank row
before the table. Converters that always take row 1 give you a key called
"Quarterly report", a column of column_2 keys, and the real
header row as your first object. The header is detected here instead. It is the first
row that contains only text and is filled across most of the table's width, looking
at the first twenty rows with content. Rows above it are skipped and counted. The report
shows which row was chosen and the keys it produced, and the header list lets you pick
another row. Each row in that list shows its first few values, not just a number.
Duplicate headings overwrite each other
Two columns called name cannot both be keys in one JSON object. Most
converters write both and the second silently replaces the first, so half a column
disappears without a message. The second one is renamed to name_2 here and
every rename appears in the report. Blank headings become column_4 and so
on by position.
Empty cells, merges and formulas
| In the sheet | In the JSON |
|---|---|
| Empty cell | Key left out, null or "", as you choose |
| Completely empty row | Skipped and counted |
| Merged area | Value in the first cell, or repeated across the merge |
| Formula | The result saved with the file |
| Formula never calculated | null, with the cell named in the report |
Error such as #N/A | null, with the cell named in the report |
| Number shown rounded, 3.14159 as 3.14 | 3.14159, the stored value |
| Zero-padded number, 721 as 00721 | "00721" |
Leaving empty keys out keeps the file small and is what most APIs expect. Writing
null gives every object the same set of keys, which some typed languages
and database loaders need. The formula row matters for files produced by scripts. They
often contain formulas that were never calculated, and the library underneath this
page reports those as 0. We measured it. Reporting a missing total as
zero is worse than reporting nothing, so those cells become null and are
named.
Numbers are kept at full precision
Excel keeps 15 significant digits, and the JSON uses the same limit. A value that
JavaScript would print as 0.30000000000000004 is written as
0.3, as Excel displays it. Formatting such as currency symbols, percent
signs and thousands separators is not part of the value. A cell showing
12.5% holds 0.125, and that is what you get.
Next steps
Excel to CSV exports the same sheets as CSV files with the same date and precision rules. JSON to CSV and JSON to XML take the result further, and CSV to Excel builds a workbook from a CSV without losing leading zeros. All of them are on the data tools page.