Which JSON converts to a spreadsheet, and which does not
A spreadsheet is a grid: rows and columns, one value per cell. JSON is a tree. The conversion only works cleanly when your JSON already happens to be grid-shaped — an array of flat objects with the same keys:
[
{ "id": 1, "name": "Ada", "role": "engineer" },
{ "id": 2, "name": "Grace", "role": "admiral" }
]That becomes three columns (id, name, role) and two rows. Everything below is about what to do when your JSON does not look like that.
The API-response case: your table is nested one level down
This is the most common reason a conversion produces a single useless row. API responses usually wrap the data in an envelope:
{
"status": "ok",
"results": [ <- this is the table
{ "id": 1, "name": "Ada" },
{ "id": 2, "name": "Grace" }
]
}The top-level value here is one object, so it converts to one row with columns status and results. What you want is the inner array. Copy that array — from its opening bracket to its closing one — and convert that instead.
Nested objects
A cell holds one value, so { "city": "London" } cannot go in a cell as a structure. The usual answer is to flatten: turn each leaf into its own column with a dotted name.
{ "id": 1, "address": { "city": "London", "zip": "EC1" } }
flattened:
{ "id": 1, "address.city": "London", "address.zip": "EC1" }Do that before converting and the result is a clean two-dimensional table. If the nesting is the point of the document — a configuration file, a deeply branched tree — a spreadsheet is the wrong destination and you will lose the structure. Convert to XML or YAML instead, both of which keep the hierarchy intact.
Arrays inside a row
A field like "tags": ["a", "b", "c"]" has no natural single-cell representation. Three options, in decreasing order of how well they survive a round trip: join the values into one delimited string, split them into numbered columns (tags_1, tags_2), or split the row into several rows, one per tag. Which is right depends on what you plan to do in Excel afterwards — filtering wants the third, reading wants the first.
Types, and what survives
- Numbers stay numbers, so they sort and sum correctly in Excel.
- Booleans become
TRUE/FALSE. - null becomes an empty cell — which is indistinguishable from a missing key once it is in a spreadsheet. If that difference matters to you, it cannot survive the conversion.
- Dates are the one to watch. JSON has no date type, so they arrive as strings and are written as text rather than being auto-converted. This is deliberate: guessing between
03/04/2026as March and as April silently corrupts data, and a wrong date is worse than an unformatted one. Format the column once in Excel. - Very large integers lose precision above roughly 9×1015, because both JSON parsers and Excel store numbers as 64-bit floats. IDs of that size should be strings in the source JSON.
Column order and uneven objects
Columns are the union of every key across every object, so nothing is silently dropped when your records disagree about which fields they have — a row missing a key simply gets an empty cell. Order follows first appearance, which means the first object in the array effectively sets the layout. If you want a particular column order, put a complete record first.
Why .xlsx and not .xls
The output is .xlsx. The older .xls binary format caps out at 65,536 rows and 256 columns and has been superseded since 2007; Excel, LibreOffice, Numbers and Google Sheets all open .xlsx. If something downstream genuinely requires .xls, open the result and re-save it from Excel — but check the row count first.