Converter CSV em JSON
CSV to JSON parses a spreadsheet export into an array of records in your browser. It reads RFC 4180 properly — quoted fields containing commas, newlines and escaped quotes all survive — infers scalar types, and rebuilds nested objects and arrays from dotted or bracketed column names.
A interface desta ferramenta está em inglês.
O guia abaixo está disponível apenas em inglês.
How does CSV to JSON work?
The naive implementation of this conversion is one line — line.split(",") — and it is wrong for a large fraction of real files. A CSV field may be quoted, and a quoted field may contain the delimiter, a literal newline, and doubled quotes standing for a single one. Splitting on commas turns "Hopper, G." into two fields and shifts every column after it by one, which corrupts the record rather than failing on it.
So the parser here is an explicit state machine over the character stream, tracking whether it is inside a quoted region, exactly as RFC 4180 describes. It also handles the things the RFC does not mention but real files contain: a UTF-8 byte-order mark before the first column name, CRLF and bare LF line endings mixed in one file, a trailing newline that would otherwise produce a phantom empty record, and a stray quote in the middle of an unquoted field, which Excel writes and which is taken literally rather than treated as fatal.
Delimiter detection counts candidates in the header line — comma, semicolon, tab, pipe — but only outside quoted regions. A file whose header is name,description with semicolons inside the quoted descriptions would otherwise be split on the wrong character, which is the kind of bug that looks like corrupt data rather than a wrong setting.
Type inference is deliberately conservative. A cell matching the JSON number grammar becomes a number, true/false become booleans, and null becomes null. Everything else stays a string — including 007, because the grammar forbids leading zeros and a part number must not be renumbered, and including integers beyond 253, because converting those drops digits outright.
Finally, column names that look like paths are treated as paths: customer.name rebuilds a nested object, tags[0] rebuilds an array. Because those names come from the file, they are untrusted input being used to index an object — a column called a.__proto__.polluted is a prototype-pollution payload, and it is refused rather than followed.
CSV in
id,user.name,tags[0],tags[1] 1,Ada,a,b 2,"Hopper, G.",c,
JSON out
[
{ "id": 1, "user": { "name": "Ada" }, "tags": ["a", "b"] },
{ "id": 2, "user": { "name": "Hopper, G." }, "tags": ["c"] }
]What types do CSV columns become in JSON?
id arrives as a number and joined stays a string: a date is not a JSON type, and turning it into one would silently change the value.
CSV
id,name,joined 1,Ada,1815-12-10 2,Grace,1906-12-09
JSON
[
{
"id": 1,
"name": "Ada",
"joined": "1815-12-10"
},
{
"id": 2,
"name": "Grace",
"joined": "1906-12-09"
}
]Header cells become keys. A column whose values all look numeric is typed as numbers — which is why an ID column with leading zeros should be quoted in the source file.
What options and edge cases does CSV to JSON support?
| Parameter | Type | Default | Behaviour & edge cases |
|---|---|---|---|
| Delimiter | auto | , ; tab | | auto | Auto counts candidates in the header line, ignoring anything inside quotes. Override it when a file's header is unrepresentative of its body. |
| Header row | boolean | true | Row one supplies the keys. With it off, keys are column1, column2 and so on. A blank header cell also falls back to a positional name so the record is never missing a key. |
| Infer types | boolean | true | Applies the JSON number grammar plus true/false/null. "007", "+1", "0x10" and "1,5" stay strings. Turn it off when every column must remain text — an ID column full of digits is the usual reason. |
| Expand paths | boolean | true | Rebuilds nesting from customer.name and tags[0]. With it off you get a flat object whose keys are the literal column names, which is what you want when a column is genuinely called "user.name". |
| Empty cells | omit | keep | omit | CSV cannot distinguish an absent field from an empty string. Omitting is the better default because the column set is a union: a record that simply lacks tags[1] is written as an empty cell exactly like one whose tags[1] is "". |
| Quoted fields | RFC 4180 | — | A quoted field may contain the delimiter, CR, LF and doubled quotes. An unterminated quote is a hard error with a line and column, because silently truncating would produce plausible, wrong output. |
| Ragged rows | warning | — | A row with the wrong number of fields is kept, not dropped: missing fields are omitted and extra ones ignored, with a warning saying how many rows were affected. |
| Duplicate columns | warning | rightmost wins | Matches spreadsheet import behaviour. Warned about explicitly, because silently discarding a column the user can see in the file is worse than saying so. |
Frequently asked questions
Why does my file convert wrongly when a field contains a comma?
It should not — this parser tracks quoting properly, so "Hopper, G." stays one field. If a converter splits it into two, it is splitting on commas without regard to quotes, which is the single most common CSV bug. If it happens here, check whether the field is actually quoted in the source file: an unquoted comma is genuinely ambiguous and no parser can recover it.
Why do the leading zeros in my ID column keep disappearing?
Not here — "007" stays a string, because the JSON number grammar forbids leading zeros and that rule is exactly what protects part numbers, postcodes and account references. If zeros are disappearing, it happened in the spreadsheet before export: Excel strips them on import unless the column is set to Text. If you want every column kept as text, turn off Infer types.
What does customer.name in a header do?
It rebuilds a nested object: {"customer":{"name":"…"}}. Bracketed names like tags[0] rebuild arrays. This is the inverse of what JSON to CSV writes, so a document survives a round trip through a spreadsheet. If your columns are genuinely named with dots and you want them literal, turn off Expand paths.
Can it handle a file with newlines inside a field?
Yes, provided the field is quoted, which RFC 4180 requires. An address or a comment spanning several lines is common in exports and is handled correctly. What cannot be handled is an unquoted newline mid-record, because nothing distinguishes it from the end of the row.
How large a file can I convert?
Up to 8 MB. The conversion runs on the main thread, and past that ceiling it is declined with a message rather than attempted, because attempting it locks the tab. Nothing is uploaded at any size — the file is read by your browser and never sent anywhere.
Is my spreadsheet data sent to a server?
No. Parsing happens in the page you already have open. That matters for this tool specifically, because a CSV export is usually real records — customers, orders, payroll — and sending one to an unknown endpoint to reformat it is a disclosure you cannot undo. Open the Network panel and watch while you paste.