使用方法
- 把 CSV 粘进上面的输入框。页面打开时已经放了一段 5 行 6 列的表格示例,右侧结果区显示的就是它的转换结果,不需要点任何按钮。
- 选好「分隔符」。默认逗号;有些地区的 Excel 导出的是分号,制表符导出的选制表符,都不是就选「自定义」再填一个字符。
- 「首行作为表头」默认勾选,第一行会被当成键名,输出对象数组;取消勾选则输出「数组的数组」,每行一个数组。
- 「类型推断」默认勾选:整数和小数变成 JSON 数字,
true/false变成布尔,null变成空值,其余保持字符串。取消勾选则所有值都是字符串。 - 点「转换」(或在输入框里按 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 列,其中一行带跨行字段、两处带转义引号、一个字段为空、一处数字带前导零。转换后的实测指标是:
- 数据行 4(表头不算)、字段数 6,一共 24 个单元格;
- 推断数字 11:
1、2、3、59.9、329、129、120、45、0、89、15; - 推断布尔 4:四个
true/false;字符串 9:含那个带前导零的"007"与一个空字符串;11 + 4 + 9 = 24,正好对上单元格总数; - 引号字段 5:被双引号整体包裹过的字段有 5 个;字段内换行 1 处;
- 输出字节 573(UTF-8,缩进 2 空格);改成压缩输出后是 404 字节,省下 169 字节、约 29.5%。
输出里最值得对照的两处:59.90 变成了 59.9——数字的末尾零在 JSON 里没有意义;而 007 仍然是字符串 "007",否则它就会变成 7,一个工号或邮编就此变形。含转义引号的字段输出为 "含 \"静音\" 按键",跨行字段输出为 "第一行\n第二行",都是合法 JSON 转义。
分隔符与参数对照表
转换结果里绝大部分差异都来自下面这几个参数。改动任意一个都会立刻重算,不需要再点按钮。
| 参数 | 可选值 | 默认 | 影响 |
|---|---|---|---|
| 分隔符 | 逗号 / 分号 / 制表符 / 竖线 / 自定义 | 逗号 | 决定字段边界;引号内的分隔符不算边界 |
| 自定义分隔符 | 1 个字符,最多 4 个字符的输入框 | 空 | 只有分隔符选「自定义」时才读取,取输入的第一个字符 |
| 首行作为表头 | 开 / 关 | 开 | 开:输出对象数组;关:输出数组的数组 |
| 类型推断 | 开 / 关 | 开 | 关:所有值都写成带引号的字符串 |
| 跳过空行 | 开 / 关 | 开 | 关:一个完全空的行也会产生一条记录 |
| 缩进 | 压缩 / 2 空格 / 4 空格 | 2 空格 | 只影响文本体积,不影响任何值 |
类型推断的判定顺序也是一份对照表,按这个顺序逐条匹配,命中即停:
| 字段原文 | 判定结果 | 依据 |
|---|---|---|
| 空字符串 | "" | CSV 无法区分「空字符串」和「缺失」,一律保留空字符串 |
全小写 true / false | true / false | 与 JSON 字面量保持一致,大写不认 |
全小写 null | null | 同上 |
| 匹配整数正则 | number | 但绝对值大于 253−1 时退回字符串 |
| 匹配小数正则 | number | 59.90 变 59.9,末尾零不保留 |
| 其它一切 | 字符串 | 含 007、+86、1e3、0x1F、带空格的值 |
输入范围、边界与精度说明
- 整数的安全边界是 253−1 = 9007199254740991。这是 IEEE 754 双精度浮点能精确表示的最大整数,超过之后
Number()就会开始丢精度:9007199254740993会变成9007199254740992。本页对超界整数保留成字符串,宁可让下游多做一次类型转换,也不静默改写你的数据。 - 前导零一律保留字符串。
007、0755这类写法在 JSON 数字语法里本来就不合法(不允许前导零),而且它们几乎总是编号而不是数量,所以推断函数直接跳过。代价是如果某列真的是「带前导零的数字」,你需要自己再转一次。 - 小数会被规范化。
59.90→59.9、1.00→1。JSON 数字不保存「几位小数」这种格式信息,金额要保留两位请关掉类型推断,让它保持字符串。 - 空字段不会变成 null。CSV 里一个空的格子既可能是空字符串也可能是缺失值,规范没有给出区分办法,本页统一输出
""。真要null请在下游按业务规则转换。 - 字段与表头数量不匹配不会中断转换。多出来的字段被丢弃、缺的键补空字符串,两种情况的受影响行号都会写在结果下方的补充说明里。
- BOM 会被自动剥掉。如果 CSV 是记事本另存的 UTF-8(带
U+FEFF),第一个键名本来会变成"\uFEFFid",本页解析前先丢掉这一个字符。 - GBK 乱码不修。如果文件是用 GBK 编码保存的,粘进来就已经是乱码了,工具看到的只是些错字符。请先在编辑器和 Excel 里另存为 UTF-8 再粘贴。
- 输入上限 100 万字符(输入框
maxlength)。解析与推断都是单次遍历,示例规模下是毫秒级;几十万行建议分批处理,因为输出文本会同等规模地占用页面内存。
常见问题
为什么我的 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 这种按列号命名的键。
相关工具
- JSON校验工具:转出来的 JSON 语法对不对,用逐字符状态机定位到具体行列。
- JSON转CSV转换器:反方向的转换,把对象数组压回逗号分隔文本。
- CSV格式化:只做对齐与缩进,不改变字段结构。
- CSV转Markdown表格:把同一份数据直接变成文档里能用的 Markdown 表格。
- TSV转CSV转换器:制表符与逗号之间互换,适合从 Excel 直接复制出来的数据。
- XML转JSON转换器:同样是结构化数据换格式,但 XML 有属性与文本节点之分。
- YAML转JSON转换器:YAML 本身就有类型系统,不用推断。
- 开发者工具:查看全部开发者工具。