CSV转JSON转换器

按 RFC 4180 把逗号分隔文本转成 JSON:双引号包裹、双引号转义、字段内换行都按标准处理,首行表头变成对象键名,整数、小数、布尔与 null 会被推断成 JSON 原生类型。

分隔符 缩进
数据行4
字段数6
推断数字11
推断布尔4
引号字段5
输出字节573

提示:输入框里按 Ctrl + Enter(macOS 用 Cmd + Enter)立刻转换一次;单独按 Enter 是换行。表格里的示例 CSV 本身带一个跨行字段和一处转义引号,可以直接看出 RFC 4180 的处理效果。

下表的「JSON 结果」列是本页同一个推断函数对单个字段跑出来的实测值。

字段原文JSON 结果规则
4242整数,推断为 number
-7-7负整数
3.143.14小数
59.9059.9小数,末尾零被去掉
1.01小数,值等于整数时仍是 number
00数字零
007"007"前导零,保留字符串
.5".5"缺整数部分,保留字符串
1e3"1e3"科学计数法不推断
+86"+86"带正号,保留字符串
0x1F"0x1F"十六进制写法不推断
90071992547409919007199254740991正好等于 253−1,仍是 number

使用方法

  1. 把 CSV 粘进上面的输入框。页面打开时已经放了一段 5 行 6 列的表格示例,右侧结果区显示的就是它的转换结果,不需要点任何按钮。
  2. 选好「分隔符」。默认逗号;有些地区的 Excel 导出的是分号,制表符导出的选制表符,都不是就选「自定义」再填一个字符。
  3. 「首行作为表头」默认勾选,第一行会被当成键名,输出对象数组;取消勾选则输出「数组的数组」,每行一个数组。
  4. 「类型推断」默认勾选:整数和小数变成 JSON 数字,true / false 变成布尔,null 变成空值,其余保持字符串。取消勾选则所有值都是字符串。
  5. 点「转换」(或在输入框里按 Ctrl + Enter)出结果;「复制结果」带走整段 JSON;「下载 .json」存成文件——这个文件不带 BOM,因为带 BOM 的 JSON 会让 JSON.parse 在第一行直接报错。

这个 CSV转JSON转换器能解决什么问题

一是把表格数据交给程序。Excel、WPS、数据库导出、后台导出的清单大多是 CSV,而接口和配置文件要的是 JSON。这个 CSV转JSON转换器负责中间那一步:表头变成键名,每一行变成一条记录,字段里的逗号、引号、换行按标准处理,不会在第一个带逗号的中文名称处把一行拆成两行。

二是让数字重新变成数字。直接人工转出来的 JSON 里,价格和库存经常带着引号写成 "59.90",下游再做求和就要先做类型转换。类型推断默认开启,整数和小数会写成 59.9 这种真正的 number,布尔字段写成 true 而不是 "true"。

三是保住那些不能变形的编号。工号、邮编、订单号、身份证号带前导零,一旦被当成数字就会丢掉开头的 0。本页的规则是:整数一旦有前导零就保留成字符串,超过 253−1 的整数也保留成字符串,避免静默丢精度。

四是处理跨行字段。备注、地址这类字段里常常带换行,Excel 会用双引号把它包起来。本页按 RFC 4180 把引号内的换行算作字段内容而不是记录结束,转出来的 JSON 里是 "第一行\n第二行"。

本页不做这些事:不读 .xlsx 二进制、不做 CSV 与 Excel 的双向转换、不合并多个文件、不做字段级的业务校验(字段数与表头不一致只提示不拦截)、不生成 CSV 的方言声明。要把 JSON 转回 CSV 请用页面底部的「JSON转CSV转换器」;只做 TSV 与 CSV 互转请用「TSV转CSV转换器」。

转换原理:RFC 4180 状态机、表头映射与类型推断

解析是一个只有两个状态的逐字符状态机:一个「在引号内」标志,加一个字段缓冲。逐个字符读进去——命中分隔符就结束当前字段,命中换行就结束当前记录;一旦当前字段的第一个字符是 ",就进入引号内状态,此后分隔符和换行都只是普通字符。规范来源是 RFC 4180(1997 年发布的 CSV 通用格式与 MIME 类型),它规定的五条内容本页都实现了:字段用逗号分隔、记录用 CRLF 结束、字段可以整体用双引号包裹、字段内部的引号写成两个连续双引号、含逗号或换行的字段必须加引号。除此之外本页额外接受三种行尾:\r\n、单独的 \n 和单独的 \r,因为 Mac 老版本、Windows 和 Unix 的行尾在真实文件里经常混在一起。

表头映射是第二步:首行的每个字段按顺序成为键名。三条例外规则:重复表头会自动加后缀,第二个 id 变成 id_2,避免后面的值把前面的悄悄覆盖;空表头会补成 column3 这种按列号命名的键;某一行字段比表头多时多余字段被丢弃并在提示里报出行号,比表头少时缺的键补空字符串,两种情况都不会让转换中断。

类型推断只用了两条正则:整数 /^-?(0|[1-9]\d*)$/、小数 /^-?(0|[1-9]\d*)\.\d+$/。它们的写法本身就排除了几种常见误判——007 不匹配(整数部分只能是单个 0 或以 1–9 开头),+86 不匹配(只允许前导减号),.5 不匹配(必须有整数部分),1e3 和 0x1F 也不匹配。布尔与空值只认全小写的 true / false / null,与 JSON 规范一致,TRUE 和 NULL 一律按字符串处理。

