Skip to content
SimpleTools24

How to Convert Nested JSON to Excel Without Losing Data

By SimpleTools24Published 4 min read

To convert nested JSON to Excel, you have to decide how each level of nesting maps onto a flat grid. Nested objects are usually flattened into extra columns with dotted names, like address.city. Nested arrays have more options: join simple values into one cell, spread them across numbered columns, keep them as JSON text, or, for arrays of objects, move them to a separate sheet linked back to the parent row. The right choice depends on what you'll do with the spreadsheet.

Why Nested JSON Is a Problem for Spreadsheets

A spreadsheet is two-dimensional: rows and columns. JSON is a tree. Consider one order:

json
{
  "orderId": "A-1001",
  "customer": { "name": "Sara Malik", "address": { "city": "Karachi", "country": "PK" } },
  "tags": ["gift", "express"],
  "items": [
    { "sku": "MUG-01", "qty": 2, "price": 8.5 },
    { "sku": "TEA-04", "qty": 1, "price": 12 }
  ]
}

customer is an object nested two levels deep, tags is an array of strings, and items is an array of objects. Each needs a different treatment. A naive converter produces cells containing [object Object] or silently drops the arrays.

Nested Objects: Flatten Into Columns

Objects are the easy part. Each nested key becomes its own column, with the path joined by dots:

Flattened columns for the nested customer object
orderIdcustomer.namecustomer.address.citycustomer.address.country
A-1001Sara MalikKarachiPK

This keeps one row per order and makes every value filterable. The only downside is long column names, which you can rename after flattening.

The alternative is to keep customer as JSON text in one cell. That's useful when the nested data is irrelevant to your analysis but must be preserved.

Arrays of Simple Values: Four Options

For tags: ["gift", "express"]:

Ways to represent an array of values in Excel
OptionResultGood for
Join into one cellgift, expressReading, filtering with "contains"
Numbered columnstags.1 = gift, tags.2 = expressShort arrays of predictable length
Keep as JSON["gift","express"]Round-tripping data back to JSON
Separate sheetOne row per tag, with a link to the orderCounting and pivoting tags

Joining is usually the friendliest. Numbered columns get unwieldy if one record has 50 tags and the rest have two.

Arrays of Objects: The One-to-Many Problem

items is the hard case. One order has many items, so there are three common approaches:

Put orders on one sheet and items on another, with a column linking each item to its order's row:

Items sheet linked to the orders sheet
parent_rowskuqtyprice
1MUG-0128.5
1TEA-04112

This mirrors how a database would store the data. You can pivot items, sum quantities and still trace each one back to its order with a lookup.

2. One Row Per Item (Explode)

Repeat the order's fields on every item row. It's easy to filter but duplicates data, and summing an order-level field such as shipping cost will double-count it.

3. Keep as JSON Text

Store the whole items array in one cell. Nothing is lost, but you can't analyse it in Excel without further work.

Doing It With a Converter

The JSON to Excel converter offers each of these approaches as a setting. Flatten objects into dotted columns or keep them as JSON; join arrays, expand them into numbered columns, keep them as JSON, or move arrays of objects to their own sheet with a parent_row column. You can then drop columns you don't need in the mapping table, and the preview updates as you change settings, so you can see the shape before downloading. It runs in your browser, so the data stays on your device.

Doing It in Python

pandas handles both object flattening and one-to-many expansion:

python
import json
import pandas as pd

orders = json.load(open("orders.json", encoding="utf-8"))

# One row per order, nested objects flattened
orders_df = pd.json_normalize(orders).drop(columns=["items"])

# One row per item, with the order ID carried along
items_df = pd.json_normalize(orders, record_path="items", meta=["orderId"])

with pd.ExcelWriter("orders.xlsx") as xl:
    orders_df.to_excel(xl, sheet_name="orders", index=False)
    items_df.to_excel(xl, sheet_name="items", index=False)

Here the link is the orderId column rather than a row number, which is often better when the data has a natural key.

Common Mistakes to Avoid

  • Losing arrays silently. Check that every top-level key appears somewhere in the output.
  • Exploding without noticing. If your row count jumped from 1,000 orders to 3,400 rows, you've exploded an array.
  • Inconsistent records. If some records have address as an object and others as a string, flattening produces mixed columns. Look at a few odd records before converting.
  • Very deep nesting. Ten levels of dotted names are unreadable. Consider which levels you actually need.

If you're not sure the JSON is valid in the first place, how to convert JSON to Excel covers validation and type handling, and exporting API JSON deals with wrapper objects around the records.

Frequently Asked Questions

Why do I see [object Object] in my spreadsheet?

The converter turned a nested object into text using JavaScript's default string conversion. Use a tool that flattens objects or keeps them as JSON.

Can Excel's Power Query flatten nested JSON?

Yes, by expanding record and list columns step by step. It works well but takes a few clicks per level.

How do I convert JSON with different keys in each record?

Use the union of all keys as columns. Records missing a key get empty cells.

Can I convert the Excel file back to the same nested JSON?

Only if you kept enough structure, such as linked sheets or JSON text cells. Flattening with joined values is hard to reverse exactly.

Summary

Flatten objects into columns, choose deliberately for arrays, and use a linked second sheet for arrays of objects. Check row counts and columns afterwards to make sure nothing was dropped or duplicated.