Menu

Search toolsChangelog

to move to openDescribe the problem, not the tool

Convert a CSV file to JSON

Converts a CSV export into JSON, in your browser, with the quoting rules a spreadsheet actually uses. Quoted commas, escaped quotes and line breaks inside a cell all survive, and the file is never sent anywhere.

Anything a spreadsheet exports. It is read in this tab and never sent anywhere.

Objects are keyed by the header row. Arrays keep the original column order.

Turn this off if the file starts straight into data.

Rows converted
Not counting the header row, if there is one.
Columns
Separator used

How it works

What this does

Turns a spreadsheet export into JSON without it leaving your computer. Most online converters upload the file to a server, which means a customer list, a payroll export or a set of medical records has just been sent to somebody else’s machine. This one reads the file in the tab you are already looking at.

The method

The interesting part is the quoting, and it is the reason this is a parser rather than a split(','). All four of the following are ordinary in a real export, and all four break a naive split:

Name,Role
"Lovelace, Ada",Mathematician
"She said ""hello""",Quoted
"12 High Street
London",Multi-line

The parser walks the text one character at a time and keeps one piece of state: whether it is currently inside quotes. A separator seen inside quotes is part of the value. A line break inside quotes is part of the value. Two quotes in a row inside a quoted field are one literal quote. Everything else follows from that.

The separator itself is detected by counting candidates in the first complete record — outside quotes, for the same reason — because a semicolon-separated European export split on commas produces twice as many columns as it has, every one of them wrong, with no error to tell you.

Before you read on

A CSV export is 500 lines of text. Can it hold fewer than 500 records?

  • It is what most code assumes, and it is why so much of that code breaks on a real export.

  • Yes. An address across two lines is one field on one record spanning two lines of the file.

  • That too, but it is the smaller problem, and it does not need quotes to happen.

Yes. A quoted field may contain a line break, and that break is part of the value rather than the end of a record — an address written across two lines is the everyday case. It may also contain the separator, and two quotes in a row inside it stand for one literal quote. All three are ordinary in a real export, and all three are fatal to a split on commas, which is the entire reason this is a parser rather than one line of string handling.

The parser keeps one piece of state
  1. inside = false

    Whether the walk is currently between quotes. That single flag is the whole state machine.

  2. on a quote: inside = !inside

    Unless the next character is also a quote, in which case the pair is one literal quote in the value and the flag does not move.

  3. on a separator: inside ? keep it : end the field

    A comma inside quotes is part of the value. Lovelace, Ada is one field, not two.

  4. on a line break: inside ? keep it : end the record

    Which is how a 500-line file holds fewer than 500 records.

A worked example

Four rows of a savings schedule:

Year,Paid in,Interest,Balance
1,3000,152.34,3152.34
2,6000,468.91,6468.91
3,9000,955.02,9955.02
4,12000,1620.77,13620.77

converts to four rows and four columns, the first of which is:

{ "Year": "1", "Paid in": "3000", "Interest": "152.34", "Balance": "3152.34" }

Those exact figures are asserted in calc.test.ts, so this page and the code cannot drift apart about what the tool does.

It also leaves the rows exactly as it found them. Use the CSV column selector first when the JSON should contain only a named subset or a different column order. To sort lines or drop duplicates first, do that before converting rather than after — JSON is the harder shape to tidy. For the reverse direction, JSON to CSV has to decide which keys form the complete header and what nested objects mean before it can write the first row.

How it is done

  1. Read the chosen file in this tab and decode it as UTF-8, discarding the byte-order mark Excel writes at the front.
  2. Work out the column separator by counting commas, semicolons, tabs and pipes in the first complete record, outside any quotes — or use the one you picked.
  3. Walk the text one character at a time, tracking whether the parser is inside a quoted field, so a separator or a line break inside quotes stays part of the cell.
  4. Treat two consecutive quotes inside a quoted field as one literal quote, which is how RFC 4180 escapes them.
  5. Take the first row as keys when you say there is a header, padding short rows and naming blank or duplicated headers positionally so no column is silently lost.
  6. Serialise to JSON with two-space indentation and offer it as a download. Nothing is uploaded at any point.

What it assumes

  • Every value comes out as a string. CSV has no types, and guessing that "007" is the number 7 loses information that cannot be recovered.
  • The file is read into memory in one piece, which is why it is capped at 20 MB, 500,000 rows and 5,000 columns. Larger exports belong in a spreadsheet or a database rather than a browser tab.
  • The text is decoded as UTF-8. A file saved in a legacy Windows code page will convert, but accented characters may come through as replacement characters.

Common questions

Is my CSV uploaded anywhere?

No. The file is read in this browser tab and converted by a worker running on your own machine. There is no server to send it to, and the automated test for this page fails if any request leaves this site while a file is loaded.

Why are all my numbers strings?

Because CSV has no types, and guessing costs more than it saves. A leading zero in a product code, a phone number, a version like 1.10 — every one of those is destroyed by a converter that decides it looks numeric. Convert the columns you know about on the other side, where you know what they mean.

My file uses semicolons. Will that work?

Yes. Much of Europe exports semicolon-separated files, because the comma is the decimal point there. The separator is detected from the first complete record, and you can override it under "More options" if the guess is ever wrong.

What happens to a cell that contains a comma or a line break?

It survives. A spreadsheet wraps such a cell in quotes, and the parser tracks whether it is inside a quoted field, so the comma stays part of the value instead of splitting the row. Doubled quotes inside a quoted field become one literal quote, per RFC 4180.

Sources