JSON to CSV: How to Convert JSON Arrays to Spreadsheet Format
JSON is the lingua franca of APIs; CSV is the lingua franca of spreadsheets. Converting between them is a daily task for data engineers, analysts, and developers pulling data from APIs into Excel, Google Sheets, or a SQL import. This guide covers how the conversion works, the edge cases that trip people up, and code examples in JavaScript and Python.
When you need JSON → CSV
- API data into spreadsheets — export REST API responses to Excel or Google Sheets for non-technical stakeholders
- Database exports — MongoDB and Firestore export JSON; downstream tools often expect CSV
- Data science pipelines — pandas, R, and most ML toolkits read CSV natively and have no built-in JSON array reader
- Bulk imports — CRMs, email platforms, and accounting tools almost universally accept CSV for data import
How JSON arrays map to CSV
The conversion only makes sense for a JSON array of objects with consistent keys. Each object becomes a row; the keys become column headers.
// Input JSON
[
{ "name": "Alice", "age": 30, "city": "Mumbai" },
{ "name": "Bob", "age": 25, "city": "Delhi" },
{ "name": "Carol", "age": 35, "city": "Pune" }
]
// Output CSV
name,age,city
Alice,30,Mumbai
Bob,25,Delhi
Carol,35,PuneConvert online (DevBench)
- Open DevBench JSON to CSV
- Paste your JSON array (or upload a .json file)
- Click Convert — headers are auto-detected from the first object's keys
- Copy the CSV output or download as a .csv file
DevBench handles nested objects by flattening them with dot notation (address.city) and arrays by joining values with a semicolon.
Convert in JavaScript
function jsonToCsv(arr) {
if (!arr.length) return "";
const headers = Object.keys(arr[0]);
const escape = (val) => {
const str = String(val ?? "");
return str.includes(",") || str.includes('"') || str.includes("\n")
? `"${str.replace(/"/g, '""')}"`
: str;
};
const rows = arr.map((obj) =>
headers.map((h) => escape(obj[h])).join(",")
);
return [headers.join(","), ...rows].join("\n");
}
const data = [
{ name: "Alice", age: 30, city: "Mumbai" },
{ name: "Bob", age: 25, city: "Delhi" },
];
console.log(jsonToCsv(data));The escape function handles the RFC 4180 quoting rules: wrap in double-quotes if the value contains a comma, double-quote, or newline; double up any embedded double-quotes.
Convert in Python
import json, csv, io
with open("data.json") as f:
data = json.load(f)
output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
print(output.getvalue())Python's csv.DictWriter handles all quoting automatically. Replace io.StringIO() with open("output.csv", "w", newline="") to write directly to a file. The newline="" argument is required on Windows to prevent double line endings.
Edge cases and how to handle them
| Edge case | Example | How to handle |
|---|---|---|
| Missing keys | Object 2 has no city key | Output empty string for the cell; don't skip the column |
| Value contains comma | "New York, NY" | Wrap in double-quotes: "New York, NY" |
| Value contains double-quote | He said "hello" | Escape as "He said ""hello""" |
| Nested object | { "addr": { "city": "Mumbai" } } | Flatten to addr.city column, or JSON-encode the value as a string |
| Array value | { "tags": ["a", "b"] } | Join as a;b or JSON-encode as ["a","b"] |
| Null / undefined | null | Output as empty string (most spreadsheet tools interpret blank as null) |
| Very large numbers | 9007199254740993 | Wrap in double-quotes to prevent Excel from rounding with float precision |
Handling nested JSON: flatten vs stringify
Two strategies for nested objects:
- Flatten — recursively expand
{ "address": { "city": "Mumbai", "pin": "400001" } }into two columns:address.cityandaddress.pin. Good when nested structure is shallow and consistent. - Stringify — JSON-encode the nested value as a string and put it in a single column. Good for deeply nested or variable-structure objects — preserves data without exploding column count.
// Flatten approach
function flatten(obj, prefix = "") {
return Object.entries(obj).reduce((acc, [k, v]) => {
const key = prefix ? `${prefix}.${k}` : k;
if (v && typeof v === "object" && !Array.isArray(v)) {
Object.assign(acc, flatten(v, key));
} else {
acc[key] = v;
}
return acc;
}, {});
}
const flat = data.map(flatten);
console.log(jsonToCsv(flat));For quick conversions without writing code, use the DevBench JSON to CSV converter — paste your array and download the result in one click.
Try it yourself
Use the free browser-based JSON to CSV Converter on DevBench — no signup, runs entirely in your browser.
Open JSON to CSV Converter