问题出在哪
CSV 是平面表格:固定列、每行一条记录。
JSON 是树形结构:对象里可以嵌对象,数组里可以套数组。
这两个形状对不上。所以「JSON 转 CSV」本质上不是格式转换,而是一次结构映射的决策——你得先决定那棵树怎么压平。
下面按嵌套程度分三种情况。
一、最简单:数组套对象
json[
{ "id": 1, "name": "张三", "age": 28 },
{ "id": 2, "name": "李四", "age": 32 }
]
这种直接转,没有歧义:
id,name,age
1,张三,28
2,李四,32
用 JSON 转 CSV 粘进去就出结果。
二、对象里嵌对象:扁平化成 a.b 列名
json[
{ "id": 1, "user": { "name": "张三", "city": "杭州" } }
]
嵌套对象本身是「一对一的属性」,压平就行,列名用点号连起来:
id,user.name,user.city
1,张三,杭州
注意:层级别太深。三层以上列名会长到没法看,而且下游用起来也痛苦。真遇到这种结构,多半说明数据模型该调整了。
三、数组里嵌数组:这里必须做选择
json[
{ "id": 1, "tags": ["前端", "React"] }
]
tags 有多个值,但一行只有一格。三种处理方式:
① 序列化成字符串 —— 最简单,但下游要再拆一次
id,tags
1,"[""前端"",""React""]"
② 用分隔符连起来 —— 可读性好,但值里本身有分隔符就废了
id,tags
1,前端|React
③ 展开成多行 —— 一行变两行
id,tags
1,前端
1,React
这种方式没有信息损失,但行数变了,下游做统计时要注意去重。
三种策略怎么选
| 策略 | 优点 | 代价 |
|---|---|---|
| 扁平化(a.b) | 无信息损失,一列一个值 | 列名变长,层级别太深 |
| 序列化(JSON 字符串) | 简单、无损 | 下游要再解析一次 |
| 拆多行 | 便于分组统计 | 行数膨胀,主键重复 |
| 拆多张表 | 最规范 | CSV 装不下关系,得改交付格式 |
判断依据:目标读者是人还是程序。给人看的报表用扁平化;给程序批处理用序列化或拆多行。
中文乱码:Excel 打开 CSV 的正确姿势
这是转完 CSV 之后最常踩的坑:用 Excel 打开,中文全是乱码。
原因:CSV 文件默认存成 UTF-8,而中文版 Excel 默认按 GBK 解读,两边对不上。
两个解法:
① 存成「UTF-8 with BOM」 —— 在文件开头写一个 BOM 标记,Excel 看到就知道这是 UTF-8。这是最省事的办法,Windows 用户拿到就能直接双击打开。
② 用 Excel 的「数据 → 从文本/CSV」导入 —— 手动指定编码为 UTF-8。不改变文件,但每次都要操作一遍。
如果 CSV 是要发给别人的,建议直接选带 BOM 的;如果是喂给程序读的,不要 BOM(很多解析库会把 BOM 当成内容的一部分,反而出错)。
字段不一致怎么办
json[
{ "id": 1, "name": "张三" },
{ "id": 2, "name": "李四", "vip": true }
]
第二条多了个 vip 字段。标准做法是取所有对象的字段并集作为表头,缺失的位置留空:
id,name,vip
1,张三,
2,李四,true
不要因为「第一条没有 vip」就把这列丢掉——那会静默丢数据。
一个检查清单
转完 CSV 之后对着过一遍:
- 行数对不对(数组里几个对象就该几行,拆多行策略除外)
- 列名有没有重复(嵌套路径拼出来的列名偶尔会撞)
- 值里含逗号、引号、换行的字段有没有被正确加引号转义
- 中文在目标软件里打开正常吗
- 大整数字段有没有被 Excel 自动转成科学计数法
最后一条特别容易中招:Excel 会把超过 11 位的数字显示成 1.23E+15,而且不可逆。订单号、身份证号这类字段,转 CSV 前最好先转成字符串。
动手试
把 JSON 粘到 JSON 转 CSV 就能转。结构不合法的话,先用 JSON 格式化 校验一遍再转,能少走弯路。