JSON to CSV
Convert a JSON array into CSV, flattening nested objects into dotted column headers.
JSON to CSV tool
What this tool does
CSV is flat and JSON is not, so the interesting part of this conversion is deciding what
happens to the nesting. This tool flattens each record into dotted column names —
contact.email, settings.alerts.slack — and builds the header from
the union of every key it finds, so a record that is missing a field gets an empty cell in the
right column instead of shifting the rest of the row.
You pick the delimiter, decide whether arrays become numbered columns or a single joined cell, and untick any column you do not want before downloading. Quoting follows RFC 4180: a field is wrapped in double quotes when it contains the delimiter, a quote, a line break or padding whitespace, and an embedded quote is doubled.
Common uses
- Handing an API export to someone who works in Excel, Numbers or Google Sheets.
-
Preparing a file for
COPY FROMin PostgreSQL orLOAD DATA INFILEin MySQL, both of which want one flat table. - Turning a paginated list response into a table you can sort and pivot.
- Feeding a BI tool or a CSV-only import form that has no JSON option.
- Diffing two exports as text, where fixed column order makes the change obvious.
A short example
Two records with different shapes:
[
{ "id": 1042, "contact": { "email": "ada@example.com" }, "seats": 3 },
{ "id": 1043, "contact": { "email": "grace@example.com" }, "trial_ends": "2026-05-01" }
] produce one table whose header is the union of both:
id,contact.email,seats,trial_ends
1042,ada@example.com,3,
1043,grace@example.com,,2026-05-01 Choosing a delimiter, and the spreadsheet trap
A comma is only the default. Excel reads and writes CSV using the list separator of the operating system's locale, which is a semicolon across most of continental Europe — the same file opens as one column per row on a German machine and correctly on a US one. If the recipient is on a European locale, pick Semicolon; if you do not know, tab is the safest choice because no locale reassigns it.
Tick Excel BOM when the data contains non-ASCII characters: Excel assumes the
system's legacy code page, so Müller arrives as Müller without the
three-byte UTF-8 marker. pandas.read_csv and psql are happier
without it.
Worth knowing
A cell whose text begins with =, +, - or
@ is treated as a formula by Excel and Sheets. That is CSV injection: a value
like =HYPERLINK(…) stored by a user in your database becomes executable content
in a colleague's spreadsheet. This tool writes values verbatim rather than mangling your
data, so prefix such fields with an apostrophe yourself when the source is untrusted. Note
also that CSV has no types: true, 42 and the string
"42" all land as bare text, which is why the round trip back has to guess.
Frequently asked questions
Why does Excel turn my IDs into 1.05E+18 and drop leading zeros?
Excel types every cell as it opens a .csv, holds numbers as doubles with 15 significant digits and discards the rest, so a 19-digit order ID is rounded and 00123 arrives as 123. Re-formatting the column afterwards cannot restore the digits. Import through Data > From Text/CSV and mark those columns as Text, or open the file somewhere that does not guess.
A field containing a line break splits into two rows. Is the export wrong?
No — RFC 4180 §2 permits CR LF inside a quoted field, and such values are quoted here. The reader is at fault: anything that breaks the input into lines before it handles quoting, including a quick split on newlines, cut or awk, will tear the record apart. PostgreSQL’s COPY … CSV and Python’s csv module both cope.
How many rows and columns can a spreadsheet actually take?
Excel stops at 1,048,576 rows and 16,384 columns, and a wide flattened export can hit the column ceiling long before the row one, because the header is the union of every key that appears. Google Sheets caps a document at 10 million cells across all its tabs. Beyond those, load the file into a database or read it with pandas.