Guide

How to convert JSON to CSV

JSON is a tree and CSV is a table, so this conversion is a genuine change of shape rather than a change of notation. It works cleanly when the JSON is already table-shaped, an array of objects with consistent keys, and needs decisions from you when it is not.

The usual destination is a spreadsheet, a database import, or a colleague who works in Excel. Knowing in advance which parts of your data cannot survive the trip is the difference between a clean import and one that quietly drops a field.

Open the JSON to CSV

Use this when


  • An API returned an array of records and someone needs it in a spreadsheet
  • You are preparing data for a bulk database import that expects CSV
  • A reporting tool accepts CSV and nothing else
  • You want to sort or pivot API data without writing code

What shape the input needs to be


The conversion expects an array of objects, where each object becomes one row and each key becomes one column. That is the shape most list endpoints already return.

A single object rather than an array produces one row. Scalar entries in an array use a column named value, rather than an unnamed column. Review mixed arrays carefully: a scalar value column and an object property called value can share the same output column.

When the array you want is nested inside a wrapper object, as in a response shaped like an object containing a data array alongside pagination fields, extract that array first. Converting the wrapper produces one row describing the wrapper, which is rarely useful.

How nesting is flattened


A nested object becomes several columns whose names are joined with a dot: an address object containing a city key becomes a column named address.city. This makes the table readable, but the CSV-to-JSON converter treats that dotted name as a literal key rather than automatically rebuilding the original object.

The number of columns is determined by every key that appears anywhere in the input, not by the first record. A record missing a key gets an empty cell rather than a shifted row, which is the part that matters: a shifted row corrupts every column after it and is not obvious on inspection.

Deeply nested data produces a very wide table. Three levels of nesting across several branches can easily reach fifty columns, at which point CSV is arguably the wrong target and the conversion is telling you something about the data rather than failing.

Arrays are the lossy case


An array inside a record has no natural representation in a single cell. This converter writes the array as JSON text inside its cell, preserving a recognizable representation but not turning it into a relational set of rows or columns. The CSV-to-JSON converter reads that cell as text; it does not parse it back into an array automatically.

There is no joined-list or indexed-array mode in this converter. To produce one row per array element, transform the source into records first and decide how parent identifiers should be repeated. That is a schema decision, not an automatic formatting option.

The cell contains JSON text with CSV quoting around it when necessary. Use a CSV parser before interpreting that cell; counting commas by eye mixes array separators with CSV delimiters. Keep the original JSON when the complete typed structure matters.

Quoting and delimiters


A field containing a comma, a double quote or a line break must be quoted, and a double quote inside a quoted field is escaped by doubling it. This is handled automatically, and it is the single most common source of corrupted CSV when done by hand.

Semicolon-delimited files exist because of locale: in regions where the comma is the decimal separator, Excel writes and expects semicolons. If a colleague opens your file and sees everything in one column, the delimiter is the first thing to change.

Tab-separated output avoids the quoting question almost entirely, since tabs rarely appear inside values, and pastes directly into a spreadsheet. It is worth preferring when the destination is a paste rather than a file.

What happens to types


CSV has no types. Every value becomes text, and whatever reads the file guesses what that text meant. This is why a CSV round trip is not lossless even when no cell is empty: the number 007 comes back as 7, or as the string "007", depending entirely on the reader.

The values worth watching are leading zeros in identifiers and postcodes, values that look like dates, and booleans. Spreadsheets are aggressive about reinterpreting all three, and the change happens on open rather than in the file, which makes it easy to blame the wrong tool.

A null and an empty string both become an empty cell, and there is no way to tell them apart afterwards. If that distinction matters in your data, CSV cannot carry it.

Common problems


Each of these is something that actually happens, with the cause rather than a generic suggestion to check your input.

Everything lands in a single spreadsheet column

Cause
The delimiter does not match what the spreadsheet expects for its locale.
Fix
Switch the output delimiter to semicolon, or use the tab-separated output and paste rather than open.

Rows are shifted so values sit under the wrong headers

Cause
Almost always an unquoted value containing the delimiter, if the file was assembled by hand or by string concatenation.
Fix
Regenerate the file with proper quoting rather than repairing it. A single corrupted row is a symptom, not the extent of the problem.

Leading zeros have disappeared from IDs or postcodes

Cause
The spreadsheet interpreted the column as numeric on open. The file itself is usually correct.
Fix
Import rather than open, and set that column to text during the import. Check the raw file first to confirm the zeros are actually there.

Far more columns than expected

Cause
Flattening expanded many nested object properties, and columns are collected across all records. Arrays are JSON text in cells, not one column per element.
Fix
Select a smaller record shape before conversion, or turn flattening off to keep nested objects as JSON text in cells.

Only one row, describing the response envelope

Cause
The array is nested inside a wrapper object alongside pagination fields.
Fix
Extract the inner array and convert that. The wrapper is one object, so it correctly produces one row.

Questions


Will nested JSON survive the conversion?
Nested objects can be flattened into dotted column names and arrays become JSON text inside cells. That is a useful export shape, not an automatic round trip: converting the CSV back leaves dotted names as flat keys and array text as strings. Keep the original JSON when the exact tree matters.
Why are some cells empty?
Because that key was absent from that record. Columns are derived from every key found anywhere in the input, so a record missing one gets an empty cell. That is deliberate: the alternative is a shifted row, which corrupts every column after it.
Can I convert the result back to JSON?
Yes, but not as an automatic reconstruction of the original tree. Dotted column names stay literal keys, JSON text in cells stays text, and CSV has no types. The reverse conversion must infer numbers and booleans, while null, empty string and missing values can already be indistinguishable. Keep the original JSON for exact recovery.
Which delimiter should I choose?
Comma unless you have a reason. Semicolon for colleagues whose Excel uses a comma as the decimal separator. Tab when you are going to paste into a spreadsheet rather than open a file, since it avoids quoting questions almost entirely.