Skip to content
Torna al blog
Tutorial

Conversione CSV in JSON: metodi, insidie ed esempi di codice

Converti CSV in JSON (e viceversa) online con Python, JavaScript e CLI. Tratta encoding, type coercion e streaming di file di grandi dimensioni.

12 min di lettura

Guida alla conversione CSV in JSON: metodi, insidie e best practice

Il tuo team operativo ti invia un export CSV. La tua API si aspetta JSON. Apri il file, fissi 10.000 righe di valori separati da virgola e ti chiedi: qual è il modo più veloce per convertire CSV in JSON senza perdere dati?

Questa guida copre quattro metodi di conversione (strumenti browser, JavaScript, Python, CLI), la direzione inversa (JSON in CSV), cinque insidie che corrompono silenziosamente i tuoi dati e come gestire file troppo grandi per stare in memoria.

CSV vs JSON: quando usare quale

Prima di convertire, è utile capire in cosa eccelle ciascun formato.

DimensioneCSVJSON
StrutturaTabella piatta (righe e colonne)Gerarchia annidata (oggetti, array)
Tipi di datoTutto è una stringastring, number, boolean, null
Leggibilità umanaAdatto a fogli di calcoloAdatto agli sviluppatori
Uso primarioExport/import dati, report, ETLAPI, file di config, storage NoSQL
Dimensione filePiù piccolo (no nomi di chiave ripetuti)Più grande (nomi di chiave ripetuti per record)
SchemaImplicito (riga di intestazione)Esplicito (o tramite JSON Schema)

Regola pratica: Usa CSV quando i tuoi dati sono tabellari e il consumatore è un foglio di calcolo o una pipeline dati. Usa JSON quando i tuoi dati hanno gerarchia o il tuo consumatore è una API. Puoi sempre validare il tuo output JSON con un Formattatore JSON per cogliere problemi strutturali in anticipo.

Se il tuo progetto usa formati JSON rilassati come JSON5 o JSONC per la configurazione, vedi la nostra guida alla formattazione di JSON5 e JSONC per differenze di sintassi e tooling.

4 modi per convertire CSV in JSON

Metodo 1 — Strumento basato su browser

Per conversioni una tantum, un approccio basato su browser è il percorso più veloce. Incolla il tuo CSV in un convertitore online, ottieni il JSON in uscita, poi valida il risultato in un Formattatore JSON per confermare che la struttura sia corretta.

Il vantaggio: i tuoi dati non lasciano mai il browser. Niente upload, niente elaborazione server, niente preoccupazioni sulla privacy. Questo conta quando lavori con dati interni, chiavi API incorporate negli export, o qualsiasi cosa che preferiresti non inviare a un server di terze parti.

Migliore per: file piccoli (sotto i 10 MB), conversioni rapide una tantum e membri del team non tecnici.

Metodo 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));

Funziona per CSV semplici senza campi tra virgolette. Per uso in produzione con virgole all’interno dei valori, a capo nei campi o stringhe tra virgolette, usa un parser appropriato.

Node.js (csv-parser + stream):

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’opzione columns: true usa la prima riga come chiavi. L’opzione trim rimuove gli spazi dai valori. Questo gestisce campi tra virgolette, virgole con escape e valori multilinea correttamente.

Metodo 3 — Python

Libreria standard (zero dipendenze):

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 mappa ogni riga a un dizionario usando la riga di intestazione come chiavi. Il flag ensure_ascii=False preserva i caratteri Unicode (cinesi, giapponesi, accentati) invece di farne escape in \uXXXX.

Pandas (one-liner per data scientist):

import pandas as pd

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

Quando usare cosa:

  • csv + json: Script leggeri, funzioni Lambda, container dove vuoi dipendenze minime.
  • pandas: Quando devi anche pulire, filtrare o trasformare dati prima di convertire. L’overhead di importare pandas vale la pena quando stai facendo più della semplice conversione di formato.

Metodo 4 — Strumenti CLI

Per script shell e pipeline di automazione:

csvkit:

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

Miller (mlr):

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

Pipe con jq per filtrare:

# Converti e filtra in un'unica pipeline
csvjson data.csv | jq '[.[] | select(.age | tonumber > 25)]'

Miller è particolarmente potente perché gestisce CSV, JSON, TSV e altri formati nativamente. Puoi trasformare i dati durante la conversione:

# Converti CSV in JSON, rinomina un campo, aggiungi un campo calcolato
mlr --csv --json rename name,fullName then put '$age_group = ($age > 30) ? "senior" : "junior"' data.csv

