手头有一段 JSON 对象数组,想转成 Markdown 表格贴到 README 或文档里。最稳的路径不是直接 JSON 转表格,而是先转成 CSV,再过一遍 CSV to Markdown 工具。直接转的工具也有,但一旦数据里混了嵌套结构或缺失字段,输出就容易乱,而且很难定位是哪一列出了问题。中间夹一层 CSV,列和行的对应关系可以直接用眼睛检查,结果可控得多。
下面从结构确认开始,讲 CSV 转换、表格生成、API 响应处理、嵌套 JSON 的应对,一步步走完。所有处理都在浏览器内完成,API 响应或内部数据贴进来也不会发到任何服务器。
结论:JSON 经过 CSV 转 Markdown 表格
先给整体流程。
- 用 JSON Formatter 格式化 JSON,确认是对象数组。
- 把数组转成 CSV——每个对象的键变成列头,每个元素变成一行。
- 把 CSV 贴到 CSV to Markdown,生成表格。
FormatArc 没有"一键 JSON 转表格"的按钮。把格式化工具和 CSV 转换工具组合起来用,得到的 GFM 兼容表格在任何渲染器上都不会错位。CSV 作为中间格式的好处是:列错位或值缺失,你当场就能看出来。
什么样的 JSON 适合转 Markdown 表格
Markdown 表格是"列头 + 数据行"的二维网格。所以最适合转表格的 JSON,就是结构一致的对象的数组。
[
{ "name": "Mika", "role": "admin", "active": true },
{ "name": "Noah", "role": "viewer", "active": false }
]
每个对象的键(name、role、active)对应列头,数组里每个元素对应一行。上面这段 JSON 对应的表格:
| name | role | active |
| --- | --- | --- |
| Mika | admin | true |
| Noah | viewer | false |
反过来,如果只是一个裸对象(没有包在数组里的 { ... }),它本身构不成多行。要么转成键值两列表格,要么用 [ { ... } ] 包成数组再转。
步骤:把 JSON 转成 Markdown 表格
第 1 步:格式化 JSON 并确认结构
从 API 响应或日志里拿出来的 JSON 经常是一长串没有换行的文本。先贴进 JSON Formatter 格式化,肉眼确认两件事:确实是对象数组,每个元素持有相同的键。
有语法错误的话,后面的转换全都会卡住。缺了右花括号、多了尾逗号(trailing comma),先修掉。// 之类的注释不是标准 JSON,混进来了也得删掉。
第 2 步:把数组转成 CSV
结构确认没问题之后,把数组改成 CSV 格式。要做的事就两件:
- 第一行写键,逗号分隔,当列头
- 每个对象的值按相同顺序逗号分隔,一行一个
上面那段 JSON 转出来就是:
name,role,active
Mika,admin,true
Noah,viewer,false
值里面如果含有逗号或换行符,用双引号 "..." 把那个值包起来。CSV 的基本写法见什么是 CSV。反过来想把 CSV 转回 JSON,逻辑是对称的。
第 3 步:用 CSV to Markdown 生成表格
CSV 准备好了,贴到 CSV to Markdown 运行。


