上周三下午,运营同事甩过来一段接口响应,让我"帮忙整理成表格"。那是订单列表接口,外层是 {"code":0,"msg":"ok","data":{"total":28413,"list":[...]}},list 里 500 条订单,每条带 order_no、pay_amount、create_time、buyer、items。我的第一反应是全选复制、粘进 Excel:结果所有内容挤在 A 列,金额变成 1.00002E+15,日期那一列只剩下几个 #,一个多小时白干。事后看,问题不在 Excel 难用,而是我没弄懂 JSON 和表格在结构上怎么对应,也没管住字段的类型。
一、JSON 和表格其实是同一种东西的两种画法
对应关系很窄:对象数组的每一项就是一行,对象里的键就是列名,值落在格子里。反过来也成立——一张去掉表头的表格就是一个对象数组。
[
{"order_no":"20240915001","pay_amount":128.5,"city":"杭州"},
{"order_no":"20240915002","pay_amount":219,"city":"北京"}
]
order_no | pay_amount | city
20240915001 | 128.5 | 杭州
20240915002 | 219 | 北京
所以动手前的第一件事是确认"哪个数组才是数据本身"。整包响应直接转只会得到一行,列名是 code、msg、data,看着没错但完全不能用;要单独取 data.list。第二类麻烦是字段不齐:那 500 条里有 39 条没带 coupon_amount(没用券),表头必须取所有对象键的并集、缺的留空;如果照第一条的键来定列,就会无声少掉两列,而且没有任何提示。
二、真正花时间的是嵌套和一对多
buyer 是对象,展平成 buyer.nickname、buyer.phone 两列不丢信息,读着也更直白。items 是数组,那一单最多有 12 个 SKU,硬塞进一格只会变成一串 JSON 文本,没法做金额汇总。这种我会拆成两张表:orders 一行一单,order_items 一行一件,两边用 order_no 关联,业务侧在 Excel 里用数据透视表或 VLOOKUP 对上就行。
拆之前还要先把键名对齐。有的接口一处写 create_time、另一处写 createTime,表头就凭空多出一列同义字段,报表里没人会去查它为什么一半是空的。
三、我那天的处理顺序
- 先校验结构再动手。整段响应先丢进 JSON 格式化过一遍,语法不合法时能拿到出错的行列位置,比自己数括号快;常见情况是接口把一段 JSON 当字符串塞进另一个 JSON,双层转义要先脱一层壳。
- 把
data.list单独复制出来,粘进 JSON 转 Excel 看渲染出的表格。预览这步是关键:字段实际抽出了哪些列、要不要保留表头行,都在预览里一眼能确认,不用等导完再返工。 - 从预览直接复制表格贴进 Excel,或者下载 CSV 再打开。给业务看的那份我另存成 xlsx,原始那份 CSV 不动,方便下次重算。
- 反向那次是业务把明细改完用 Excel 回传,要变成 JSON 数组给开发入库。从 Excel 复制出来的是 Tab 分隔文本,Excel 转 JSON 认这种粘贴,数字和布尔值会按类型输出,省掉手工补引号。
表里有手机号和收货地址,所以我特意确认了这类转换是在浏览器本地完成的、数据不发往服务端。即便如此,往外发之前还是应该把 phone 中间四位替换掉——这份 CSV 后来在群里转了三手。
四、表格出来之后,Excel 里要防这五个坑
| 现象 | 原因 | 怎么办 |
|---|---|---|
| 订单号显示成 1.00002E+15 | Excel 只保留 15 位有效数字,18 位单号的末几位被抹成 0 | 该列按文本导入;已经变成科学计数法的必须重新导,被抹掉的尾数找不回来 |
| 中文列变成"䏿–‡"这种怪字 | CSV 没带 BOM,Excel 拿本地 ANSI 去解 UTF-8 字节 | 导出带 UTF-8 BOM 的那份,或在"数据→从文本"里手工指定 65001 |
| 日期列显示 ###### | 列宽不够,或那个值本质上还是字符串 | 双击列边界自适应;字符串日期用"分列"按 YYYY-MM-DD 转一次 |
| 备注里一个逗号把一行劈成两列 | 字段含分隔符却没有整体用双引号包住 | 含逗号/换行的字段必须加引号,字段内部的双引号写成两个 |
| 金额 1,280.50 变成文本或日期 | 千分位逗号让 Excel 猜错了类型 | CSV 里只放裸数值,千分位交给 Excel 单元格格式去做 |
这五条里只有第一条是不可逆的。我那天贴坏的两百多行单号就是重新导了一遍才修回来。
五、常见疑问
Q:粘进去只有几百行,接口明明说有两万多条?
多半是分页。total 是 28413 而 list 长度是 500,说明手上只有第一页。这种先翻完再转,别把一页当全量交出去。
Q:CSV 和 xlsx 该存哪个?
CSV 是纯文本、单表、不带样式,任何语言都能读,体积小,适合再进程序;xlsx 支持多工作表、公式和格式,适合交付给业务。我的习惯是 CSV 存档、另存一份 xlsx 给看的人。
Q:导出来的列顺序和我想的不一样?
列序取决于字段在数据里首次出现的先后,不是你期望的顺序。想固定列序,就在转之前把字段挑一遍、只留需要的键。
Q:数据量很大还能这么处理吗?
这类页面是把文本读进浏览器再渲染成表格,几十万行时光是渲染就够卡。我的分界线是几千行以内走这里,几万行以上让后端直接落文件,或者分页取完合并。
Q:转出来的表怎么核对没丢数据?
看两个数:源数组的长度对上表格行数,pay_amount 求和对上接口另给的汇总字段。两项都一致才算转完,只挑几行看是看不出漏列的。
回头看那个下午,真正让我难看的不是不会转表格,而是拿一份只有 500 条的数据做完了月报,第二天被财务指出总额差了三十万。转换本身是十分钟的事,值钱的顺序是:先确认哪个数组是数据、再确认拿到的是不是全量、最后才定列和类型——尤其是单号这种一旦被数值化就回不来的列。