HandyTools Hub

JSON 转 CSV 转换器

即时将 JSON 数组转换为 CSV 格式

API 和配置文件用 JSON 说话;电子表格、数据库导入和大多数报表工具用 CSV 说话。这个转换器就是两者之间的桥:粘贴一段 JSON 对象数组,它会生成一张展平、转义正确的表格,并带上表头。嵌套对象变成点号列名,含逗号或引号的字段被正确包裹,结果可以在 Excel、Google 表格或导入脚本里干净打开。

使用方法

  1. 粘贴 JSON 对象数组到输入框,或点击示例按钮载入一个三行的例子。
  2. 点击转换。 JSON 格式有误或不是数组时,错误面板会出现;否则输出区立即填入结果。
  3. 核对统计。 界面会显示行数和列数,并为每个列名显示一个标签。
  4. 复制 CSV,把结果粘进电子表格或 .csv 文件。

转换器接受什么

顶层必须是数组。每个元素应该是对象;如果某个元素是字符串或数字这类原始值,它只贡献一个空行,不贡献任何列。空数组是合法的 JSON 文档,但会提示「输入数组为空」,因为无法据此构建表头。格式错误的 JSON 会直接显示解析器本身的报错文本。转换器绝不去猜包装对象,所以 {"data": [...]} 一定要先拆开。

值在被写到 CSV 之前一直保留 JSON 类型。数字用 JavaScript 默认的数字转字符串规则序列化,因此超大整数可能在进入 CSV 之前就丢精度——一个 20 位的 ID 可能被四舍五入或以科学计数法输出。日期以字符串形式到达并原样通过,API 用什么 ISO 格式,列里就是什么格式。如果这两点会带来影响,请在源 JSON 里先把值转成字符串。深层嵌套对象没问题,每多一层,点号键就长一截。

实操示例:嵌套的 API 数据

输入:

[
  { "id": 1, "name": "Alice", "address": { "city": "Austin", "zip": "78701" } },
  { "id": 2, "name": "Bob", "address": { "city": "Denver" }, "tags": ["admin", "beta"] }
]

第一行展平为 id、name、address.city、address.zip。第二行没有 address.zip,但多出 tags。于是列的顺序是 id, name, address.city, address.zip, tags,输出为:

id,name,address.city,address.zip,tags
1,Alice,Austin,78701,
2,Bob,Denver,,"admin,beta"

注意 Alice 那一行末尾的空单元格,以及 "admin,beta" 外的引号——因为拼接后的数组含逗号。

展平与转义的工作原理

展平只递归进入普通对象。每一层嵌套把子键用点号接到父键后面,所以 user.contact.email 能表示三层。数组被当作叶子值处理。转义遵循 RFC 4180:字段包含逗号、双引号、回车或换行时整体用双引号包裹,内部的每个双引号翻倍。于是 He said "hi" 会变成 "He said ""hi"""。不需要特殊处理的字段则裸写。

表头行与数据行使用同一个转义函数,当某个键自身含逗号或引号时就很重要——API 里少见,但用户生成的字段名里并非不可能。列以展平后的路径为键,所以两个来源对象各自含有的 address.city 会合并成同一列,哪怕这两个对象在其他方面毫无关系。由于并集是在写入任何数据之前、基于所有行算出的,只在最后一条记录里出现的键同样会成为一列,并且如果没有在别处出现,它会排在列表靠后的位置。

常见错误与修正

  • 传入包装对象。 先把 { "results": [...] } 拆成里面的数组再转换。
  • 指望数组展开成多列。 数组只会塌缩成一个逗号拼接的字符串;若需要每项单独成列,请预处理成具名列。
  • 让一条记录撑大整个表结构。 单独一行多出的嵌套字段会给其他所有行都加上一个空白列。
  • 忘了 JSON 与 CSV 的空值陷阱。 缺失的键、null 和空字符串都渲染成空单元格,下游无法区分。
  • 用 Excel 默认双击打开复制结果。 含非 ASCII 文本时,请走「数据 → 从文本/CSV」,手动选 UTF-8,避免乱码。
  • 假设数字原样保留。 大 ID 可能被 JavaScript 的数字处理四舍五入;在源 JSON 里给它们加引号可保精确。
  • 指望带 UTF-8 字节序标记。 输出没有 BOM,这对代码和数据库通常是正确的,但可能让 Excel 误读非 ASCII 文本,除非通过文本/CSV 对话框导入。

什么时候 CSV 不是合适的格式

CSV 是扁平表,无法在不重复的前提下表达递归或重复组。如果 JSON 嵌套很深,或者数组长度各不相同,电子表格要么丢失结构,要么变得难以阅读。这类情况下,把数据留在 JSON 里、导入数据库,或者只把真正需要的字段展平成若干张分开的表。当每条记录形状大致扁平、并且由人或电子表格来阅读时,CSV 才是正确的选择。

一个实用的折中做法是输出两张相关联的 CSV——一张放父记录,一张放嵌套集合,两者共享一个 ID 列,然后在电子表格或数据库里连接。这样能保留单一扁平表会抹平到认不出的重复结构。如果你只是想要一个人类可读的嵌套 API 响应视图,JSON 格式化或查看工具会比任何 CSV 都更适合。

相关工具

常见问题

为什么转换时报「输入不是数组」的错误?

输入的顶层必须是 JSON 对象数组,而 API 返回的常见包装形式“results”键的外壳会被拒绝,因为最外层是对象而不是数组。先剥掉外层——把内层数组单独复制出来,或先用 JSON 格式化工具看清结构再粘贴。

行内出现数组时会怎样处理?

嵌套对象会递归展平、键用点号连接,但数组被当作单个值。像 admin、beta 这样的数组会被 CSV 转义器拼成 admin,beta;由于含逗号,整个单元格会被引号包住。若数组里装的是对象,只会得到无用的 [object Object],转换前请先自行展平或拼接。

各行键不一致时会发生什么?

转换器按首次出现的顺序收集所有行里的全部唯一键,这个并集就是表头。某行缺少某个键,对应单元格留空。这让可选字段很好处理;但反过来,某一条记录里多出一个孤立的键,就会给整张表增加一整列几乎全空的列。

null、缺失值和布尔值的写法有区别吗?

有。null 和 undefined 输出为空单元格。数字和布尔值写成字面文本,true 仍是 true,42 仍是 42。空字符串同样变成空单元格,所以「存在但为空」和「缺失」在 CSV 里看起来完全一样——下游逻辑若依赖这个区别,要特别留意。

能直接下载 .csv 文件,还是只能复制文本?

本工具只提供生成结果的复制按钮,没有文件下载控件。把结果粘进一个扩展名为 .csv 的空白文本文件,或直接粘贴到电子表格单元格再分列导入。输出是带表头行的标准逗号分隔文本。

转换器会排序或重排列吗?

不会。列顺序按对象数组中键首次出现的顺序,行顺序也与输入完全一致。如果需要字母序表头或按某字段排序的行,请在转换前先对 JSON 排序,而不要指望转换器代劳。

由 HandyTools Hub 团队审校 · 最后更新