JSON in CSV: gestire la direzione inversa

Convertire JSON in CSV introduce sfide che non esistono nella direzione diretta.

Appiattire oggetti annidati

Il CSV è intrinsecamente piatto. Quando il tuo JSON ha oggetti annidati, ti serve una strategia di appiattimento:

{
  "name": "Mario Rossi",
  "address": {
    "city": "Milano",
    "zip": "20100"
  }
}

Diventa:

nameaddress.cityaddress.zip
Mario RossiMilano20100

La convenzione della notazione a punto (address.city) è l’approccio più comune. In Python:

import pandas as pd

data = [
    {"name": "Mario Rossi", "address": {"city": "Milano", "zip": "20100"}},
    {"name": "Luigi Bianchi", "address": {"city": "Roma", "zip": "00100"}}
]

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

Gestire gli array

I campi array richiedono una decisione:

StrategiaEsempio inputOutput CSVMigliore per
Unione come stringa["admin","editor"]admin;editorListe semplici, riimportabili
Espansione in colonne["admin","editor"]role_0: admin, role_1: editorArray a lunghezza fissa
Espansione in righe["admin","editor"]Due righe, una per ruoloAnalisi relazionale

Scegli in base al tuo consumatore a valle. Se il CSV torna in un database, espandere in righe di solito ha più senso.

Perdita di informazioni sui tipi

Il CSV non ha sistema di tipi. Quando converti JSON in CSV:

  • true diventa la stringa "true" — è un boolean o una stringa?
  • null diventa una cella vuota — indistinguibile da una stringa vuota ""
  • 42 diventa "42" — è un numero o una stringa?

Se la fedeltà del round-trip conta (CSV → elabora → JSON), documenta le tue convenzioni di tipo in un commento di intestazione o in un file schema accompagnatorio.

5 insidie comuni e come evitarle

Questi problemi corrompono silenziosamente i dati. La maggior parte dei tutorial li salta. Non impararli in produzione.

1. Mine vaganti dell’encoding

Il problema: Apri un CSV da un collega e vedi é invece di é, o 锟斤拷 invece di caratteri cinesi.

Perché succede: Il file è stato salvato in un encoding (Windows-1252, GBK, Shift_JIS) ma il tuo parser assume UTF-8. Excel su Windows spesso salva CSV come Windows-1252 o aggiunge un BOM UTF-8 (Byte Order Mark — il \xEF\xBB\xBF invisibile all’inizio del file).

La soluzione:

# Rileva prima l'encoding
import chardet

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

# Poi leggi con l'encoding corretto
with open('data.csv', encoding=result['encoding']) as f:
    reader = csv.DictReader(f)
    # ...

In Node.js, rimuovi il BOM esplicitamente:

import { readFileSync } from 'fs';

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

2. Confusione sui delimitatori

Il problema: Il tuo parser produce una colonna gigante invece di più campi.

Perché succede: In molte locale europee (Francia, Germania, Spagna, Italia), Excel usa il punto e virgola (;) come delimitatore CSV perché le virgole sono usate come separatori decimali (es. 3,14 invece di 3.14). I file separati da tab (.tsv) aggiungono un’altra variante.

La soluzione: Auto-rileva il delimitatore campionando le prime righe:

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. Gli zeri iniziali svaniscono

Il problema: Il CAP 00501 diventa 501. Il codice prodotto 007 diventa 7.

Perché succede: Il parser (o Excel) interpreta il campo come numero e rimuove gli zeri iniziali. Questo è particolarmente pericoloso con CAP, numeri di telefono e codici ID.

La soluzione: Forza il tipo stringa. In pandas:

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

In JavaScript, verifica se la stringa originale differisce dal suo parse numerico:

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

4. Perdita di precisione con numeri grandi

Il problema: L’ID 9007199254740993 diventa 9007199254740992 nel tuo JSON.

Perché succede: Number di JavaScript è un float a 64 bit (IEEE 754). Gli interi sopra Number.MAX_SAFE_INTEGER (2^53 - 1 = 9007199254740991) perdono precisione. Questo colpisce ID di database, ID Snowflake e ID dei post Twitter/X.

La soluzione: Mantieni i numeri grandi come stringhe in JSON, o usa BigInt nel tuo codice di elaborazione:

// Analizza preservando le stringhe per i numeri grandi
function safeParseNumber(value) {
  const num = Number(value);
  if (Number.isInteger(num) && !Number.isSafeInteger(num)) {
    return value; // Mantieni come stringa per preservare la precisione
  }
  return isNaN(num) ? value : num;
}

