A importação funciona perfeitamente com o arquivo de exemplo. Vai para produção, o primeiro cliente envia a planilha dele, e tudo cai em uma coluna só — ou os acentos viram símbolos, ou os CPFs perderam o zero da frente. O CSV tem fama de formato simples e é exatamente essa fama que faz a importação ser subestimada no planejamento.
A raiz do problema é que CSV não é um formato: é uma convenção com variações. E o conjunto de variações que aparece em arquivos brasileiros tem particularidades próprias, quase todas herdadas do formato regional do Excel.
Armadilha 1 — o separador é ponto e vírgula
Em português, a vírgula é o separador decimal: escrevemos 1.234,56. Se o Excel usasse vírgula também para separar campos, o valor 1.234,56 viraria dois campos. A solução dele é usar ponto e vírgula, e o resultado é que a maioria dos CSVs gerados por usuários brasileiros não é separada por vírgula, apesar do nome do formato.
# Exportado em inglês nome,valor,data Maria Souza,1234.56,2026-03-15 # Exportado em português nome;valor;data Maria Souza;1234,56;15/03/2026
Repare que a diferença não para no separador: o decimal e o formato de data também mudam. Um parser que só trata o separador ainda vai converter 1234,56 para o número 1234 ou falhar.
function detectarSeparador(primeiraLinha) {
const candidatos = [";", ",", "\t", "|"];
// O separador correto é o que aparece mais vezes no cabeçalho,
// já que nomes de coluna raramente contêm delimitadores.
return candidatos.reduce((melhor, candidato) => {
const ocorrencias = primeiraLinha.split(candidato).length - 1;
const melhorOcorrencias = primeiraLinha.split(melhor).length - 1;
return ocorrencias > melhorOcorrencias ? candidato : melhor;
}, ",");
}Armadilha 2 — a codificação não é UTF-8
O Excel em português, ao salvar como CSV, ainda usa Windows-1252 por padrão em muitas versões. Um arquivo assim, lido como UTF-8, transforma cada caractere acentuado em um símbolo estranho: São Paulo vira São Paulo.
| Caractere | Bytes em UTF-8 | Bytes em Windows-1252 | Lido como UTF-8 |
|---|---|---|---|
| ã | C3 A3 | E3 | caractere inválido |
| ç | C3 A7 | E7 | caractere inválido |
| é | C3 A9 | E9 | caractere inválido |
| ã (mojibake) | — | — | resultado de ler UTF-8 como Latin-1 |
A correção certa é na origem: pedir ao usuário que salve como CSV UTF-8, opção disponível nas versões recentes do Excel. Quando isso não é viável, dá para detectar a codificação por heurística e reprocessar, mas a detecção nunca é perfeita e falha justamente em arquivos curtos.
Armadilha 3 — o BOM invisível
Alguns programas escrevem três bytes no início do arquivo UTF-8 — EF BB BF, a marca de ordem de bytes. Ela não aparece em nenhum editor, mas o parser a lê como parte do primeiro campo do cabeçalho.
O sintoma é característico e desnorteante: a coluna existe, o dado está lá, mas o acesso pelo nome devolve indefinido. Ao inspecionar o objeto no console, a chave parece exatamente igual à que você digitou.
function removerBom(texto) {
// U+FEFF é invisível e gruda no nome da primeira coluna.
return texto.charCodeAt(0) === 0xfeff ? texto.slice(1) : texto;
}
const conteudo = removerBom(await arquivo.text());Armadilha 4 — aspas e o separador dentro do campo
Um endereço como Rua das Flores, 120 contém o separador. A convenção é envolver o campo em aspas duplas, e escapar uma aspa interna duplicando-a. Isso significa que um parser correto não pode simplesmente dividir a linha pelo separador — ele precisa percorrer caractere a caractere, controlando se está ou não dentro de aspas.
nome;endereco;observacao Maria Souza;"Rua das Flores, 120";"Cliente disse ""urgente"" no pedido"
Um split simples pelo ponto e vírgula produziria quatro campos onde existem três, e ainda deixaria as aspas no valor. É o motivo pelo qual escrever o próprio parser de CSV costuma ser mais caro do que parece — a estrutura de aspas, quebras de linha dentro do campo e escapes cobre mais casos do que a primeira versão prevê.
Armadilha 5 — a conversão automática de tipos
CSV não carrega tipo. Todo valor é texto, e converter é uma decisão do importador — decisão que erra de formas específicas e caras em dados brasileiros.
| Valor no CSV | Inferência ingênua | O que deveria ser |
|---|---|---|
| 00012345678 | 12345678 (número) | texto, é um CPF |
| 01310-100 | texto ou data | texto, é um CEP |
| 1234,56 | 1234 ou NaN | número 1234.56 |
| 15/03/2026 | texto ou data errada | data, formato dia/mês/ano |
| ABC1D23 | texto | texto, é uma placa Mercosul |
| 3E2 | 300 (notação científica) | texto, provavelmente um código |
A última linha é a mais traiçoeira: um código de produto como 3E2 é interpretado como notação científica por várias linguagens e vira o número 300. O dado é corrompido sem nenhum erro, e a descoberta acontece meses depois.
Uma ordem de processamento que funciona
- 1Leia o arquivo como bytes e determine a codificação antes de decodificar para texto.
- 2Remova o BOM, se houver, antes de olhar para o cabeçalho.
- 3Normalize as quebras de linha, já que arquivos do Windows usam CRLF e os de outros sistemas usam LF.
- 4Detecte o separador pela linha de cabeçalho e permita que o usuário corrija.
- 5Faça o parse respeitando aspas, aspas escapadas e quebras de linha dentro de campos.
- 6Normalize os nomes das colunas — remova espaços nas pontas e padronize a caixa.
- 7Converta tipos apenas nas colunas declaradas como numéricas ou de data.
- 8Mostre uma prévia das primeiras linhas antes de gravar qualquer coisa.
O passo oito é o que mais reduz suporte. Uma prévia de cinco linhas com as colunas já separadas revela erro de delimitador, de codificação e de mapeamento antes que o usuário importe dez mil registros errados.
Testando a importação
Monte uma pasta de arquivos-problema e rode a importação contra ela na suíte automatizada. O conjunto mínimo tem seis arquivos: separado por vírgula, separado por ponto e vírgula, em Windows-1252, com BOM, com aspas e vírgulas dentro de campos, e com colunas de documento que têm zero à esquerda.
O conversor CSV para JSON do Codigio Labs ajuda na etapa de diagnóstico: colando uma amostra do arquivo do cliente, dá para ver rapidamente como as colunas estão sendo separadas e se os acentos sobreviveram. O processamento acontece no navegador, então planilhas com dados de clientes não precisam ser enviadas a um serviço externo — ainda assim, o ideal é trabalhar com uma amostra anonimizada.
Resumo
- CSV brasileiro costuma ser separado por ponto e vírgula, porque a vírgula é o separador decimal.
- Windows-1252 em vez de UTF-8 é a segunda causa mais comum de falha, e corrompe os acentos.
- O BOM é invisível e gruda no nome da primeira coluna, causando campo indefinido sem erro.
- Aspas, escapes e separadores dentro de campos exigem parser real, não split.
- Documentos e códigos são texto: zero à esquerda é informação, e 3E2 não é trezentos.