How to Convert JSON to CSV: Flattening Nested Objects, Handling Arrays, and RFC 4180 Compliance
Learn how to transform complex, nested JSON objects into clean CSV spreadsheets: flattening hierarchies, handling arrays, and adhering to RFC 4180 escaping rules.
The Challenge: Hierarchical Trees vs Flat Tables
JSON represents multidimensional data trees with arbitrary nesting and variable keys, whereas CSV (Comma-Separated Values) represents two-dimensional relational tables with fixed columns. Converting JSON to CSV requires two crucial transformations: flattening deep object properties into dot-notated column headers and serializing array values deterministically.
RFC 4180 CSV Escaping Rules
To prevent Excel and automated parsers from corrupting data, every CSV generator must adhere strictly to RFC 4180:
- Quote Fields with Delimiters: If a field contains a comma (
,), semicolon, or newline (\n), the entire field value must be enclosed in double quotes ("field, value"). - Escape Embedded Quotes: If a field contains a double-quote character (
"), the quote must be escaped by prefixing it with another double quote (""). For example,He said "Hello"becomes"He said ""Hello""". - CRLF Line Endings: RFC 4180 specifies
\r\nas the standard row delimiter.
Flattening Nested JSON Keys (Dot Notation)
Deeply nested properties are flattened using dot-notation headers:
// Nested Input JSON:
[
{
"id": 101,
"user": {
"name": "Sarah Chen",
"address": { "city": "Seattle", "state": "WA" }
}
}
]
// Flattened CSV Table:
// id,user.name,user.address.city,user.address.state
// 101,"Sarah Chen","Seattle","WA"Handling Arrays in CSV Columns
Arrays of primitive strings (such as user tags ["developer", "admin"]) are serialized into a single column using pipe or semicolon delimiters (e.g. "developer|admin"). For arrays of nested objects, developers can choose between JSON-stringifying the cell or generating one CSV row per child entry.
Complete TypeScript & Python Converter Recipes
// RFC 4180 Compliant JSON to CSV Converter in TypeScript
export function jsonToCsv(items: Record<string, any>[]): string {
if (!items.length) return '';
// 1. Extract all unique header keys across all items
const headers = Array.from(
new Set(items.flatMap(item => Object.keys(item)))
);
// 2. Escape cell according to RFC 4180
const escapeCell = (val: any): string => {
if (val === null || val === undefined) return '';
const str = typeof val === 'object' ? JSON.stringify(val) : String(val);
if (/[",\n\r]/.test(str)) {
return `"${str.replace(/"/g, '""')}"`;
}
return str;
};
// 3. Assemble CSV string
const headerRow = headers.map(escapeCell).join(',');
const rows = items.map(item =>
headers.map(header => escapeCell(item[header])).join(',')
);
return [headerRow, ...rows].join('\r\n');
}Code Formatter & Converter Suite
Validate, format, minify, and convert JSON, SQL, YAML, XML, and code dialects directly on your local machine.
Frequently Asked Questions
How do I prevent Excel from showing numbers with leading zeros as truncated integers (e.g. "01234" becoming 1234)?
In CSV files opened directly in Excel, text fields starting with zero can be formatted as formula strings (e.g. `="01234"`) or exported with UTF-8 BOM encoding (`\uFEFF`) to preserve text typing.
What is the maximum file size for CSV exports in browser environments?
Browser memory handles CSV generation up to several hundred megabytes smoothly using `Blob` URLs and streaming chunk downloads with Web Workers.
Conclusion
You have to flatten the structure before converting it to CSV, usually by joining keys with dots (e.g., `address.city` and `address.zip`) to form unique columns in your table.
Related Articles
How to Convert CSV to JSON: Delimiter Detection, Type Ingestion, and Streaming Large Datasets
A comprehensive guide to converting CSV files into JSON: RFC 4180 parsing, automated type casting (numbers, booleans, dates), and streaming multi-gigabyte files.
Developer ToolsHow to Validate JSON: Syntax Diagnostics, JSON Schema (Draft 2020-12), and Runtime Validation
Learn how to validate JSON data: debugging syntax errors, defining JSON Schema (Draft 2020-12) contracts, and validating runtime payloads with Ajv, Zod, and Pydantic.
Developer ToolsJSON Minification: Performance Gains, Gzip Interaction, and Streaming Parsers
Understand how JSON minification reduces bandwidth and compute costs, how minification interacts with gzip/Brotli compression, and how to stream minify large payloads.