右侧输出 GFM 兼容的 Markdown 表格,分隔行和列宽自动对齐。直接复制就能贴到 GitHub README、Issue、PR 描述或技术文档里。转换的机制和边界情况,在CSV 转 Markdown 表格的完整指南里有详细说明。
API 响应的 JSON 转表格
用 curl 调了 API,想把响应整理成表格共享给同事,场景很常见。流程和上面一样:格式化响应,转 CSV,生成表格。
curl -s https://api.example.com/users | jq .
响应本身是对象数组的话,直接贴进 JSON Formatter 格式化,然后从第 2 步继续。如果响应外层包了一层,比如 { "data": [ ... ] },就只取要转表格的那段数组(data 里面的内容)。用 jq 的话,jq '.data' 就能把数组抽出来。
curl 响应本身的格式化,jq、Python、CLI、浏览器 4 种做法见curl JSON 格式化 4 种方法。专门针对 curl 响应的表化工作流(认证头、分页、按 6 种响应结构分难度)见API 响应 JSON 转 Markdown 表格。
嵌套 JSON 怎么处理
实际 API 响应里,值里面再套一层对象或数组是很常见的事。
[
{ "name": "Mika", "address": { "city": "Tokyo", "zip": "100-0001" } }
]
Markdown 表格是二维的,嵌套结构没法原样塞进一个单元格。应对方式有两个。
扁平化后转表格
把嵌套的键展开成点号记法(dot notation),比如 address.city,变成一层结构再转 CSV。
name,address.city,address.zip
Mika,Tokyo,100-0001
数据量少的时候手动改也行。量大就用工具:jq 的 to_entries,或者 Python 的 pandas.json_normalize()。扁平化之后,跟前面一样走 CSV 转表格。
嵌套值作为字符串放进单元格
不扁平化,把嵌套的那部分序列化成一段 JSON 字符串,整个放进一个单元格。address 列的值就是 {"city":"Tokyo","zip":"100-0001"} 这样的字符串。
这种情况下,字符串里如果有管道符 | 或换行,表格会断。在 CSV 阶段用双引号把值包好就行。CSV to Markdown 会自动把单元格内的管道符转义为 \|,换行替换为空格,所以贴的时候不用额外处理。
指定列对齐
GFM 表格在分隔行里加冒号 : 可以控制每列的对齐方式。
| name | count |
| :--- | ---: |
| Mika | 12 |
| Noah | 340 |
:---— 左对齐(默认):---:— 居中对齐---:— 右对齐
数值列右对齐,位数对齐了读起来舒服。但注意,对齐标记能否生效取决于渲染端。GitHub 上正常,其他平台不一定。对齐、转义等记法的细节见Markdown 表格语法。
常见问题
每个元素的键不一样
数组里有的元素多一个键,有的少一个。列怎么定?取所有元素键的并集,缺值的地方就是空单元格。只取第一个元素的键,后面元素独有的键就丢了。建议在写 CSV 之前就定好列,否则输出不稳定。
布尔值、null、数值
true、false、null 和数字写到 CSV 里就是纯文本。在 Markdown 表格里也以字符串形式显示,语义上没问题。空值渲染为空单元格。
单元格内的换行和管道符
值里混了换行或 |,会跟列分隔符冲突,表格直接断。CSV 阶段用双引号包好,CSV to Markdown 会安全处理。
常见问题解答
需要把 JSON 上传到服务器吗?
不需要。FormatArc 所有转换都在浏览器本地运行。贴进去的 API 响应、内部数据不会发送到任何服务器。
为什么要经过 CSV?
CSV 作为中间格式,列头和每行的对应关系一目了然。JSON 直接转表格,嵌套或缺字段把结果搞乱了,你不知道是哪列出了问题。中间加一层 CSV,错位当场就能修。
嵌套 JSON 能直接进表格吗?
不能原样进。要么用点号记法扁平化(address.city),要么把嵌套部分序列化成 JSON 字符串放进一个单元格。具体操作见上面"嵌套 JSON 怎么处理"一节。
用代码转 JSON 到 Markdown 表格
浏览器工具之外,如果你需要在脚本、CI 流水线或文档自动生成里完成这个转换,下面几种方式都可以用。输入都是扁平的对象数组,输出都是 GFM 兼容表格。
Python(tabulate)
from tabulate import tabulate
data = [
{"id": 1, "name": "Mika", "role": "admin"},
{"id": 2, "name": "Noah", "role": "viewer"},
{"id": 3, "name": "Sofia", "role": "editor"},
]
print(tabulate(data, headers="keys", tablefmt="pipe"))
tablefmt="pipe" 输出 GFM 管道表格。想显式写对齐行的话用 tablefmt="github"。安装:pip install tabulate。
JavaScript / Node.js(tablemark)
import tablemark from "tablemark";
const data = [
{ id: 1, name: "Mika", role: "admin" },
{ id: 2, name: "Noah", role: "viewer" },
{ id: 3, name: "Sofia", role: "editor" },
];
console.log(tablemark(data));
tablemark 直接接收对象数组,输出 GFM 管道表格。安装:npm install tablemark。
Shell(jq + FormatArc CLI)
不想引运行时依赖,一行管道搞定:
curl -s https://api.example.com/users \
| jq -r '(.[0] | keys_unsorted) as $k | $k, (.[] | [.[$k[]]]) | @csv' \
| npx formatarc csv-to-markdown
jq 取第一个对象的键作为列头行,其余数据以 CSV 形式输出。formatarc csv-to-markdown 从 stdin 读 CSV,stdout 输出 Markdown 表格。CI 里用 Makefile 从 API 响应重新生成 README 表格段落时很方便。这里用的 CLI 是 formatarc npm,不装额外二进制,npx 一行就能在终端跑。
Markdown 表格的局限与何时切 HTML
Markdown 表格的语法是故意保持简单的。数据超出这个范围时,别硬撑,直接在 Markdown 里写 HTML <table>。
| 需求 | Markdown 表格 | HTML <table> | 建议 |
|---|---|---|---|
单元格合并(colspan / rowspan) | 不支持 | 支持 | HTML |
| 单元格内换行 | 行内 <br> | 原生支持 <br> | HTML 或行内 <br> |
| 100 行以上大数据量 | 取决于渲染器 | 轻量 | HTML 或分页 |
| 作为 LLM 上下文 | 适合(token 效率高) | 标签冗余 | Markdown |
| GitHub README 显示 | 适合 | 取决于渲染器 | Markdown |
| 左/中/右以外的对齐 | 不支持 | 行内样式可实现 | HTML |
| 无表头表格 | 不自然(仍需分隔行) | 支持 | HTML |
GitHub、Obsidian、Notion(块导入)和大多数静态站点生成器都接受 Markdown 文档里的原生 HTML。需要合并单元格或可排序表头时,手写 <table> 或用模板引擎从 JSON 生成后嵌入,都是可行方案。反方向,已有的 HTML 表格要转回 Markdown 表格时,管道符、换行、列错位的自动处理见HTML 表格转 Markdown 表格。
总结
把 JSON 转成干净的 Markdown 表格,最短路径就是经过 CSV。用 JSON Formatter 确认结构,把数组转成 CSV,贴进 CSV to Markdown,GFM 兼容表格直接可复制。嵌套数据、API 响应这些不那么直接的场景,加一步扁平化就能走通同样的流程。
生成的 Markdown 表格如果要传给 LLM 做上下文,比 HTML 表格省 token,提取也更干净。实测对比见LLM 输入用 Markdown 还是 HTML。