最后一步是 JSON.stringify(值, null, 缩进),缩进为 0 时输出压缩成一行、没有任何多余空白。所以输出永远是一段可以直接 JSON.parse 的合法文本,不需要再手工补引号或去掉尾随逗号。解析前的第一件事是丢掉开头的 U+FEFF(UTF-8 BOM):Windows 记事本另存为 UTF-8 会加上它,如果不丢,第一个键名会变成 "\uFEFFid",肉眼完全看不出来,程序里按 row.id 取值却永远是 undefined。

完整示例(数值仅作演示)

这个 CSV转JSON转换器打开时的默认条件与下面的示例完全一致:分隔符逗号、首行作为表头、类型推断开启、跳过空行、缩进 2 空格。这段 CSV 共 5 行 6 列,其中一行带跨行字段、两处带转义引号、一个字段为空、一处数字带前导零。转换后的实测指标是:

输出里最值得对照的两处:59.90 变成了 59.9——数字的末尾零在 JSON 里没有意义;而 007 仍然是字符串 "007",否则它就会变成 7,一个工号或邮编就此变形。含转义引号的字段输出为 "含 \"静音\" 按键",跨行字段输出为 "第一行\n第二行",都是合法 JSON 转义。

分隔符与参数对照表

转换结果里绝大部分差异都来自下面这几个参数。改动任意一个都会立刻重算,不需要再点按钮。

参数可选值默认影响
分隔符逗号 / 分号 / 制表符 / 竖线 / 自定义逗号决定字段边界;引号内的分隔符不算边界
自定义分隔符1 个字符,最多 4 个字符的输入框空只有分隔符选「自定义」时才读取,取输入的第一个字符
首行作为表头开 / 关开开:输出对象数组;关:输出数组的数组
类型推断开 / 关开关:所有值都写成带引号的字符串
跳过空行开 / 关开关:一个完全空的行也会产生一条记录
缩进压缩 / 2 空格 / 4 空格2 空格只影响文本体积,不影响任何值

类型推断的判定顺序也是一份对照表,按这个顺序逐条匹配,命中即停:

字段原文判定结果依据
空字符串""CSV 无法区分「空字符串」和「缺失」,一律保留空字符串
全小写 true / falsetrue / false与 JSON 字面量保持一致,大写不认
全小写 nullnull同上
匹配整数正则number但绝对值大于 253−1 时退回字符串
匹配小数正则number59.90 变 59.9,末尾零不保留
其它一切字符串含 007、+86、1e3、0x1F、带空格的值

输入范围、边界与精度说明

常见问题

为什么我的 CSV 转出来多了一列或少了一列?

绝大多数是分隔符选错了。分号分隔的文件用逗号去切,会把整行当成一个字段;反过来,逗号分隔的文件用分号切也是一样。本页在切出来的字段数只有 1、而原文里出现了逗号时会提示你检查分隔符。另一种情况是某行的字段数与表头不一致,那会在补充说明里报出具体行号。

字段里的逗号和换行要不要自己加引号?

要。含逗号、含换行、含双引号的字段必须用双引号整体包起来,这是 RFC 4180 的硬性要求,不是可选项。字段内部的双引号要写成两个连续的双引号 ""。本页的示例 CSV 里两处都能看到:"无线鼠标, 黑色" 用引号保住了逗号,"含 ""静音"" 按键" 用两个双引号表示一个字面引号。

为什么 007 没有变成 7?

因为前导零的整数在 JSON 里本来就是非法写法,而且在真实数据里几乎总是编号——工号、邮编、订单号、航班号。本页的整数正则是 /^-?(0|[1-9]\d*)$/,007 不匹配,于是保留成字符串。如果你确实需要数字,可以在转换后自行处理,或关掉类型推断再手工决定每一列的类型。

价格字段的 59.90 为什么变成了 59.9?

因为 JSON 的 number 不携带格式信息,59.90 和 59.9 是同一个值,JSON.stringify 只会输出最短形式。金额、单价这类对小数位数有要求的字段,建议取消勾选「类型推断」,让它们原样保持字符串,展示时再格式化。

空字段为什么是 "" 而不是 null?

因为 CSV 没有表达「缺失」的方式:一个空的格子既可能是空字符串,也可能是没填。RFC 4180 层面两者完全一样,本页只能选择一种并说清楚。选空字符串的理由是它不会让下游的 null 检查意外触发;需要 null 的话在业务层按列判断更可靠。

输出的 JSON 能直接 JSON.parse 吗?

可以,而且一定可以。输出由 JSON.stringify 生成,字符串里的引号、反斜杠、换行都会被正确转义,不存在尾随逗号或单引号。想验证的话,把「下载 .json」拿到的文件丢进浏览器控制台执行 JSON.parse(文本) 即可——注意本页导出的 .json 文件不带 BOM,正是因为带 BOM 会让 JSON.parse 报 Unexpected token。

Excel 打开导出的 CSV 中文乱码,是这个工具的问题吗?

不是。乱码发生在文件编码这一层:Excel 在中文 Windows 上默认按 GBK 解读,而多数系统导出的是 UTF-8。解决办法是导入时在 Excel 的「数据 → 从文本/CSV」里把文件原始格式选成 UTF-8,或者用带 BOM 的 UTF-8 保存。本页导出的 CSV 对照表带 BOM 就是为了让 Excel 直接双击打开也不乱码。

首行当表头之后,重复的列名会怎样?

会自动加后缀。第二个 id 变成 id_2,第三个变成 id_3。如果不加后缀,后一列的值会把前一列覆盖掉,生成的对象里只剩最后一个,这种丢数据比报错更难发现。空列名则补成 column3 这种按列号命名的键。

相关工具