JSON zu CSV · Go
JSON zu CSV in Go
Go deckt beide Schritte mit der Standardbibliothek ab: encoding/json parst die Quelle, encoding/csv schreibt das Ergebnis samt korrektem Quoting. Es braucht kein externes Modul. Das folgende Programm liest eine JSON-Datei mit beliebigen Schlüsseln und schreibt eine saubere CSV-Datei zurück.
Ansatz
encoding/json dekodiert in eine Map-Liste, encoding/csv schreibt mit automatischem Quoting.
Code-Beispiel
package main
import (
"encoding/csv"
"encoding/json"
"log"
"os"
"sort"
)
func main() {
roh, err := os.ReadFile("daten.json")
if err != nil {
log.Fatal(err)
}
var daten []map[string]any
if err := json.Unmarshal(roh, &daten); err != nil {
log.Fatal(err)
}
// Go-Maps haben keine feste Reihenfolge, deshalb sortieren wir die Spalten
gesehen := map[string]bool{}
var spalten []string
for _, obj := range daten {
for k := range obj {
if !gesehen[k] {
gesehen[k] = true
spalten = append(spalten, k)
}
}
}
sort.Strings(spalten)
f, err := os.Create("daten.csv")
if err != nil {
log.Fatal(err)
}
defer f.Close()
f.WriteString("\uFEFF") // BOM für Excel
w := csv.NewWriter(f)
w.Comma = ';'
defer w.Flush()
w.Write(spalten)
for _, obj := range daten {
zeile := make([]string, len(spalten))
for i, k := range spalten {
if v, ok := obj[k]; ok && v != nil {
zeile[i] = zelle(v)
}
}
w.Write(zeile)
}
}
func zelle(v any) string {
if s, ok := v.(string); ok {
return s
}
b, _ := json.Marshal(v) // Zahlen, Booleans, Objekte und Arrays als JSON-Text
return string(b)
}
Hinweise
Der csv.Writer von Go setzt Anführungszeichen automatisch, sobald ein Feld das Trennzeichen, ein Anführungszeichen, einen Zeilenumbruch oder ein führendes Leerzeichen enthält, das Escaping ist also abgedeckt. Wichtig ist der Aufruf von Flush, hier per defer abgesichert, sonst bleiben die letzten Zeilen im Puffer und landen nie in der Datei. Maps in Go haben keine feste Reihenfolge, deshalb werden die Spalten im Beispiel alphabetisch sortiert. Wer die Reihenfolge aus dem JSON braucht, liest die Schlüssel mit json.Decoder und Token-Zugriff selbst aus. Die Hilfsfunktion zelle serialisiert alles außer Texten über json.Marshal, sodass Zahlen, Booleans und verschachtelte Objekte als lesbarer Text landen. Für feste Schemata sind typisierte Structs mit json-Tags schneller und sicherer. Das Trennzeichen steht im Feld Comma des Writers. Go schreibt UTF-8, das BOM kommt im Beispiel als erste Zeichenfolge in die Datei.
FAQ
Häufige Fragen
Warum darf ich Flush nicht vergessen?
Der csv.Writer puffert die Ausgabe. Ohne abschließendes Flush, hier per defer w.Flush(), fehlen die letzten Zeilen in der Datei. Das ist ein häufiger Fehler bei der ersten Nutzung.
Warum sind die Spalten sortiert und nicht in der Reihenfolge der JSON-Datei?
Beim Dekodieren in eine Map geht die Reihenfolge der Schlüssel verloren, und Go gibt Maps in zufälliger Reihenfolge aus. Das Beispiel sortiert die Spalten deshalb, damit die Ausgabe bei jedem Lauf gleich ist.
Sie wollen nicht selbst programmieren? Der JSON-CSV-Konverter wandelt Ihre Daten direkt im Browser um, ohne Upload und ohne Installation.