Guide de conversion CSV en JSON : méthodes, pièges et bonnes pratiques
Votre équipe opérations vous envoie un export CSV. Votre API attend du JSON. Vous ouvrez le fichier, contemplez 10 000 lignes de valeurs séparées par des virgules, et vous vous demandez : quel est le moyen le plus rapide de convertir du CSV en JSON sans perdre de données ?
Ce guide couvre quatre méthodes de conversion (outils navigateur, JavaScript, Python, CLI), la direction inverse (JSON vers CSV), cinq pièges qui corrompent silencieusement vos données, et comment traiter des fichiers trop volumineux pour tenir en mémoire.
CSV vs JSON : quand utiliser lequel
Avant de convertir, il est utile de comprendre les atouts de chaque format.
| Dimension | CSV | JSON |
|---|---|---|
| Structure | Table plate (lignes et colonnes) | Hiérarchie imbriquée (objets, tableaux) |
| Types de données | Tout est une chaîne de caractères | string, number, boolean, null |
| Lisibilité | Adapté aux tableurs | Adapté aux développeurs |
| Usage principal | Export/import de données, rapports, ETL | API, fichiers de configuration, stockage NoSQL |
| Taille du fichier | Plus petit (pas de noms de clés répétés) | Plus grand (les noms de clés se répètent par enregistrement) |
| Schéma | Implicite (ligne d’en-tête) | Explicite (ou utilisation de JSON Schema) |
Règle générale : Utilisez CSV lorsque vos données sont tabulaires et que le consommateur est un tableur ou un pipeline de données. Utilisez JSON lorsque vos données ont une hiérarchie ou que votre consommateur est une API. Vous pouvez toujours valider votre sortie JSON avec un JSON Formatter pour détecter les problèmes structurels en amont.
Si votre projet utilise des formats JSON assouplis comme JSON5 ou JSONC pour la configuration, consultez notre guide de formatage JSON5 et JSONC pour les différences de syntaxe et les outils disponibles.
4 façons de convertir du CSV en JSON
Méthode 1 — Outil dans le navigateur
Pour les conversions ponctuelles, un outil dans le navigateur est la voie la plus rapide. Collez votre CSV dans un convertisseur en ligne, obtenez du JSON en sortie, puis validez le résultat dans un JSON Formatter pour confirmer que la structure est correcte.
L’avantage : vos données ne quittent jamais votre navigateur. Aucun téléchargement, aucun traitement serveur, aucun problème de confidentialité. C’est important lorsque vous travaillez avec des données internes, des clés API intégrées dans des exports, ou tout ce que vous préféreriez ne pas envoyer à un serveur tiers.
Idéal pour : les petits fichiers (moins de 10 Mo), les conversions rapides ponctuelles et les membres non techniques de l’équipe.
Méthode 2 — JavaScript / Node.js
Navigateur (JS vanilla) :
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));
Cela fonctionne pour du CSV simple sans champs entre guillemets. Pour une utilisation en production avec des virgules dans les valeurs, des retours à la ligne dans les champs ou des chaînes entre guillemets, utilisez un parseur adapté.
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));
});
L’option columns: true utilise la première ligne comme clés. L’option trim supprime les espaces autour des valeurs. Cette approche gère correctement les champs entre guillemets, les virgules échappées et les valeurs multi-lignes.
Méthode 3 — Python
Bibliothèque standard (zéro dépendance) :
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 associe chaque ligne à un dictionnaire en utilisant la ligne d’en-tête comme clés. Le paramètre ensure_ascii=False préserve les caractères Unicode (chinois, japonais, caractères accentués) au lieu de les échapper en \uXXXX.
Pandas (une seule ligne pour les data scientists) :
import pandas as pd
df = pd.read_csv('data.csv')
df.to_json('data.json', orient='records', indent=2, force_ascii=False)
Quand utiliser lequel :
- csv + json : Scripts légers, fonctions Lambda, conteneurs où l’on veut minimiser les dépendances.
- pandas : Lorsque vous devez également nettoyer, filtrer ou transformer les données avant la conversion. Le coût d’import de pandas est justifié dès que vous faites plus qu’une simple conversion de format.
Méthode 4 — Outils CLI
Pour les scripts shell et les pipelines d’automatisation :
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
Pipeline avec jq pour le filtrage :
# Convert and filter in one pipeline
csvjson data.csv | jq '[.[] | select(.age | tonumber > 25)]'
Miller est particulièrement puissant car il gère nativement CSV, JSON, TSV et d’autres formats. Vous pouvez transformer les données pendant la conversion :
# 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 vers CSV : gérer la direction inverse
La conversion de JSON en CSV introduit des difficultés qui n’existent pas dans le sens direct.
Aplatir les objets imbriqués
Le CSV est par nature plat. Lorsque votre JSON contient des objets imbriqués, il faut une stratégie d’aplatissement :
{
"name": "Alice",
"address": {
"city": "New York",
"zip": "10001"
}
}
Devient :
| name | address.city | address.zip |
|---|---|---|
| Alice | New York | 10001 |
La convention de notation par points (address.city) est l’approche la plus courante. En 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
Gérer les tableaux
Les champs de type tableau nécessitent un choix :
| Stratégie | Exemple en entrée | Sortie CSV | Idéal pour |
|---|---|---|---|
| Joindre en chaîne | ["admin","editor"] | admin;editor | Listes simples, ré-importables |
| Étendre en colonnes | ["admin","editor"] | role_0: admin, role_1: editor | Tableaux de longueur fixe |
| Étendre en lignes | ["admin","editor"] | Deux lignes, une par rôle | Analyse relationnelle |
Choisissez en fonction de votre consommateur en aval. Si le CSV est destiné à une base de données, l’extension en lignes est généralement la plus pertinente.
Perte d’information de type
Le CSV n’a pas de système de typage. Lorsque vous convertissez du JSON en CSV :
truedevient la chaîne"true"— est-ce un booléen ou une chaîne ?nulldevient une cellule vide — impossible à distinguer d’une chaîne vide""42devient"42"— est-ce un nombre ou une chaîne ?
Si la fidélité aller-retour est importante (CSV -> traitement -> JSON), documentez vos conventions de typage dans un commentaire d’en-tête ou un fichier de schéma associé.
5 pièges courants et comment les éviter
Ces problèmes corrompent silencieusement les données. La plupart des tutoriels les ignorent. Ne les découvrez pas en production.
1. Les mines de l’encodage
Le problème : Vous ouvrez un CSV envoyé par un collègue et vous voyez é au lieu de é, ou 锟斤拷 au lieu de caractères chinois.
Pourquoi cela arrive : Le fichier a été enregistré dans un encodage (Windows-1252, GBK, Shift_JIS) mais votre parseur suppose UTF-8. Excel sur Windows enregistre souvent le CSV en Windows-1252 ou ajoute un BOM UTF-8 (Byte Order Mark — le \xEF\xBB\xBF invisible au début du fichier).
La solution :
# 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)
# ...
En Node.js, supprimez le BOM explicitement :
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. Confusion de délimiteur
Le problème : Votre parseur produit une seule colonne géante au lieu de plusieurs champs.
Pourquoi cela arrive : Dans de nombreuses locales européennes, et tout particulièrement en France, Excel utilise le point-virgule (;) comme délimiteur CSV par défaut, car la virgule sert de séparateur décimal (par exemple 3,14 au lieu de 3.14). Si vous travaillez avec des fichiers générés par Excel en locale française, vous rencontrerez quasi systématiquement des fichiers séparés par des points-virgules. Les fichiers séparés par des tabulations (.tsv) ajoutent encore une variante supplémentaire.
La solution : Détectez automatiquement le délimiteur en échantillonnant les premières lignes :
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. Les zéros en tête disparaissent
Le problème : Le code postal 00501 devient 501. Le code produit 007 devient 7.
Pourquoi cela arrive : Le parseur (ou Excel) interprète le champ comme un nombre et supprime les zéros en tête. C’est particulièrement dangereux avec les codes postaux, les numéros de téléphone et les codes d’identification.
La solution : Forcez le typage en chaîne. Avec pandas :
df = pd.read_csv('data.csv', dtype={'zip': str, 'product_code': str})
En JavaScript, vérifiez si la chaîne d’origine diffère de sa conversion numérique :
function preserveLeadingZeros(value) {
if (/^0\d+$/.test(value)) return value; // Keep as string
const num = Number(value);
return isNaN(num) ? value : num;
}
4. Perte de précision des grands nombres
Le problème : L’identifiant 9007199254740993 devient 9007199254740992 dans votre JSON.
Pourquoi cela arrive : Le type Number en JavaScript est un flottant 64 bits (IEEE 754). Les entiers au-delà de Number.MAX_SAFE_INTEGER (2^53 - 1 = 9007199254740991) perdent en précision. Cela concerne les identifiants de base de données, les Snowflake ID et les identifiants de publications Twitter/X.
La solution : Conservez les grands nombres sous forme de chaînes dans le JSON, ou utilisez BigInt dans votre code de traitement :
// 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. Ambiguïté des valeurs vides
Le problème : Votre CSV contient des cellules vides. Après conversion, impossible de savoir si la valeur d’origine était une chaîne vide "", null, ou simplement absente.
Pourquoi cela arrive : Le CSV n’a aucun moyen de distinguer ces trois états. Un champ vide entre deux virgules (Alice,,30) peut signifier n’importe lequel d’entre eux.
La solution : Définissez une convention et appliquez-la de manière cohérente :
def parse_value(value):
if value == '':
return None # or '' — pick one convention
if value == 'NULL' or value == 'null':
return None
return value
Si vos données utilisent des valeurs sentinelles comme NULL, N/A ou -, documentez-les et gérez-les explicitement.
Streaming de gros fichiers
Lorsque votre CSV dépasse 100 Mo, le charger entièrement en mémoire n’est pas envisageable. Utilisez le streaming.
Node.js (pipeline de streams) :
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 (générateur) :
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')
Pour les très gros fichiers, envisagez le format JSON Lines (.jsonl) plutôt qu’un seul tableau JSON. Chaque ligne est un objet JSON indépendant, ce qui signifie que vous pouvez également traiter le fichier de sortie ligne par ligne — sans avoir à parser l’ensemble.
FAQ
Quelle est la différence entre CSV et JSON ?
CSV (Comma-Separated Values) stocke les données sous forme de table plate où chaque valeur est une chaîne de caractères. JSON (JavaScript Object Notation) stocke des données structurées avec des objets imbriqués, des tableaux et des valeurs typées (chaînes, nombres, booléens, null). Le CSV est plus compact et adapté aux tableurs ; le JSON est plus expressif et adapté aux API.
Comment convertir du CSV en JSON en JavaScript ?
Utilisez le package csv-parse dans Node.js : lisez le fichier avec createReadStream, passez-le dans parse({ columns: true }) via un pipe, et collectez les résultats. Pour une utilisation dans le navigateur, lisez le fichier avec FileReader, découpez par retours à la ligne, et associez les lignes à des objets en utilisant la ligne d’en-tête comme clés.
Comment convertir du CSV en JSON en Python ?
Utilisez csv.DictReader de la bibliothèque standard pour lire les lignes sous forme de dictionnaires, puis json.dump() pour les écrire sous forme de tableau JSON. Pour manipuler les données avant la conversion, pandas.read_csv() suivi de df.to_json(orient='records') est une alternative en une seule ligne.
Peut-on convertir du JSON imbriqué en CSV ?
Oui, mais il faut une stratégie d’aplatissement. L’approche la plus courante utilise la notation par points : un champ comme address.city devient un en-tête de colonne. En Python, pandas.json_normalize() gère cela automatiquement. Les tableaux nécessitent des décisions supplémentaires — joindre en chaînes, étendre en colonnes ou étendre en lignes.
Pourquoi mon CSV affiche-t-il des caractères corrompus après conversion ?
Il s’agit d’une incompatibilité d’encodage. Le fichier a probablement été enregistré en Windows-1252 ou GBK, mais votre parseur suppose UTF-8. Utilisez une bibliothèque de détection comme chardet (Python) pour identifier l’encodage, puis spécifiez-le explicitement à la lecture. Vérifiez également la présence d’un BOM UTF-8 que certains outils ajoutent automatiquement.
Comment gérer un fichier CSV de plus de 100 Mo ?
Utilisez le streaming au lieu de charger le fichier entier en mémoire. En Node.js, passez le flux dans csv-parse avec des streams. En Python, itérez avec csv.DictReader en utilisant un générateur. Envisagez le format JSON Lines (.jsonl) en sortie plutôt qu’un seul tableau JSON pour faciliter le traitement en aval.
Comment vérifier que mon JSON converti est valide ?
Collez la sortie dans un JSON Formatter en ligne pour vérifier la syntaxe, la structure et l’imbrication. Pour une validation automatisée, utilisez JSON.parse() en JavaScript ou json.loads() en Python — les deux génèrent des erreurs claires sur une entrée invalide. Pour la validation de schéma, définissez un JSON Schema et validez de manière programmatique.
Points clés à retenir
- Choisissez la bonne méthode selon votre contexte : outils navigateur pour les conversions ponctuelles, code pour l’automatisation, CLI pour les pipelines.
- Attention aux problèmes d’encodage — spécifiez toujours l’encodage explicitement plutôt que de vous fier aux valeurs par défaut.
- Préservez les types intentionnellement — les zéros en tête, les grands entiers et les valeurs null nécessitent tous un traitement explicite.
- Utilisez le streaming pour les gros fichiers au lieu de les charger en mémoire. Envisagez le format JSON Lines pour les très grands jeux de données.
- Validez votre sortie — passez le JSON converti dans un JSON Formatter pour détecter les problèmes structurels avant qu’ils n’arrivent en production.