Ir para o conteúdo
jsonbeautifiers
Português

CSV para JSON

Detecção de delimitador, campos entre aspas e inferência de tipos que não come os seus CEPs.

CSV
JSON

Nada do que você cola sai do seu navegador. A lista de permissões connect-src transforma isso em uma garantia do navegador, e não em uma promessa. Confira você mesmo

Converta CSV em um array JSON de objetos, com a linha de cabeçalho virando as chaves. Os delimitadores são detectados, campos entre aspas com vírgulas e quebras de linha dentro são tratados, e nomes de coluna duplicados são renomeados em vez de descartados.

A inferência de tipos vem desligada por padrão, e isso é de propósito.

Por que todo valor é string até você dizer o contrário

A inferência de tipos é onde conversores de CSV destroem dados. Um CSV não tem tipos, então o conversor precisa adivinhar, e os palpites erram de um jeito difícil de perceber.

007 vira 7 e lá se foi o CEP. Um telefone escrito como 1234567890123456789 passa do que um número JavaScript consegue guardar e volta diferente. Um código de produto como 1E5 vira 100000. Um valor NA vira string em uma linha e cabeçalho de coluna em outro lugar.

Por isso o padrão é string. Ligue a inferência quando você conhece os seus dados, e note que mesmo assim os zeros à esquerda são preservados e qualquer valor que não sobreviveria a uma ida e volta em float64 continua string.

As regras do CSV em que todo mundo tropeça

Aspas
RFC 4180: um campo que contém vírgula, aspas ou quebra de linha é envolvido em aspas duplas, e uma aspa interna vira duas aspas. Este parser lê isso corretamente, inclusive campos de várias linhas.
Delimitadores
Vírgula, ponto e vírgula, tabulação e barra vertical são detectados automaticamente contando ocorrências fora das aspas nas primeiras linhas. O Excel europeu escreve ponto e vírgula.
Cabeçalhos duplicados
Objetos JSON não podem ter chaves duplicadas, então um nome de coluna repetido recebe um sufixo e a mudança é reportada. Descartar um deles seria perda silenciosa de dados.
Linhas irregulares
Uma linha com menos campos que o cabeçalho recebe nulls; uma com mais guarda o excedente sob a chave _extra. Os dois casos são reportados com número de linha em vez de realinhados em silêncio.
A marca de ordem de bytes
É removida e reportada. Deixada ali, ela vira parte do nome da primeira coluna, o que produz um campo que some misteriosamente.

Reconstruindo a estrutura aninhada

Se os seus cabeçalhos forem caminhos com pontos, como em um CSV produzido pelo nosso próprio conversor, ligue "expandir cabeçalhos com pontos" e o aninhamento é reconstruído: address.city vira um objeto aninhado em vez de uma chave que contém um ponto.

How to do this in code

Convertendo em código.

py Python

utf-8-sig tira o BOM. dtype=str é como você impede o pandas de transformar 007 em 7.

import csv, json

# The standard library gives you strings, which is the honest default
with open('in.csv', newline='', encoding='utf-8-sig') as f:
    rows = list(csv.DictReader(f))
print(json.dumps(rows, indent=2))

# pandas infers types, which is convenient and lossy
import pandas as pd
df = pd.read_csv('in.csv', dtype=str)   # dtype=str turns inference OFF
records = df.to_dict(orient='records')
js JavaScript
import Papa from 'papaparse';

const { data, errors } = Papa.parse(csv, {
  header: true,
  skipEmptyLines: true,
  dynamicTyping: false,   // leave it off; see the note above
});
sh Shell
# csvkit
in2csv data.csv | csvjson --indent 2 > data.json

# Or with Miller, which is a single binary
mlr --icsv --ojson cat data.csv

Perguntas frequentes

Devo ligar a inferência de tipos?
Só se você conhece os dados. Ela acerta na maior parte das vezes, e as exceções são justamente os valores que você não pode perder: CEPs, números de conta, códigos de peça, telefones, qualquer coisa com zero à esquerda. Mesmo com a inferência ligada, esta ferramenta deixa esses em paz.
Por que o nome da minha primeira coluna está estranho?
Uma marca de ordem de bytes. Esta ferramenta remove e avisa. Um parser que não faz isso deixa um caractere invisível no começo do nome, então buscas por esse nome falham sem motivo visível.
Dá para gerar NDJSON em vez de um array?
Converta aqui e depois use a página de NDJSON, que transforma um array em um registro por linha. Esse é o melhor formato para qualquer coisa que você pretenda transmitir em fluxo ou ir acrescentando.