CSV 打开全是乱码:BOM、编码与分隔符
办公与文档发布于 2026-10-31
导出数据、下载报表、系统对接,只要沾 CSV,「双击打开是乱码」这件事几乎一定会遇到一次。
先把结论说完:
| 现象 | 原因 | 处理 |
|---|---|---|
| 中文全变「锟斤拷」「烫烫烫」或方块 | 文件是 UTF-8,Excel 按 GBK 解了 | 存成 UTF-8 带 BOM,或改用「数据 → 从文本/CSV」导入 |
| 所有内容挤在一列 | 分隔符不是逗号 | 导入时手动指定分隔符 |
| 数字变成 1.23E+15、日期变成 ######## | Excel 自动识别类型 | 导入时把该列设为「文本」 |
| 某个单元格里出现不该有的换行 | 字段内含逗号或换行但没加引号 | 按 RFC 4180 用双引号包裹 |
下面逐条说清楚。
乱码本身不是「文件坏了」
文本文件只是字节,编码是「怎么解释这些字节」的约定。同一个「中」字:
- UTF-8 里是 3 个字节
E4 B8 AD - GBK 里是 2 个字节
D6 D0
用 GBK 去读 UTF-8 的字节,会按两个一组重新拼字,拼出来的就是「涓」这类离奇汉字;拼不成合法字符时显示成 �。字节一个都没丢,只是解释方式错了。
所以乱码的正确修法永远是「换一种编码重新读」,而不是复制出来手动改。
为什么 Excel 双击就错,导入就对
Excel 双击打开 .csv 时,不看文件内容,只看两件事:
- 文件开头有没有 BOM
- 没有 BOM,就用系统「非 Unicode 程序的语言」对应的代码页(简体中文 Windows 上是 GBK / CP936)
UTF-8 无 BOM 的文件在这些机器上必然乱码。而「数据 → 从文本/CSV」这个入口会让你显式选编码(列表里选 65001 : Unicode (UTF-8)),所以它是对的。
同一个文件在 Mac 版 Excel 上可能是正常的 —— macOS 默认按 UTF-8 解。这类「同事那边好好的」问题几乎都是编码差异。
BOM 加还是不加
BOM 是文件最前面 3 个字节 EF BB BF(U+FEFF)。它不属于内容,是个提示。
| 场景 | 建议 |
|---|---|
| 给 Excel 用户下载的 CSV | 加。这是唯一能让双击打开不乱码的办法 |
| 给程序读的 CSV(pandas / 后端导入) | 不加更干净,但加了通常也能读;pandas 要写 encoding='utf-8-sig' |
| 上传到第三方系统 | 先看它的文档。有些老系统会把 BOM 当成第一列的列名的一部分,导致「表头匹配不上」 |
那个「表头匹配不上」很典型:列名本来叫 姓名,带 BOM 后程序读到的是 \ufeff姓名,两个字符串不相等,校验直接失败,而肉眼看起来一模一样。
怎么判断一个文件有没有 BOM
在命令行里看前三个字节:
# Linux / macOS / Git Bash
head -c 3 data.csv | xxd
# 有 BOM:00000000: efbb bf
Windows 上可以用 PowerShell:
[System.IO.File]::ReadAllBytes('data.csv')[0..2] -join ','
# 有 BOM:239,187,191
分隔符:逗号不是唯一的
CSV 的 C 是 comma,但现实里到处是分号、制表符、竖线。原因之一是欧洲区域设置里逗号是小数点,Excel 只好用分号当列表分隔符。
判断方法:把文件当纯文本看一眼,哪一列字符出现得最规律,哪个就是分隔符。
遇到这种文件,别硬改后缀,交给工具转一下更省事 —— CSV 转 JSON 会自动识别逗号、分号、制表符和竖线四种分隔符,也能顺手看清到底被切成了几列;如果只是想要一份规整的表格,表格转换 支持 CSV / TSV / Markdown 表格之间互转。
引号与转义:最容易被忽略的一节
RFC 4180 规定:字段里如果含有分隔符、双引号或换行,整个字段要用双引号包起来,字段内的双引号写成两个。
姓名,备注
张三,"他说""明天到"",别等他"
李四,"第一行
第二行"
第二条记录是一行数据横跨两行文本。用 split('\n') 去切这种文件必错 —— 这是自己写 CSV 解析器最常见的第一个坑。判断「是否在引号内」的状态机不能省。
反过来,很多人用 Excel 另存为 CSV 后发现「格式全乱了」,通常是引号规则不同(Excel 只在必要时加引号),而不是文件坏了。
一份可以直接照做的排查顺序
- 看前 3 个字节有没有
EF BB BF。有 BOM 还乱码,说明文件其实不是 UTF-8。 - 换编码试读。UTF-8 → GBK → GB18030,一般三次之内必中。GB18030 是超集,能读 GBK 也能读部分生僻字。
- 看列数对不对。乱码修好后如果只剩一列,是分隔符问题,不是编码问题。
- 数字被吃掉了。Excel 把
00123变成123、把 18 位订单号变成1.23E+17,都是自动类型转换。用导入向导把列设成文本,或者干脆别用 Excel 打开 —— 文本排版纠正 这类工具处理全角空格、不可见字符更稳。 - 还是不对,就转成 JSON 看结构。JSON 会强制显式表达「这是字符串」,肉眼能立刻发现哪一列被切错。
一句话记住
乱码 = 编码猜错,挤成一列 = 分隔符猜错,数字变形 = 类型猜错。Excel 双击打开时这三件事都在「猜」。要它别猜,就走导入向导。
导出 CSV 时也一样:给业务同事的文件加 BOM,给程序的文件明确声明 UTF-8,两边都少一半沟通成本。