使用方法
- 「CSV 源数据」默认已经写好四行,第一行是表头
name,score,note,第二行的备注里含一个被引号包裹的逗号,第三行的备注里含一对转义双引号。 - 「表头行数」默认 1,可填 0 到 2。填 0 表示源数据没有表头,工具会生成一行空表头;填 2 表示前两行都当表头,只取第二行作为列名。
- 「数值列判定阈值」默认 100,单位百分比。某一列的非空单元格里,能被解析成数字的比例不低于这个阈值,就判为数值列并右对齐。
- 「对齐方式」默认自动。选左、居中或右会覆盖自动判定,把全部列统一成一种对齐。
- 按 Ctrl+Enter(Mac 上 Cmd+Enter)或在上方任一输入框里按回车即可转换。
- 结果区第一行是主结果行数与列数,下面是可直接粘进 Markdown 的表格原文,最后一行统计转义了几处竖线、几处换行。
- 下方是二十行转义速查表,默认显示 12 行,点「加载更多」展开余下 8 行;「导出 CSV」存成带字节序标记的文件。
- 源数据为空、引号不闭合、各行列数不一致、表头行数超过总行数、两个数字输入越界或不是整数,都会给出写明行号或字段名与原因的具体提示。
这个CSV转Markdown表格工具能解决什么
把表格数据从 Excel 或数据库导出成 CSV 后,要放进 README、issue 或文档站点,就得改写成 Markdown 表格。手写的工作量不大,但转义规则繁琐:单元格里出现竖线会撑破列、出现换行会让表格断行、出现逗号又容易在二次编辑时出错。这一页做的是按 RFC 4180 把 CSV 正确切成行列,再按 GFM 的规则逐格转义输出。
第一类是日常的 README 表格。四行三列的源数据粘进来,输出 | name | score | note | 打头、第二行是分隔行,直接贴进 .md 文件就能渲染。score 这一列全是数字,自动判为数值列写成 ---:,其余列保持左对齐。
第二类是含特殊字符的数据。备注里写「含, 逗号」,如果不加引号,CSV 会把它切成两列;加了引号,本页解析后仍然是一个完整的单元格。备注里写「含"引号"」,源数据里必须写成两个连续双引号,本页解析时还原成一个——这一步最容易在二次编辑时被破坏,因此结果区会统计转义次数供核对。
第三类是排版细节。GFM 要求表头下方必须有分隔行,否则整段会被当成普通段落;单元格里的竖线要写成 \| 才能显示为字面竖线;单元格里的换行在表格里无法表示,只能换成 <br>。这三条规则本页全部自动处理。
还有一类边界要说清:本页只做格式转换与转义,不做数据校验,合并单元格、跨行表头、单元格内的 Markdown 语法都不在支持范围内。
计算原理与变量说明
解析部分是一个双状态扫描器:状态「在引号内」与「在引号外」。引号外的逗号结束当前字段、换行结束当前行;引号内两者都只是普通字符,唯一需要特殊处理的是连续两个双引号,它代表一个字面双引号。扫描结束后把最后一个字段与最后一行收尾,并丢弃文件末尾多余的空行。
为什么必须用状态机而不是 split。按逗号切分无法区分「字段分隔的逗号」与「字段内容里的逗号」。RFC 4180 规定后者必须整段用双引号包裹,只有维护「是否在引号内」这个状态才能正确还原字段。
| 变量 | 含义 | 取值 | 影响 |
|---|---|---|---|
| hd | 表头行数 | 0、1、2 的整数 | 决定哪一行当列名,0 时补空表头 |
| thr | 数值列阈值 | 0 ~ 100 的整数 | 非空数字占比达标即右对齐 |
| am | 对齐方式 | auto / left / center / right | 非 auto 时统一覆盖自动判定 |
| w | 表格列数 | 各行列数的最大值 | 短行补空,长行截断到表头列数 |
| iq | 引号状态 | true 表示处于引号内 | 解析结束时仍为 true 即引号不闭合 |
| n | 转义计数 | 非负整数 | 统计竖线与换行被替换的次数 |
输出只做三处改动。一是单元格里的竖线替换成 \|;二是换行(\n、\r\n、\r 都算)替换成 <br>;三是列宽统一,以表头列数为准,缺的补空、多的丢弃。其余原样保留,不做 trim。
对齐靠分隔行而不是单元格。GFM 的对齐写在表头下方那一行的冒号位置:左对齐 :---、居中 :---:、右对齐 ---:、不指定 ---。它管的是整列,所以「数值列右对齐」是给那一列的分隔格写 ---:,而不是给每个数字加空格。
数值列的判定用正则而不是 Number()。因为 Number("")、Number(" ")、Number("1,2") 在 JS 里的行为各不相同,直接用它判断会把空串和千分位写法误判成数字。本页用 /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/ 先做形状检查,只有形状合规才计入数值计数。
表头只能取一行。分隔行只有一行,多行列名在 GFM 里无法表达;表头行数填 2 时取第二行当列名,第一行丢弃,是为兼容导出时多带的一行标题。
完整示例(数值仅作演示)
默认源数据四行三列:表头 name,score,note,数据三行。第二行备注 "含, 逗号" 因含逗号而被引号包裹,解析后是一个单元格,内容为「含, 逗号」;第三行备注 "含""引号""" 里的两处连续双引号各还原成一个字面双引号,得到「含"引号"」。
源:name,score,note "含, 逗号" → 一个字段,内容是「含, 逗号」 "含""引号""" → 一个字段,内容是「含"引号"」 列判定:score 列 3 个非空值全部匹配数字正则 → --- 输出:| name | score | note | | --- | ---: | --- |
把「表头行数」改成 0,输出会在数据上方补一行空表头,数据仍是三行;改成 2,则取第二行当列名,第一行数据被丢弃。把阈值从 100 改成 60,score 列仍然 3/3 达标;若某列三个格子里只有两个是数字,占比约 66.7%,阈值 60 时判为数值列,阈值 100 时不判。
把「对齐方式」改成居中,全部列都会写成 :---:。源数据里填一行只有两个字段的记录,会提示第几行列数不符——这是 CSV 最常见的错误,二次编辑时最容易漏掉引号。
转义规则速查表
下表列出二十种单元格内容经过本页转义后的结果,由页面自己的转义函数逐格生成,可以直接对照。需要改写的只有竖线与换行两种字符,其余一律原样保留。
| 原始单元格 | 输出单元格 | 说明 |
|---|---|---|
| abc | abc | 普通文本不做任何改动 |
| a,b | a,b | 逗号来自引号内,转义阶段原样保留 |
| a"b | a"b | 双引号已在解析阶段还原成一个 |
| a\nb | a<br>b | 换行在表格里无法表示,转成 br 标签 |
| a|b | a\|b | 字面竖线必须转义,否则会多出一列 |
| 价格|数量 | 价格\|数量 | 表头里的竖线同样要转义 |
| 1\n2 | 1<br>2 | 两行文本合并成一个单元格 |
| 50% | 50% | 百分号不是特殊字符 |
| #3498DB | #3498DB | 井号只在行首才是标题 |
| 含,逗号和|竖线 | 含,逗号和\|竖线 | 两种特殊字符同时出现 |
| x | x | 前后空格原样保留 |
| (空) | (空) | 空字段输出为空单元格 |
第二张表给出对齐写法与列判定的对应关系,以及分隔行缺失时的后果。
| 写法 | 含义 | 适用列 |
|---|---|---|
| --- | 不指定对齐 | 默认,渲染器自行决定 |
| :--- | 左对齐 | 文本列 |
| :---: | 居中 | 短枚举值 |
| ---: | 右对齐 | 数值列 |
| 无分隔行 | 整段不渲染为表格 | 检查表头下是否漏了这一行 |
结果边界、舍入与适用说明
- 源数据整段为空时提示「CSV 源数据这一栏是空的」,不会输出空白表格;清空后点「转为表格」会自动填回示例。
- 双引号不闭合时提示「第几行的双引号没有闭合」,并指出缺少的是收尾引号——多数情况是二次编辑时删多了一个引号。
- 各行列数不一致时提示「第几行有 N 个字段,与表头的 M 个不一致」,不自动补空,避免把错位的数据悄悄塞进错误的列。
- 表头行数必须是 0 到 2 的整数,且不能超过源数据总行数,否则提示具体是越界还是超行数。
- 数值列阈值必须是 0 到 100 的整数,填小数或越界会分别给出提示;阈值 0 表示只要有一个数字就右对齐。
- 转义只处理竖线与换行两种字符,不做 trim,也不处理反斜杠本身,因此源里已有的反斜杠会原样出现在输出中。
- 本页只做格式转换,不支持合并单元格、跨行表头与单元格内的 Markdown 语法。
- 页面不联网、不写本地存储;导出的 CSV 带字节序标记,Excel 打开不乱码。
常见问题
为什么不能直接按逗号切分?
因为 RFC 4180 允许字段内容里含逗号,只要整段用双引号包裹即可。按逗号切分无法区分这两种逗号,会把一个字段拆成两列。
字段里的双引号为什么要写两个?
因为双引号本身是包裹符。要在内容里表示一个字面双引号,就得写成连续两个,解析器在引号内遇到两个连续双引号时还原成一个。这是 RFC 4180 的规定,不是本页自创。
单元格里的换行会怎样?
会被转成 br 标签。GFM 表格的每一行必须写在一行文本里,物理换行会终止整个表格,所以只能用 br 标签表达单元格内的软换行。
数值列是怎么判出来的?
统计该列非空单元格中能被数字正则匹配的比例,比例不低于阈值就判为数值列。阈值默认 100,表示整列必须全是数字才右对齐。
分隔行是什么,漏了会怎样?
是表头下方那一行由连字符与可选冒号组成的行。GFM 靠它判定上面那行是表头、下面是数据;漏掉它,整段会被当成普通段落原样显示。
能把制表符分隔的数据粘进来吗?
不能。本页只认 RFC 4180 的逗号分隔格式;制表符分隔的数据会被当成普通字符留在同一格里。请先在表格软件里另存为 CSV。
生成结果能在哪些地方渲染?
GitHub、GitLab、多数静态站点生成器与常见 Markdown 编辑器都支持 GFM 表格语法。少数老式解析器不支持对齐冒号,此时分隔行会被忽略但表格仍能显示。
输入的数据会上传到服务器吗?
不会。解析、转义、拼表与导出全部在本页 JavaScript 里完成,没有发起任何网络请求,刷新即恢复默认示例。
相关工具
- CSV转JSON转换器:同一份源数据换成 JSON 结构。
- Markdown表格生成器:手工逐格录入生成表格。
- ASCII表格生成器:终端与纯文本场景的表格画法。
- HTML格式化:把表格再转成 HTML 标签形式。
- JSON格式化工具:整理 JSON 后再与本页结果对照。
- 开发者工具:查看全部开发者工具。