Loading your tools...
Loading your tools...
Learn how to parse JSON arrays and convert them into downloadable CSV files in React. Master header extraction, row mapping, and CSV escaping.
JSON is a tree. CSV is a flat sheet. Converting between them requires "flattening" an array of objects types into rows and columns. This guide shows you how to do it entirely in the browser—no server required.
We assume the user provides an Array of Objects. Each object represents a row. Each key represents a column.
[
{ "id": 1, "name": "John", "role": "Admin" },
{ "id": 2, "name": "Sarah", "role": "User" }
]
We need to know what the columns are. Usually, we just grab the keys from the first object in the array.
const data = JSON.parse(jsonString);
const headers = Object.keys(data[0]); // ["id", "name", "role"]
const csvHeaderRow = headers.join(","); // "id,name,role"
What if a user's name is "Doe, John"?
If you naively join with commas, you break the CSV structure.
1,Doe, John,Admin -> This looks like 4 columns!
The Fix:
Wrap any field containing commas, quotes, or newlines in Double Quotes.
And if the field contains a double quote, escape it by doubling it ("").
const escapeCSV = (str) => {
if (str.includes(",") || str.includes("\n") || str.includes('"')) {
return `"${str.replace(/"/g, '""')}"`; // Escape quotes with double quotes
}
return str;
}
JsonToCsv.jsx) 💻Here is the production-ready component that handles parsing, escaping, and downloading.
'use client';
import { useState } from 'react';
import { Download, FileJson } from 'lucide-react';
export default function JsonToCsv() {
const [json, setJson] = useState('');
const downloadCSV = () => {
try {
const data = JSON.parse(json);
if (!Array.isArray(data) || data.length === 0) {
alert("Please enter a non-empty JSON Array");
return;
}
// 1. Get Headers
const headers = Object.keys(data[0]);
// 2. Build Rows
const rows = data.map(obj =>
headers.map(header => {
const val = String(obj[header] ?? '');
// Safety: Escape special characters
return val.includes(',') || val.includes('"') || val.includes('\n')
? `"${val.replace(/"/g, '""')}"`
: val;
}).join(",")
);
// 3. Combine
const csvContent = [headers.join(","), ...rows].join("\n");
// 4. Trigger Download
const blob = new Blob([csvContent], { type: 'text/csv' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'export.csv';
a.click();
URL.revokeObjectURL(url);
} catch (e) {
alert("Invalid JSON! Check your syntax.");
}
};
return (
<div className="max-w-2xl mx-auto p-6 bg-white border rounded-xl shadow-sm">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-bold flex items-center gap-2">
<FileJson className="text-orange-500"/> JSON to CSV
</h2>
</div>
<label className="block text-sm font-medium text-gray-700 mb-2">Paste JSON Array</label>
<textarea
className="w-full h-64 p-4 font-mono text-xs border rounded-lg focus:ring-2 focus:ring-orange-500 outline-none"
placeholder='[ {"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"} ]'
onChange={e => setJson(e.target.value)}
value={json}
/>
<button
onClick={downloadCSV}
disabled={!json}
className="mt-4 w-full flex justify-center items-center gap-2 py-3 bg-slate-900 text-white font-medium rounded-lg hover:bg-slate-800 disabled:opacity-50 disabled:cursor-not-allowed transition"
>
<Download size={18} /> Convert & Download CSV
</button>
</div>
);
}
Developer Tools & Resource Experts
FastTools is dedicated to curating high-quality content and resources that empower developers. With nearly 5 years of hands-on development experience, our team rigorously evaluates every tool and API we recommend, ensuring you get only the most reliable and effective solutions for your projects.