JSON para CSV
Objetos e arrays aninhados tratados de forma explícita, sem limite de tamanho e sem upload.
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
CSV é retangular e JSON é uma árvore, então todo conversor precisa fazer uma série de escolhas discutíveis. A maioria faz em silêncio. Esta página faz, declara quais foram, e deixa você mudar.
Não há limite de tamanho de arquivo nem cota diária, porque não existe servidor nenhum para impor uma.
As colunas são a união, não o primeiro objeto
A decisão de maior consequência. Um conversor que lê as chaves do elemento zero descarta em silêncio todo campo que só aparece em registros posteriores, e você descobre lá na frente, quando falta uma coluna em um relatório.
Este aqui junta todos os caminhos de todas as linhas, na ordem em que cada um apareceu. É mais lento e é correto. O Papa Parse, a biblioteca CSV mais popular do JavaScript, pega o primeiro objeto por padrão e precisa de uma opção columns explícita para fazer diferente, o que vale saber se você estiver montando isso por conta própria.
Arrays dentro de uma linha: quatro políticas, um padrão
Este é o caso genuinamente ambíguo, e não há resposta certa, só um padrão certo.
- Colunas indexadas, o padrão
- tags.0, tags.1 e assim por diante. Sem perda e com ida e volta. Um único array longo explode a contagem de colunas, e esse é o custo.
- Juntar em uma célula
- Valores unidos por ponto e vírgula. Legível, com perda, e inseguro se algum valor contiver o separador.
- JSON em uma célula
- O array serializado como texto JSON. Sem perda e compacto, mas precisa de novo parsing depois.
- Explodir em linhas
- Uma linha de saída por elemento do array, repetindo as colunas escalares. É o record_path do json_normalize do pandas. Correto para uma relação de um para muitos e errado para todo o resto, então é opcional e vale para um caminho específico.
Duas coisas sobre o Excel que não são opcionais
- A marca de ordem de bytes UTF-8
- O Excel não detecta UTF-8 em um CSV. Sem um BOM no começo do arquivo ele lê os bytes na página de código do sistema e todo caractere acentuado e emoji chega corrompido. É exatamente por isso que o BOM vem ligado aqui, e desligar está a um clique para pipelines que engasgam com ele.
- Injeção de fórmulas
- Uma célula que começa com =, +, - ou @ é executada como fórmula pelo Excel, pelo Google Sheets e pelo LibreOffice. Um valor =HYPERLINK("http://evil","clique") em um CSV que você gerou vira um link ativo na planilha de outra pessoa. A OWASP chama isso de injeção de CSV. Essas células recebem um apóstrofo na frente por padrão, e a ferramenta avisa quando fez isso.
null contra string vazia
São valores diferentes em JSON e o Excel mostra os dois como em branco, então a maioria dos conversores achata os dois juntos e a distinção se perde. Aqui null vira uma célula vazia sem aspas e string vazia vira uma célula vazia com aspas, o que faz a ida e volta sobreviver. Custa dois caracteres por string vazia e vale a pena.
How to do this in code
Convertendo em código, com os argumentos que decidem se está correto.
py Python, pandas
encoding="utf-8-sig" é o jeito do pandas de escrever o BOM de que o Excel precisa. Um utf-8 puro produz um arquivo que o Excel lê errado.
import pandas as pd
# Flatten nested objects to dotted columns
df = pd.json_normalize(records)
df.to_csv('out.csv', index=False, encoding='utf-8-sig')
# One row per element of a nested array
df = pd.json_normalize(records, record_path='items', meta=['id']) sh jq
Use @csv em vez de interpolação de string. Ele cuida das regras de aspas para você.
# Union of keys as the header, then the rows
jq -r '(map(keys) | add | unique) as $c
| $c, (.[] | [.[$c[]]])
| @csv' records.json > out.csv
# @csv quotes and escapes correctly; @text does not js JavaScript
import Papa from 'papaparse';
// Pass the union explicitly. Without it, Papa takes the keys of
// the first object and silently drops the rest.
const columns = [...new Set(records.flatMap(Object.keys))];
const csv = Papa.unparse(records, { columns }); go Go
w := csv.NewWriter(f)
w.Write(columns)
for _, rec := range records {
row := make([]string, len(columns))
for i, c := range columns {
row[i] = fmt.Sprint(rec[c])
}
w.Write(row)
}
w.Flush() Perguntas frequentes
- Por que o meu CSV tem caracteres estranhos no Excel?
- O arquivo é UTF-8 e o Excel leu como a página de código do sistema. Mantenha a opção de marca de ordem de bytes ligada. Se o arquivo vai para outro lugar que não uma planilha, desligue, já que alguns parsers tratam o BOM como parte do nome da primeira coluna.
- Por que algumas células começam com um apóstrofo?
- Porque começavam com =, +, - ou @, que planilhas executam como fórmulas. O apóstrofo neutraliza isso. Desligue a opção se você precisa do valor cru e confia no destino do arquivo.
- E se os meus dados não forem um array de objetos?
- Um objeto sozinho vira uma linha. Um array de escalares vira uma coluna. Um invólucro como {"data": [...]} usa o array de dentro e avisa que fez essa escolha, porque é um palpite e não uma regra.
- Qual delimitador para o Excel europeu?
- Ponto e vírgula. O Excel escolhe o delimitador a partir do separador de listas do sistema, que é ponto e vírgula em localidades onde a vírgula é o separador decimal. É por isso que um arquivo separado por vírgulas abre como uma coluna só em uma máquina alemã ou francesa.