Skip to content
Terug naar blog
Tutorials

CSV naar JSON omzetten: methoden, valkuilen & codevoorbeelden

Zet CSV om naar JSON (en terug) met Python, JavaScript en CLI-tools. Behandelt coderingsproblemen, typeconversie en het streamen van grote bestanden.

12 min leestijd

CSV naar JSON omzetten: methoden, valkuilen & aanbevolen aanpak

Je operationeel team stuurt je een CSV-export. Je API verwacht JSON. Je opent het bestand, staart naar 10.000 rijen kommagescheiden waarden, en vraagt je af: wat is de snelste manier om CSV naar JSON om te zetten zonder gegevens te verliezen?

Deze handleiding behandelt vier conversiemethoden (browser-tool, JavaScript, Python, CLI), de omgekeerde richting (JSON naar CSV), vijf valkuilen die je data stilletjes beschadigen, en hoe je bestanden verwerkt die te groot zijn voor het geheugen.

CSV vs JSON: wanneer gebruik je wat?

Voordat je omzet, helpt het te begrijpen waar elk formaat goed in is.

DimensieCSVJSON
StructuurPlatte tabel (rijen en kolommen)Geneste hiërarchie (objecten, arrays)
GegevenstypenAlles is een stringstring, number, boolean, null
LeesbaarheidSpreadsheet-vriendelijkOntwikkelaar-vriendelijk
Primair gebruikData-export/import, rapporten, ETLAPI’s, configuratiebestanden, NoSQL-opslag
BestandsgrootteKleiner (geen herhaalde sleutelnamen)Groter (sleutelnamen herhalen per record)
SchemaImpliciet (kopregel)Expliciet (of gebruik JSON Schema)

Vuistregel: Gebruik CSV als je data tabellair is en de afnemer een spreadsheet of datapipeline is. Gebruik JSON als je data hiërarchie heeft of de afnemer een API is. Je kunt je JSON-uitvoer altijd valideren met een JSON Formatter om structurele problemen vroeg op te sporen.

Als je project gebruikmaakt van soepelere JSON-formaten zoals JSON5 of JSONC voor configuratie, zie onze handleiding voor JSON5 en JSONC formatteren voor syntaxverschillen en tooling.

4 manieren om CSV naar JSON om te zetten

Methode 1 — Tool die in de browser draait

Voor eenmalige conversies is een tool die in de browser draait de snelste aanpak. Plak je CSV in een online converter, krijg JSON terug en valideer het resultaat vervolgens in een JSON Formatter om te bevestigen dat de structuur klopt.

Het voordeel: je data verlaat nooit je browser. Geen uploads, geen serververwerking, geen privacyproblemen. Dit is bepalend voor situaties waarin je werkt met interne data, API-sleutels in exports, of alles wat je liever niet naar een externe server stuurt.

Geschikt voor: kleine bestanden (onder 10 MB), snelle eenmalige conversies en niet-technische teamleden.

Methode 2 — JavaScript / Node.js

Browser (vanilla JS):

function csvToJson(csv) {
  const lines = csv.trim().split('\n');
  const headers = lines[0].split(',').map(h => h.trim());

  return lines.slice(1).map(line => {
    const values = line.split(',');
    return headers.reduce((obj, header, i) => {
      obj[header] = values[i]?.trim() ?? '';
      return obj;
    }, {});
  });
}

const csv = `name,age,city
Alice,30,New York
Bob,25,London`;

console.log(JSON.stringify(csvToJson(csv), null, 2));

Dit werkt voor eenvoudige CSV zonder velden met aanhalingstekens. Voor productiegebruik met komma’s in waarden, regeleinden in velden of strings met aanhalingstekens gebruik je een volwaardige verwerker.

Node.js (csv-parser + streams):

import { createReadStream } from 'fs';
import { parse } from 'csv-parse';

const records = [];

createReadStream('data.csv')
  .pipe(parse({ columns: true, trim: true, skip_empty_lines: true }))
  .on('data', (row) => records.push(row))
  .on('end', () => {
    console.log(JSON.stringify(records, null, 2));
  });

De optie columns: true gebruikt de eerste rij als sleutels. De optie trim verwijdert witruimte uit waarden. Dit verwerkt velden met aanhalingstekens, ge-escapete komma’s en meerdere regels correct.

Methode 3 — Python

Standaardbibliotheek (geen extra afhankelijkheden):

import csv
import json

