Turn a JSON file into an Excel workbook
This page converts JSON to XLSX, the format Excel has saved to since 2007. Upload a .json file and you get back a workbook with your records laid out as rows and columns, ready to sort and add up. If you searched for "JSON to Excel", this is the conversion you want, because an XLSX file opens in Excel, Google Sheets and Numbers with no import step.
Apps and APIs hand over data as JSON because a program can read it quickly. A person can't, once the records start nesting inside each other, and a spreadsheet won't open the file as a table on its own. The converter reads your JSON file, gives each nested field a column of its own, and keeps the type of every value, so numbers arrive as numbers you can total and text arrives as text.
How to convert JSON to XLSX
- Upload your JSON file - Drag it into the box at the top of this page, or browse for it. You can add up to 5 files at once.
- Check the output - XLSX is already picked on this page, so there's nothing to change.
- Download your file - Save the .xlsx file when it's ready and open it in your spreadsheet app.
Your file is uploaded and converted on our servers, so there's nothing to install and no account to make. Our security page explains what happens to your file after that.
How your JSON becomes rows and columns
A spreadsheet is a grid and JSON often isn't, so the converter uses a fixed set of rules to decide where each value lands. Knowing them tells you what the workbook will look like before you open it.
- When the file is a list of records, every record is a row and every field name is a column heading.
- A record nested inside another gets its field names joined with a dot.
{"address": {"city": "Lisbon"}}gives a column calledaddress.city, so the city gets a column rather than a lump of JSON in one cell. - A list of plain values, like tags, stays in one cell, with a semicolon and a space between the items.
- If a record holds a list of records, say an order with several items, the first such list is spread out: one row per item, with the order's own fields repeated on each row. A second list of records in the same record is kept as JSON text in a single cell, because one grid can only be split along one list.
- A file holding a single record gives a one-row table. A record with exactly one list in it, like
{"page":1,"items":[{"id":1},{"id":2}]}, uses the list's items as the rows and repeats the other fields on each one, giving the columnspageandid.
Columns are placed in the order the converter first meets each name. When two different paths would produce the same heading, the second one gets _2 on the end instead of overwriting the first.
A real example from our tests
On 13 November 2026 we ran a small file we wrote ourselves through our live converter. It covers the awkward cases: a nested address, a list of tags, an empty list, accented names and a ZIP code that starts with a zero.
[
{"id": 1, "name": "Ana", "address": {"city": "Lisbon"}, "tags": ["a", "b"], "zip": "01100"},
{"id": 2, "name": "Zoë", "address": {"city": "Zürich"}, "tags": [], "zip": "8001"}
]
The .xlsx came back about 13 seconds after we started the upload. An XLSX is a binary file, so we can't print it here the way we would a CSV. We unpacked it and read the sheet data instead, and this is what it held:
| id | name | address.city | tags | zip |
|---|---|---|---|---|
| 1 | Ana | Lisbon | a; b | 01100 |
| 2 | Zoë | Zürich | 8001 |
The id cells are stored as numbers, and the other four columns as text, both ZIP codes included. The empty tags list left an empty cell, and Zoë and Zürich kept their accents. You can download the JSON we uploaded and the XLSX it produced to check them yourself.
Before launch, we also ran bigger files on our test server. A 19 MB JSON file with 122,589 records converted to XLSX in about 18 seconds, upload included.
What's inside the XLSX file
The workbook has one sheet, named Data. The first row holds the column headings in bold and is frozen, so the headings stay put while you scroll down a long table. Below it, each cell keeps the type it had in the JSON:
- JSON numbers are stored as spreadsheet numbers, so you can sum, sort and chart them straight away.
- JSON strings are stored as text, even when they look like numbers. This is the main difference from converting to CSV. A CSV has no types, so when Excel opens one it guesses, and a ZIP code like 01100 turns into 1100. In the XLSX the cell is marked as text, and the zero stays.
- Whole numbers of 15 or more digits are stored as text too. Excel keeps 15 significant digits for a number, so a 16-digit card or account number stored as a number would end in a digit that isn't yours.
- Text that begins with = is saved as text, not as a formula, so a value like
=HYPERLINK(...)hidden in your data can't run when the file opens. - One cell holds at most 32,767 characters, which is Excel's limit, so longer text is cut at that point.
We checked all of this by reading the sheet data inside the file. We haven't opened it in Excel itself yet, so we can't describe how Excel shows it on screen. If the file has to go to Excel 2003 or older, use JSON to XLS instead. To turn a workbook back into JSON, use XLSX to JSON.
Limits, and files that won't convert
- Each JSON file can be up to 20 MB. The upload box accepts bigger files, but the converter stops anything over 20 MB and asks you to split it.
- The table can have up to 1,000,000 rows, 16,384 columns and 5,000,000 cells. A file that would need more is refused with a message saying which limit it hit.
- Data nested more than 64 levels deep is refused.
- JSON Lines, with one record on each line, isn't supported, because the file has to hold a single JSON value.
- The file must be UTF-8 text. UTF-16 and UTF-32 files with a BOM work too.
- NaN and Infinity aren't allowed in JSON, so a file that uses them is refused.
- A list inside another list is written into one cell as JSON text, not split up.
If your JSON has a mistake, like a comma after the last item, the error message tells you what's wrong and which line it's on, so you can fix it and upload the file again.