5. Ambiguità del valore vuoto

Il problema: Il tuo CSV ha celle vuote. Dopo la conversione, non puoi dire se il valore originale era una stringa vuota "", null, o semplicemente mancante.

Perché succede: Il CSV non ha modo di distinguere tra questi tre stati. Un campo vuoto tra due virgole (Alice,,30) potrebbe significare uno qualsiasi di essi.

La soluzione: Definisci una convenzione e applicala in modo coerente:

def parse_value(value):
    if value == '':
        return None        # o '' — scegli una convenzione
    if value == 'NULL' or value == 'null':
        return None
    return value

Se i tuoi dati usano valori sentinella come NULL, N/A o -, documentali e gestiscili esplicitamente.

Streaming di file di grandi dimensioni

Quando il tuo CSV supera i 100 MB, caricarlo interamente in memoria non è un’opzione. Usa lo 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 (generatore):

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 verso il formato JSON Lines (un oggetto JSON per riga)
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')

Per file molto grandi, considera JSON Lines (.jsonl) invece di un singolo array JSON. Ogni riga è un oggetto JSON indipendente, il che significa che puoi elaborare anche il file di output riga per riga — non c’è bisogno di analizzare l’intera cosa.

FAQ

Qual è la differenza tra CSV e JSON?

Il CSV (Comma-Separated Values) memorizza i dati come una tabella piatta dove ogni valore è una stringa. Il JSON (JavaScript Object Notation) memorizza dati strutturati con oggetti annidati, array e valori tipizzati (stringhe, numeri, booleani, null). Il CSV è più piccolo e adatto ai fogli di calcolo; il JSON è più espressivo e adatto alle API.

Come converto CSV in JSON in JavaScript?

Usa il pacchetto csv-parse in Node.js: leggi il file con createReadStream, fallo passare attraverso parse({ columns: true }) e raccogli i risultati. Per uso nel browser, leggi il file con FileReader, dividi per a capo e mappa le righe a oggetti usando la riga di intestazione come chiavi.

Come converto CSV in JSON in Python?

Usa csv.DictReader dalla libreria standard per leggere le righe come dizionari, poi json.dump() per scriverle come array JSON. Per la manipolazione dei dati prima della conversione, pandas.read_csv() seguito da df.to_json(orient='records') è un’alternativa one-liner.

Si può convertire JSON annidato in CSV?

Sì, ma serve una strategia di appiattimento. L’approccio più comune usa la notazione a punto: un campo come address.city diventa un’intestazione di colonna. In Python, pandas.json_normalize() gestisce questo automaticamente. Gli array richiedono decisioni extra — unire come stringhe, espandere in colonne o espandere in righe.

Perché il mio CSV ha caratteri illeggibili dopo la conversione?

Mismatch di encoding. Il file è stato probabilmente salvato in Windows-1252 o GBK, ma il tuo parser assume UTF-8. Usa una libreria di rilevamento come chardet (Python) per identificare l’encoding, poi specificalo esplicitamente in lettura. Verifica anche un BOM UTF-8 che alcuni strumenti aggiungono automaticamente.

Come gestisco un file CSV più grande di 100 MB?

Usa lo streaming invece di caricare l’intero file in memoria. In Node.js, fai pipe attraverso csv-parse con stream. In Python, itera con csv.DictReader usando un generatore. Considera l’output in formato JSON Lines (.jsonl) invece di un singolo array JSON per un’elaborazione a valle più semplice.

Come posso verificare che il mio JSON convertito sia valido?

Incolla l’output in un Formattatore JSON online per verificare sintassi, struttura e annidamento. Per la validazione automatizzata, usa JSON.parse() in JavaScript o json.loads() in Python — entrambi lanciano errori chiari su input non valido. Per la validazione di schema, definisci un JSON Schema e valida programmaticamente.

Punti chiave

  1. Scegli il metodo giusto per il tuo contesto: strumenti browser per conversioni rapide una tantum, codice per l’automazione, CLI per le pipeline.
  2. Attento ai problemi di encoding — specifica sempre l’encoding esplicitamente piuttosto che fare affidamento sui default.
  3. Preserva i tipi intenzionalmente — zeri iniziali, interi grandi e valori null hanno tutti bisogno di gestione esplicita.
  4. Fai streaming dei file grandi invece di caricarli in memoria. Considera il formato JSON Lines per dataset molto grandi.
  5. Valida il tuo output — fai passare il JSON convertito attraverso un Formattatore JSON per cogliere problemi strutturali prima che arrivino in produzione.

Articoli correlati

Vedi tutti gli articoli