From records to rows
Spreadsheets want a table, and most JSON that people need in Excel already is one: an array where each object is a record. Every object becomes a row and every distinct key becomes a column, in the order the keys first appear. A record that lacks a key simply leaves that cell blank, so uneven data still lines up.
When the array is not at the top level, for example an API response shaped like {"data": {"items": [...]}}, the tool looks for the largest array of objects and uses it. The Array to export menu lists every array it found with its item count; choose another one if the guess is wrong. Picking a single object exports it as one row, and an array of plain values becomes one column called value.
Nested objects and arrays
With Flatten nested objects on, {"address": {"city": "Lagos"}} becomes a column named address.city, however deep the nesting goes. Turn it off to keep each nested object as compact JSON text in a single cell.
Arrays inside a record have three layouts:
- Join values as text writes
["vip", "beta"]asvip, beta. Arrays that hold objects are written as JSON text instead, because joining them would lose their structure. - Keep as JSON text writes every array exactly as JSON, which is the safest choice when the file will be read back by a program.
- Separate linked sheets moves each array of objects to its own sheet, like tables in a database. The main sheet gains an
_idcolumn numbering its rows 1, 2, 3, and every row on the child sheet carries a_parent_idwith the number of the record it came from. Arrays nested deeper get their own sheets, named by path (orders.lines), linked the same way. Use XLOOKUP or a pivot table on those columns to join the sheets again.
Types survive the trip
Numbers are written as numeric cells, so sums and charts work immediately, and true/false become Excel’s TRUE and FALSE. A spreadsheet stores numbers as 64-bit floating point with 15 significant digits, so a value such as a 19-digit snowflake ID would silently change in Excel. Those values are written as text instead and a note lists how many there were — see big integers in JSON for the background.
Strings are always stored as text. Leading zeros in "007" survive, and text that starts with = is never evaluated as a formula, which also protects against formula injection when the JSON came from someone else.
With ISO 8601 dates as Excel dates, strings like 2024-03-11 and 2024-03-11T10:30:00Z become real date cells that sort and filter by date. Excel has no time zones, so a timestamp with an offset is stored in UTC. Anything that is not a valid ISO date stays text.
Formatting the workbook
The header row is bold and frozen so it stays in view while you scroll, and column widths are fitted to their contents; each can be switched off. The sheet name may be up to 31 characters and cannot contain \ / ? * [ ] or :, which are replaced. The file is a standard Office Open XML workbook with compressed parts, so nothing needs repairing when Excel opens it.
Excel’s limits apply: 1,048,576 rows, 16,384 columns and 32,767 characters per cell. The tool stops with an explanation rather than writing a truncated sheet when rows or columns overflow, and it warns about any text longer than a cell can hold. For a quick look without a download, the JSON table viewer shows the same rows in the browser; for a flat text export, use JSON to CSV.
Examples
Customers with a nested address and a tag list
The address object becomes an address.city column and the tags array is joined into one cell; an empty array leaves the cell blank.
[
{ "id": 1, "name": "Aisha Tan", "address": { "city": "Singapore" }, "tags": ["vip", "beta"], "joined": "2024-03-11" },
{ "id": 2, "name": "Ben Okafor", "address": { "city": "Lagos" }, "tags": [], "joined": "2023-11-02" }
]Sheet "Data" (2 rows)
id | name | address.city | tags | joined
1 | Aisha Tan | Singapore | vip, beta | 2024-03-11
2 | Ben Okafor | Lagos | | 2023-11-02Order lines on a separate, linked sheet
With the “Separate linked sheets” layout, each order line goes to an orders.lines sheet whose _parent_id points at the order’s _id.
{
"orders": [
{ "id": "ord_1", "customer": "Aisha", "lines": [{ "sku": "KB-104", "qty": 1 }, { "sku": "MS-220", "qty": 2 }] },
{ "id": "ord_2", "customer": "Ben", "lines": [{ "sku": "HB-1", "qty": 3 }] }
]
}{"arrays": "sheets", "sheetName": "Orders"}Sheet "Orders" (2 rows)
_id | id | customer
1 | ord_1 | Aisha
2 | ord_2 | Ben
Sheet "lines" (3 rows)
_parent_id | sku | qty
1 | KB-104 | 1
1 | MS-220 | 2
2 | HB-1 | 3Nested array with IDs too long for a spreadsheet
The items array is found automatically; the 19-digit IDs are written as text so no digit changes, while likes and ratio stay numeric.
{
"data": {
"items": [
{ "tweet_id": 1790123456789012345, "likes": 42, "ratio": 0.125 },
{ "tweet_id": 1790123456789012399, "likes": 7, "ratio": 1 }
]
}
}Sheet "Data" (2 rows)
tweet_id | likes | ratio
1790123456789012345 | 42 | 0.125
1790123456789012399 | 7 | 1Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
Unexpected end of input | The JSON was cut off, often because it was copied from a log line or a console that truncates long output. | Copy the complete response, or open the saved .json file with the Open button instead of pasting. |
Nothing found at $.data.items | The path typed or chosen does not exist in this document, for example after pasting a different response. | Pick an entry from the Array to export menu, or switch it back to Automatic. |
More than 16,384 columns: Excel cannot hold that many | Flattening a record with a very wide or deeply nested object produced too many distinct keys. | Turn off flattening, choose a narrower array, or keep arrays as JSON text. |
Some numbers are written as text because a spreadsheet keeps only 15 significant digits | A note, not an error: IDs or amounts with more digits than a spreadsheet number can store exactly. | Nothing to do if they are identifiers. If you need to calculate with them, round them in the source data first. |
Frequently asked questions
Is my JSON uploaded to a server?
No. Parsing, layout and the .xlsx file itself are produced by a worker running in this tab, and the download is created locally from those bytes. You can disconnect from the network after the page loads and it keeps working.
Will the file open in Google Sheets and LibreOffice?
Yes. It is a standard .xlsx (Office Open XML) workbook; upload it to Google Drive or open it in LibreOffice Calc or Apple Numbers like any other Excel file.
How do I put a nested array on its own sheet?
Choose “Separate linked sheets” under Arrays inside records. Each array of objects gets its own sheet, and the _id and _parent_id columns connect child rows to their parent record.
Why does a long ID show as text in Excel?
Excel keeps 15 significant digits, so an ID such as 1790123456789012345 would be rounded if stored as a number. Writing it as text keeps every digit; Excel may show a small green triangle that you can ignore.
Can I convert JSON Lines or NDJSON?
Convert it to a JSON array first with the NDJSON to JSON converter, then paste the result here.
How do I go the other way?
Open the workbook with the Excel to JSON tool, which reads .xlsx and .csv files in the browser and gives you an array of objects or arrays.