JSON 转 Excel

把一组 JSON 记录铺成表格,导出 xlsx 或 CSV。嵌套字段可以按点号路径打平成列,表头、空值写法和工作表名都能自己定。

关掉打平后,嵌套的对象或数组会整体写成一格 JSON 文本。工作表名里的方括号、冒号、斜杠等字符会被自动去掉,长度截到 31 个字符。

使用说明

表格和 JSON 的结构本来就对不上:JSON 是树,键可以每层不同、也可以随便加;表格是平的,必须先定死有哪些列。所以转换的第一步是「定列」,做法是把每条记录摊成「字段路径 → 值」的映射,再按所有路径去重取并集。列的顺序按路径第一次出现的先后排,这样原始 JSON 里字段的书写顺序基本能保留下来,比按字母排序更符合直觉。

打开「打平嵌套字段」后,对象按点号继续往下走,数组则用下标当一段路径。于是 profile.city 是对象里的字段,tags.0 是数组的第一个元素,更深的组合写成 profile.tags.0.name 这样。这样导出的表格能直接在 Excel 里排序和筛选;代价是数组越长列数越多,而且不同记录之间数组长度不一致时,短的那些记录会留下一批空格子。关掉打平则相反,整个嵌套结构会被 JSON.stringify 成一段文本塞进一格,列数固定,但那格数据在 Excel 里只能当字符串看。

「空」在这里被分成了三种:格子留空、写 null、写空字符串。别看它们显示出来差不多,含义完全不同——留空代表「这个格子没有值」,null 代表「值明确是空」,空字符串代表「值是空串」。写进 CSV 时留空是两个逗号之间什么都没有,空字符串会写成一对双引号,null 是四个可见字符;之后无论是再转回 JSON 还是导入数据库,这三者都不应该被当成同一件事。空数组和空对象也会落到「空」这一类,它们没有内容可以铺成格子。

CSV 的输出有两个容易忽略的细节。第一是 BOM:Excel 打开 CSV 时默认按系统的本地编码解码,不带 BOM 的 UTF-8 中文就会变成乱码,所以导出的 CSV 开头会加一个 BOM,用记事本打开能看到多出来的三个不可见字节。第二是转义:字段里出现逗号、双引号或换行时会用双引号整段包住,内部的双引号翻倍,这是 RFC 4180 的规定。另外以等号、加号、@、制表符或回车开头的字符串值会被加一个单引号前缀,挡住 CSV 公式注入,这个前缀只在导出文本里出现,不影响页面预览。

导出 xlsx 用的是 SheetJS,它体积不小,所以做成了点按钮时才动态加载,页面首屏不付这份代价。工作表名会按 Excel 的规则清洗:方括号、星号、问号、冒号、斜杠、反斜杠都会被去掉,长度截到 31 个字符,清空后回落到 Sheet1。如果你的表格只是给程序读、不需要 Excel 的格式,CSV 更轻也更通用。要把 Excel 或 CSV 转回 JSON,用Excel 转 JSON;要处理 CSV 的列,用CSV 列处理;只是想让 JSON 好看一点,用JSON 格式化。

常见问题

粘贴的 JSON 顶层不是数组,会怎么处理?

顶层的对象会被当成「只有一行」的记录,键就是列名,并在结果区给一句提示。数组里直接放数字或字符串也能转,它们会统一落到一个叫 value 的列里。如果数据最外层是数字、字符串或布尔值,拼不成表格,会直接报错要求先包一层方括号。

打平嵌套和整体塞一格,该怎么选?

打平会把 a.b、a.0.c 这样的路径拆成一列一列,好处是导出后能在 Excel 里排序、筛选、做透视表,代价是数组越长列越多。不打平则把整个对象或数组序列化成一段 JSON 文本塞进一格,列数固定,但那一格只能在 Excel 里当字符串看,没法再拆开分析。

空值的三种写法到底差在哪?

「留空」写出来是真正的空单元格,CSV 里是两个逗号之间什么都没有;「null」会在格子里写四个字符的 null,适合之后还要被程序读回 JSON 的场景;「空字符串」在 CSV 里写成一对双引号,和留空肉眼几乎一样,但阅读时含义明确是「有值,只是为空」。写回 JSON 或数据库时这三者含义不同,不要随手选。

表头来源选「所有记录的键」和「第一条记录的键」有什么区别?

JSON 里每条记录的键可以不统一。取并集会把所有出现过的键都变成列,缺的格子留空,最不容易丢数据;只取第一条则拿第一条当模板,后面才出现的字段会被丢掉,结果区会告诉你有几个字段被丢了。数据本身规整、第一条就是完整模板时,用后者能避免多出一些偶发的怪列。

导出的数字在 Excel 里为什么顶着一个绿色三角?

那说明这个格子被 Excel 当成文本了。JSON 里写成字符串的 "123" 会被原样写进单元格,Excel 就会提示「以文本形式存储的数字」。这是刻意的:手机号、订单号、身份证号本来就该保持文本,转成数字会丢前导零。如果这一列确实要参与计算,请先在源数据里把它写成不带引号的数字。

CSV 打开中文是乱码,文件里那些单引号又是怎么回事?

乱码是因为 Excel 打开 UTF-8 的 CSV 默认按本地编码解码,所以导出的 CSV 开头带了一个 UTF-8 BOM,用记事本或支持 UTF-8 的编辑器打开就能看到它。另外,以等号、加号、@ 等开头的字符串值前面会被加一个单引号,这是为了挡住 CSV 公式注入——Excel 会把这类单元格当公式执行,导入外部数据时可能被利用。

导出 xlsx 会下载多少东西?

SheetJS 是一个几百 KB 的库,只在点「导出 xlsx」时才动态加载,首屏不会付这份代价。所以第一次导出会有一点点延迟,之后就很快了。只想拿表格数据、不需要 Excel 的格式和多个工作表时,直接导出 CSV 更轻也更通用,几十万行也不会卡。

怎么把导出的表格再变回 JSON?

用 Excel 转 JSON 那一页,把 xlsx 或 CSV 传回去即可,两边对日期和长数字的处理规则是一套。如果只是想先把 JSON 排整齐再转换,用 JSON 格式化;想按列拆分、合并 CSV 的字段,用 CSV 列处理。

相关:Excel 转 JSONJSON 格式化CSV 列处理