converters · · Updated

How to Convert JSON to Excel, CSV, XML and YAML (and Back)

By

Converting JSON is rarely the hard part. The hard part is noticing what quietly changed on the way. Each target format has a different idea of what a value is. A spreadsheet has no nesting, CSV has no types, XML can't tell one item from a list of one, and YAML drops comments on the way back to JSON. The examples below use this small customer export, and every output shown is what the converters on this site actually produce.

[
  { "id": 101, "name": "Asha", "plan": "pro", "tags": ["gst", "annual"] },
  { "id": 102, "name": "Ravi", "plan": "free", "referrer": "newsletter" }
]

JSON to CSV or Excel: one row per object

Each object becomes a row and each key becomes a column. Two details decide whether anything goes missing.

Keys that only some objects have. Asha has no referrer and Ravi has no tags. The converter creates a column for every key that appears anywhere in the array, and leaves a blank cell where an object doesn't have it:

id,name,plan,tags,referrer
101,Asha,pro,"[""gst"",""annual""]",
102,Ravi,free,,newsletter

This matters most with API exports, where optional fields often appear only on some records. (Some converters take their column list from the first object only, which silently drops a field like referrer above.)

Nested values. A single cell can't hold a list or an object, so tags is written as JSON text, ["gst","annual"], rather than something lossy like gst,annual. The doubled quotes are standard CSV escaping, and Excel shows the cell as ["gst","annual"]. If you want each nested value in its own column, use the flatten converters described in the nested JSON guide.

Excel's hard limits. A worksheet holds at most 1,048,576 rows, and a cell holds at most 32,767 characters. The JSON ⇄ Excel Converter checks the row count before building the file and tells you if it won't fit. It also stops at about 8 million cells, beyond which building the workbook in a browser tab becomes impractically slow. CSV has neither limit.

CSV back to JSON: which values become numbers

CSV has no types; every cell is text. When converting back, the converter has to decide what's a number:

pincode,phone,active,amount,joined,balance
004102,+919876543210,TRUE,"1,200",2026-04-01,-2.5

becomes

{ "pincode": "004102", "phone": "+919876543210", "active": true, "amount": "1,200", "joined": "2026-04-01", "balance": -2.5 }
  • Plain numbers (-2.5) become JSON numbers, and TRUE/FALSE become booleans.
  • 004102 stays a string. A leading zero is a strong sign the value is a code (a PIN code, an employee ID), not a quantity. Opening the same CSV directly in Excel turns it into 4102.
  • Values with more than 15 digits also stay strings, because a JavaScript number can't hold them exactly. A 20-digit order ID would otherwise come back with its last digits changed.
  • 1,200 and the date stay text, exactly as written. JSON has no date type.

An empty cell becomes an empty string "", not null, so a key that was null in the original JSON comes back as "" after a CSV round trip.

JSON and XML: attributes and the "one item" problem

The XML ⇄ JSON Converter maps XML attributes to keys prefixed with @_, and element text that sits next to attributes to #text:

<price currency="INR">499</price>
→ {"price":{"#text":499,"@_currency":"INR"}}

Going the other way, a JSON array becomes repeated elements with no wrapper around them:

<customer>
  <id>101</id>
  <tags>gst</tags>
  <tags>annual</tags>
</customer>

That creates the classic XML-to-JSON ambiguity. XML has no syntax for "a list with one item", so a customer with a single <tags> element converts back as "tags": "gst", a string, while a customer with two gets an array. Code that reads the result should accept both shapes, for example by wrapping a lone value in an array before looping.

An XML document also needs exactly one root element. If your JSON is a top-level array, or an object with several top-level keys, the converter wraps it in <root>, with array entries as <item> elements, so the output is still valid XML.

JSON and YAML: comments and "clever" values

YAML is the usual format for configuration (Docker Compose, Kubernetes, CI pipelines), and JSON is a subset of it, so the conversion itself is clean. The YAML ⇄ JSON Converter produces two-space-indented YAML:

service: billing-api
replicas: 2
env:
  LOG_LEVEL: info
  REGION: ap-south-1
ports:
  - 8080

Going from YAML to JSON has three traps worth checking in the output:

  • Comments disappear. JSON has no comment syntax, so # owner: payments team is gone after conversion.
  • Unquoted numbers lose formatting. version: 1.10 becomes the number 1.1, and port: 08080 becomes 8080. Quote them (version: "1.10") if they're really labels.
  • `yes` and `no` stay strings. The parser follows YAML 1.2, where only true and false are booleans. Older YAML 1.1 tools read yes, no, on and off as booleans too, which is why the converter quotes a key like 'on' when writing YAML.

Which converter to use

You haveYou needTool
An API response or exportA spreadsheet to filter or shareJSON ⇄ Excel
An API response or exportAn import file for a CRM or databaseJSON ⇄ CSV
A SOAP/partner XML payloadSomething your code can useXML ⇄ JSON
JSON from a scriptA config file you can commitYAML ⇄ JSON

All four run in your browser and accept files up to 200MB. Nothing is uploaded, which matters when the export contains customer records.

Related guides