JSON ist ein Baum. CSV ist ein Rechteck. Wer das eine ins andere umwandelt, muss entscheiden, wie der Baum flachgedrückt wird. Jeder Konverter trifft diese Entscheidungen für dich, meist ohne zu sagen, wie er sie getroffen hat. Deshalb kann dieselbe Datei in drei Online-Konvertern drei verschiedene Tabellen ergeben.
Wenn du die drei Entscheidungen kennst, kannst du das Tool oder die Einstellungen wählen, die sie so treffen, wie du es willst.
Die schnelle Antwort
- Ein flaches Array aus Objekten (
[{"id":1,"name":"Ada"}, …]): Jeder Konverter funktioniert. Nimmjq, Python, DuckDB, Excel oder eine App. - Verschachtelte Objekte (
"address": {"city": "Leeds"}): In Spalten mit Punktnotation umwandeln, alsoaddress.city. Pythonsjson_normalizemacht das in einer Zeile. - Arrays innerhalb jedes Datensatzes (
"tags": ["a","b"]): Du musst dich zwischen einer Spalte pro Element, einer Zeile pro Element oder einer Zelle mit verbundener Liste entscheiden. Es gibt keine richtige Antwort, nur die, die zu dem passt, was du damit vorhast. - Die Datensätze stehen nicht ganz oben: Such zuerst das Array (meist
data,itemsoderresults) und konvertiere dann dieses.
Entscheidung 1: Welches Array wird zu den Zeilen?
Eine CSV-Datei braucht eine Liste gleichartiger Dinge, eines pro Zeile. Fast kein echtes JSON beginnt mit so einer Liste. Eine API-Antwort sieht so aus:
{
"status": "ok",
"page": 1,
"data": {
"items": [
{ "id": 1, "name": "Ada", "address": { "city": "Leeds" }, "tags": ["admin"] },
{ "id": 2, "name": "Lin", "address": { "city": "Hue" }, "tags": [] }
]
}
}
Die Zeilen sind data.items. Ein Konverter, den du auf das Wurzelobjekt
ansetzt, sieht nur ein Objekt und liefert eine einzige Zeile mit status,
page und einer Spalte voller maskiertem JSON. Das ist die häufigste Klage
„der Konverter ist kaputt“, und es ist ein Pfadproblem, kein Konverterproblem.
Entscheidung 2: Was passiert mit verschachtelten Objekten?
address ist ein Objekt innerhalb jedes Datensatzes. Die übliche und für die
meisten Zwecke richtige Lösung ist, es in Spaltennamen mit Punkten
aufzulösen:
| id | name | address.city |
|---|---|---|
| 1 | Ada | Leeds |
| 2 | Lin | Hue |
Die Alternative, das ganze Objekt als JSON-String in eine Zelle zu schreiben, behält zwar alles, aber du bekommst eine Spalte, die du weder sortieren noch filtern kannst.
Entscheidung 3: Was passiert mit Arrays innerhalb eines Datensatzes?
tags ist eine Liste, und eine Liste passt nicht in eine Zelle. Es gibt drei
Möglichkeiten:
| Ansatz | Ergebnis | Gut für |
|---|---|---|
| Indexspalten | tags[0], tags[1], … | Kurze Listen mit bekanntem Maximum |
| In Zeilen aufteilen | Eine Zeile pro Tag, übrige Spalten wiederholt | Zählen oder Filtern nach Tag |
| In einer Zelle verbinden | admin;editor | Lesen, nicht Auswerten |
Das Aufteilen ändert die Zeilenzahl: Eine Person mit drei Tags sind jetzt drei Zeilen. Das stimmt für „Wie viele Personen haben welchen Tag?“ und ist falsch für „Wie viele Personen gibt es?“. Entscheide, für welche Frage die CSV-Datei gedacht ist, bevor du dich festlegst.
Was sonst noch verloren geht
Auch ein perfektes Flachdrücken verliert Dinge, weil CSV sie nicht ausdrücken kann:
- Typen.
"42"und42werden beide zu42.truewird zum Texttrue. - Null oder leer.
null,""und ein fehlender Schlüssel werden alle zu einer leeren Zelle. - Spalten aus lückenhaften Datensätzen. Hat nur ein Datensatz von 10.000
ein Feld
coupon, lässt ein Konverter, der die Kopfzeile aus den Schlüsseln des ersten Datensatzes baut, es weg. Gute Konverter bilden die Vereinigung der Schlüssel aller Datensätze.
Mit jq
Für ein flaches Array auf oberster Ebene:
jq -r '(.[0] | keys_unsorted) as $k | $k, (.[] | [.[$k[]]]) | @csv' in.json > out.csv
Das baut die Kopfzeile aus dem ersten Datensatz und lässt daher jeden
Schlüssel weg, der dem ersten fehlt. Das ist das oben genannte Problem mit
lückenhaften Datensätzen. Liegt das Array tiefer, ersetzt du das erste .
durch den Pfad, etwa .data.items. Bei verschachtelten Daten kann jq es auch,
aber der Ausdruck wird unleserlich; greif dann zu Python.
Mit Python
pandas.json_normalize trifft alle drei Entscheidungen in einem Aufruf und
bildet die Vereinigung der Schlüssel:
import json, pandas as pd
data = json.load(open("in.json"))
df = pd.json_normalize(data["data"]["items"], sep=".")
df.to_csv("out.csv", index=False)
Verschachtelte Objekte werden zu address.city. Listen bleiben als Listen in
einer Zelle; um sie in Zeilen aufzuteilen, füge vor dem Speichern
df = df.explode("tags") ein.
Mit DuckDB
Bei großen Dateien liest DuckDB JSON direkt und schreibt CSV, ohne alles in den Speicher zu laden:
duckdb -c "COPY (SELECT * FROM read_json_auto('in.json')) TO 'out.csv'"
Für ein flaches Array ist das der schnellste Weg. Verschachtelte Objekte landen
in DuckDBs eigener Struct-Schreibweise in einer einzigen Spalte. Löse sie also
im SELECT auf oder nimm Python für verschachtelte Daten.
Mit Excel
Daten → Daten abrufen → Aus Datei → Aus JSON öffnet Power Query. Klicke auf In Tabelle, dann auf das Erweitern-Symbol im Spaltenkopf (zwei Pfeile), um Datensätze und Listen Ebene für Ebene aufzuklappen. Das geht per Mausklick, und du siehst jede Entscheidung, während du sie triffst. Danach als CSV speichern. Achte auf die Typumwandlungen beim Export: Excel verändert CSV-Daten, wenn du es nicht anders einstellst.
Online-Konverter
Sie funktionieren, und bei öffentlichen Daten sind sie in Ordnung. Zwei Warnungen. Die meisten verstecken die drei Entscheidungen, also vergleiche Zeilen- und Spaltenzahl der Ausgabe mit deiner Erwartung. Und JSON aus einer API enthält oft Tokens, E-Mail-Adressen oder Kundendaten, also nimm lieber einen Konverter, der im Browser läuft, ohne etwas hochzuladen.
Auf iPhone und iPad
Smart Json wandelt JSON im sogenannten Datensatzmodus in CSV um: Ein Array aus
Objekten wird zu den Zeilen, verschachtelte Werte werden zu Spalten mit Punkten
(address.city, tags[0]), und die Kopfzeile ist die Vereinigung der
Schlüssel aller Datensätze. Die App findet das erste Array aus Objekten selbst
und lässt dich ein anderes wählen oder einen JSONPath wie $.data.items
eintippen. Das Trennzeichen ist einstellbar, und enthält ein Dokument kein
Array aus Objekten, sagt die App das, statt einen nutzlosen Zwei-Spalten-Dump
zu liefern.

Die Vorschau ist kostenlos, du siehst also genau, wie die CSV-Datei aussehen wird. Das Ergebnis zu kopieren oder zu sichern ist Pro.
Zeigt JSON als CSV in der Vorschau, mit verschachtelten Werten als Spalten mit Punkten. Du wählst das Datensatz-Array per JSONPath und erfährst klar, was CSV nicht abbilden kann.
Was es kannLiegt die Datei erst einmal als CSV vor, ist sie auf dem Handy zu öffnen ein eigenes kleines Problem; dieser Leitfaden behandelt es.
Das Ergebnis prüfen
Egal welches Tool du nutzt, drei Prüfungen:
- Zeilenzahl. Entspricht sie der Zahl der Datensätze im Array (oder ist sie höher, wenn du eine Liste absichtlich aufgeteilt hast)?
- Spaltenzahl. Hat es ein Feld, das nur in einigen Datensätzen vorkommt, in die Kopfzeile geschafft?
- Ein verschachtelter Wert. Nimm einen Datensatz mit verschachteltem Objekt und prüfe, ob sein Wert in der richtigen Spalte mit Punkt gelandet ist.