with open('data.csv', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    rows = list(reader)

with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(rows, f, indent=2, ensure_ascii=False)

csv.DictReader koppelt elke rij aan een dictionary met de kopregel als sleutels. De vlag ensure_ascii=False behoudt Unicode-tekens (Chinees, Japans, tekens met accenten) in plaats van ze te escapen naar \uXXXX.

Pandas (one-liner voor data scientists):

import pandas as pd

df = pd.read_csv('data.csv')
df.to_json('data.json', orient='records', indent=2, force_ascii=False)

Wanneer gebruik je wat:

  • csv + json: Lichte scripts, Lambda-functies, containers waarvoor je minimale afhankelijkheden wilt.
  • pandas: Als je de data ook wilt opschonen, filteren of transformeren voor de conversie. De overhead van het importeren van pandas is de moeite waard als je meer doet dan alleen formaatconversie.

Methode 4 — CLI-tools

Voor shell-scripts en automatiseringspipelines:

csvkit:

# Install: pip install csvkit
csvjson data.csv > data.json

Miller (mlr):

# Install: brew install miller (macOS) or apt install miller (Ubuntu)
mlr --csv --json cat data.csv > data.json

Pipe met jq voor filteren:

# Convert and filter in one pipeline
csvjson data.csv | jq '[.[] | select(.age | tonumber > 25)]'

Miller is bijzonder krachtig omdat het CSV, JSON, TSV en andere formaten ingebouwd ondersteunt. Je kunt data transformeren tijdens de conversie:

# Convert CSV to JSON, rename a field, add a computed field
mlr --csv --json rename name,fullName then put '$age_group = ($age > 30) ? "senior" : "junior"' data.csv

JSON naar CSV: de omgekeerde richting

JSON naar CSV omzetten kent uitdagingen die in de andere richting niet bestaan.

Geneste objecten platslaan

CSV is inherent plat. Als je JSON geneste objecten heeft, heb je een strategie nodig om ze plat te slaan:

{
  "name": "Alice",
  "address": {
    "city": "New York",
    "zip": "10001"
  }
}

Wordt:

nameaddress.cityaddress.zip
AliceNew York10001

De puntnotatieconventie (address.city) is de meest gebruikte aanpak. In Python:

import pandas as pd

data = [
    {"name": "Alice", "address": {"city": "New York", "zip": "10001"}},
    {"name": "Bob", "address": {"city": "London", "zip": "EC1A"}}
]

df = pd.json_normalize(data)
df.to_csv('output.csv', index=False)
# Columns: name, address.city, address.zip

Arrays verwerken

Arrayvelden vereisen een keuze:

StrategieVoorbeeldinvoerCSV-uitvoerGeschikt voor
Samenvoegen als string["admin","editor"]admin;editorEenvoudige lijsten, her-importeerbaar
Uitbreiden naar kolommen["admin","editor"]role_0: admin, role_1: editorArrays met vaste lengte
Uitbreiden naar rijen["admin","editor"]Twee rijen, één per rolRelationele analyse

Kies op basis van je afnemer. Als de CSV naar een database gaat, is uitbreiden naar rijen meestal de beste keuze.

Verlies van type-informatie

CSV heeft geen typesysteem. Als je JSON naar CSV omzet:

  • true wordt de string "true" — is het een boolean of een string?
  • null wordt een lege cel — niet te onderscheiden van een lege string ""
  • 42 wordt "42" — is het een getal of een string?

Als round-trip nauwkeurigheid belangrijk is (CSV → verwerking → JSON), documenteer je typeconventies in een kopcommentaar of een bijbehorend schemabestand.

5 veelvoorkomende valkuilen en hoe je ze vermijdt

Deze problemen beschadigen data zonder dat je het merkt. De meeste tutorials slaan ze over. Kom er niet pas in productie achter.

1. Coderingsvalkuilen

Het probleem: Je opent een CSV van een collega en ziet é in plaats van é, of 锟斤拷 in plaats van Chinese tekens.

Waarom dit gebeurt: Het bestand is opgeslagen in één codering (Windows-1252, GBK, Shift_JIS) maar je verwerker gaat uit van UTF-8. Excel op Windows slaat CSV vaak op als Windows-1252 of voegt een UTF-8 BOM toe (Byte Order Mark — de onzichtbare \xEF\xBB\xBF aan het begin van het bestand).

De oplossing:

# Detect encoding first
import chardet

with open('data.csv', 'rb') as f:
    result = chardet.detect(f.read(10000))
    print(result)  # {'encoding': 'Windows-1252', 'confidence': 0.73}

# Then read with the correct encoding
with open('data.csv', encoding=result['encoding']) as f:
    reader = csv.DictReader(f)
    # ...

In Node.js verwijder je de BOM expliciet:

import { readFileSync } from 'fs';

let content = readFileSync('data.csv', 'utf-8');
// Strip UTF-8 BOM if present
if (content.charCodeAt(0) === 0xFEFF) {
  content = content.slice(1);
}

2. Verwarring over het scheidingsteken

Het probleem: Je verwerker produceert één grote kolom in plaats van meerdere velden.

Waarom dit gebeurt: In veel Europese regio’s (Frankrijk, Duitsland, Spanje) gebruikt Excel puntkomma’s (;) als CSV-scheidingsteken, omdat komma’s worden gebruikt als decimaalteken (bijv. 3,14 in plaats van 3.14). Tab-gescheiden bestanden (.tsv) voegen nog een variant toe.

De oplossing: Detecteer het scheidingsteken automatisch door de eerste paar regels in te lezen:

import csv

with open('data.csv') as f:
    sample = f.read(8192)
    dialect = csv.Sniffer().sniff(sample, delimiters=',;\t|')
    f.seek(0)
    reader = csv.DictReader(f, dialect=dialect)

3. Voorloopnullen verdwijnen

Het probleem: Postcode 00501 wordt 501. Productcode 007 wordt 7.

Waarom dit gebeurt: De verwerker (of Excel) interpreteert het veld als een getal en verwijdert de voorloopnullen. Dit is bijzonder gevaarlijk bij postcodes, telefoonnummers en ID-codes.

De oplossing: Forceer string-typering. In pandas:

df = pd.read_csv('data.csv', dtype={'zip': str, 'product_code': str})

In JavaScript controleer je of de originele string verschilt van de numerieke verwerking:

function preserveLeadingZeros(value) {
  if (/^0\d+$/.test(value)) return value; // Keep as string
  const num = Number(value);
  return isNaN(num) ? value : num;
}

4. Precisieverlies bij grote getallen

Het probleem: ID 9007199254740993 wordt 9007199254740992 in je JSON.

Waarom dit gebeurt: JavaScript Number is een 64-bit float (IEEE 754). Gehele getallen boven Number.MAX_SAFE_INTEGER (2^53 - 1 = 9007199254740991) verliezen precisie. Dit treft database-ID’s, Snowflake ID’s en Twitter/X-post-ID’s.

De oplossing: Bewaar grote getallen als strings in JSON, of gebruik BigInt in je verwerkingscode:

// Parse with string preservation for large numbers
function safeParseNumber(value) {
  const num = Number(value);
  if (Number.isInteger(num) && !Number.isSafeInteger(num)) {
    return value; // Keep as string to preserve precision
  }
  return isNaN(num) ? value : num;
}

5. Onduidelijkheid bij lege waarden

Het probleem: Je CSV heeft lege cellen. Na de conversie kun je niet meer zien of de oorspronkelijke waarde een lege string "" was, null, of gewoon ontbrak.

Waarom dit gebeurt: CSV heeft geen manier om onderscheid te maken tussen deze drie toestanden. Een leeg veld tussen twee komma’s (Alice,,30) kan elk van de drie betekenen.

De oplossing: Definieer een conventie en pas die consistent toe:

def parse_value(value):
    if value == '':
        return None        # or '' — pick one convention
    if value == 'NULL' or value == 'null':
        return None
    return value

Als je data schildwachtwaarden gebruikt zoals NULL, N/A of -, documenteer ze en verwerk ze expliciet.

Grote bestanden streamen

Als je CSV meer dan 100 MB beslaat, is het volledig in het geheugen laden geen optie. Gebruik streaming.

Node.js (stream pipeline):

import { createReadStream, createWriteStream } from 'fs';
import { parse } from 'csv-parse';
import { Transform } from 'stream';
import { pipeline } from 'stream/promises';

let first = true;
const toJsonArray = new Transform({
  objectMode: true,
  transform(record, encoding, callback) {
    const prefix = first ? '[\n' : ',\n';
    first = false;
    callback(null, prefix + JSON.stringify(record));
  },
  flush(callback) {
    callback(null, '\n]');
  }
});

await pipeline(
  createReadStream('large.csv'),
  parse({ columns: true, trim: true }),
  toJsonArray,
  createWriteStream('large.json')
);

Python (generator):

import csv
import json

def csv_rows(path):
    with open(path, encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for row in reader:
            yield row

# Stream to JSON Lines format (one JSON object per line)
with open('large.jsonl', 'w', encoding='utf-8') as out:
    for row in csv_rows('large.csv'):
        out.write(json.dumps(row, ensure_ascii=False) + '\n')

Voor zeer grote bestanden overweeg je JSON Lines (.jsonl) in plaats van één grote JSON-array. Elke regel is een zelfstandig JSON-object, wat betekent dat je het uitvoerbestand ook regel voor regel kunt verwerken — je hoeft niet het hele bestand in te laden.

Veelgestelde vragen

Wat is het verschil tussen CSV en JSON?

CSV (Comma-Separated Values) slaat data op als een platte tabel waarbij elke waarde een string is. JSON (JavaScript Object Notation) slaat gestructureerde data op met geneste objecten, arrays en getypeerde waarden (strings, getallen, booleans, null). CSV is kleiner en spreadsheet-vriendelijk; JSON is expressiever en API-vriendelijk.

Hoe zet ik CSV om naar JSON in JavaScript?

Gebruik het pakket csv-parse in Node.js: lees het bestand met createReadStream, stuur het door parse({ columns: true }) en verzamel de records. Voor browsergebruik lees je het bestand met FileReader, splits je op regeleinden en zet je rijen om naar objecten met de kopregel als sleutels.

Hoe zet ik CSV om naar JSON in Python?

Gebruik csv.DictReader uit de standaardbibliotheek om rijen als dictionaries in te lezen, dan json.dump() om ze als JSON-array te schrijven. Voor datamanipulatie voor de conversie is pandas.read_csv() gevolgd door df.to_json(orient='records') een one-liner alternatief.

Kan geneste JSON worden omgezet naar CSV?

Ja, maar je hebt een strategie nodig om te platslaan. De meest gebruikte aanpak gebruikt puntnotatie: een veld als address.city wordt een kolomkoptekst. In Python verwerkt pandas.json_normalize() dit automatisch. Arrays vereisen extra keuzes — samenvoegen als strings, uitbreiden naar kolommen of uitbreiden naar rijen.

Waarom bevat mijn CSV onleesbare tekens na de conversie?

Coderings-mismatch. Het bestand is waarschijnlijk opgeslagen in Windows-1252 of GBK, maar je verwerker gaat uit van UTF-8. Gebruik een detectiebibliotheek zoals chardet (Python) om de codering te achterhalen en geef die vervolgens expliciet op bij het lezen. Controleer ook op een UTF-8 BOM die sommige tools automatisch toevoegen.

Hoe verwerk ik een CSV-bestand van meer dan 100 MB?

Gebruik streaming in plaats van het hele bestand in het geheugen te laden. In Node.js stuur je het door csv-parse met streams. In Python itereer je met csv.DictReader via een generator. Overweeg JSON Lines (.jsonl) als uitvoerformaat in plaats van één JSON-array — dat maakt verdere verwerking eenvoudiger.

Hoe kan ik controleren of mijn geconverteerde JSON geldig is?

Plak de uitvoer in een online JSON Formatter om syntaxis, structuur en nesting te controleren. Voor geautomatiseerde validatie gebruik je JSON.parse() in JavaScript of json.loads() in Python — beide geven duidelijke fouten bij ongeldige invoer. Voor schemavalidatie definieer je een JSON Schema en valideer je programmatisch.

Belangrijkste punten

  1. Kies de juiste methode voor je situatie: browser-tools voor snelle eenmalige conversies, code voor automatisering, CLI voor pipelines.
  2. Let op coderingsproblemen — geef de codering altijd expliciet op in plaats van te vertrouwen op standaardinstellingen.
  3. Behoud typen bewust — voorloopnullen, grote gehele getallen en null-waarden vereisen allemaal expliciete verwerking.
  4. Stream grote bestanden in plaats van ze in het geheugen te laden. Overweeg JSON Lines-formaat voor zeer grote datasets.
  5. Valideer je uitvoer — stuur geconverteerde JSON door een JSON Formatter om structurele problemen op te sporen voordat ze in productie gaan.

Gerelateerde artikelen

Alle artikelen bekijken