JSON 转 Excel:展平分层数据的原理与局限
将 JSON 文件转换为 Excel(XLSX)表格,本质是把树状的分层结构强制映射为扁平的二维表。页面收到一个 JSON 文件后,自动执行展平操作:对象键成为列标题,数组中的每个对象成为一行,嵌套键用点路径(dot‑path)拼接(例如 address.city)。最终输出一个只含静态数据的 XLSX 文件,不保留公式、单元格样式或多工作表。
JSON 结构与展平规则
JSON 原生支持对象({})、数组(``)、数字、布尔值、字符串和 null。这些元素可以任意嵌套,而 Excel 工作表的每个单元格只承载一个值,且整张表是行与列的二维矩阵。展平规则的唯一目的是将嵌套的层级摊平,以便用单张工作表容纳数据。
- 对象数组:当 JSON 是一个对象数组时,每个对象成为一行。所有对象中(包括嵌套键)的所有键的集合定义了列标题。算法递归遍历每个对象:
- 对于每个键值对,如果值是原始类型(字符串、数字、布尔值、null),则将其写入属于该键点路径的单元格。
- 如果值是另一个对象,算法会递归,并用每个子键扩展点路径。
- 如果值是原始类型数组,它会成为一个包含该数组 JSON 表示的单个单元格——例如,`` 作为字符串。
- 如果一个对象缺少在其他对象中出现的键,则缺少的单元格留空。Null 值也成为空单元格。
例如
[{"name": "张三", "address": {"city": "北京"}}]→ 列名为name、address.city,值为张三、北京。
- 数组的数组:如果顶层 JSON 是一个数组的数组(例如
[ [1, "x"], [2, "y"] ]),每个内部数组成为一行,并且不生成标题行——第一个内部数组就是工作表的第一行。不会发生嵌套数组的展平,因为没有键可以连接。 - 混合类型:顶层数组甚至可以混合对象与其他值:任何非对象的元素都放在名为
value的列中(数组作为其 JSON 文本放在那里)。 null与空值:JSON 中明确写为null的字段在 XLSX 中输出为空单元格;缺失字段同理。
这种展平方式的代价是:原本在一个对象内并列的多个嵌套对象,会被拆散到多列。例如 {"a": {"x": 1}, "b": {"y": 2}} 变成 a.x 和 b.y 两列,语义上不再属于同一层级,但保留了完整的路径信息。
数据类型映射:JSON 到 XLSX
CSV 格式将所有数值和布尔值转为字符串,而 XLSX 原生支持数字、布尔、日期等数据类型。该工具利用这一优势:
| JSON 类型 | XLSX 单元格类型 | 示例 |
|---|---|---|
| 数字 | 数字(Number) | 123.45 → 123.45 |
| 布尔值 | 布尔(Boolean) | true → TRUE |
| 字符串 | 文本(String) | "hello" → "hello" |
| null | 空 | 空单元格 |
这意味着一列数字在 Excel 中仍然是数字。你可以对其求和、格式化或在公式中使用,而无需转换字符串。一列布尔值显示为 TRUE/FALSE,Excel 可以在逻辑函数中使用。这是 JSON 到 CSV 工作流的实际优势,因为在 CSV 中布尔值会变成字符串 "true" 或 "false"。
但需注意:如果一个字段在不同行中包含混合类型(例如,一行是数字,另一行是字符串),工具会以其自己的类型写入每个单元格。Excel 将在同一列中存储数字和文本单元格的混合。大多数电子表格应用程序都能很好地处理这种情况,但数据透视表和某些公式可能会出现意外行为。
输入要求:为什么必须是“表格形状”
该工具期望“表格形状”的 JSON 输入。实际上,这意味着顶层值应该是一个对象数组或一个数组的数组。单个对象也被接受——它会转换为一个单行表格。
- 有效输入示例:
[{"id": 1}, {"id": 2}](对象数组)[[1, "a"], [2, "b"]](数组的数组)
- 无效输入示例:
{"name": "foo"}(顶层不是数组,但单个对象是有效输入,会转换为单行表格)[{"a":1},](JSON 语法错误,例如尾随逗号)
不符合条件时,页面会提示“This JSON is invalid or not table‑shaped.”。
边界情况与错误提示
工具在转换过程中会检查若干条件,并给出明确的错误信息。所有处理均在浏览器端完成,因此文件大小和转换时长受限于用户机器性能。已知错误提示包括:
- “Choose a CSV, JSON or XLSX file.”——选了其他类型文件时。
- “This file is too large. Use a file under ‹max›.”——超出大小限制(最大 8 MB)。
- “This JSON is invalid or not table‑shaped.”——JSON 解析失败或结构不合要求。
- “This file has no table rows.”——数组为空。
- “This table has more than ‹max› rows.”——输出表格超出 10,000 行上限。
- “This table has more than ‹max› columns.”——输出表格超出 200 列上限。
- “Conversion cancelled.”——用户主动中止。
- “这次转换耗时太久,请换一个更小的文件。”——处理超时(超过约 12 秒)。
转换后,页面会显示预览表格(前 8 行和 8 列)、行数和列数,以及输出文件的大小。
XLSX 格式的局限性
XLSX 是一个 ZIP 包内的 XML 文件集合,可以储存公式、样式、多张工作表等。然而,本工具的输出文件只包含一个工作表,且只写入静态数据。这意味着:
- 不计算公式。 即使 JSON 包含表达式(不太可能),它们也被视为文字字符串。
- 无单元格样式。 没有粗体标题,没有列宽,没有字体选择。第一行成为标题行(包含点路径键),但没有视觉区分。
- 生成单个工作表,名为 Sheet1。没有选项可以将 JSON 分割成多个工作表或添加元数据。
如果需要多工作表或特定格式化,必须通过 Excel 或其他程序手动处理输出的文件。
隐私与客户端处理
页面完全在浏览器中运行,JSON 文件不会被上传到任何服务器。所有解析、展平、生成 XLSX 的操作均由 JavaScript 在用户本地完成。这对于处理敏感数据(如 API 响应中的个人信息、业务配置)至关重要——文件本身不会离开用户的设备。
FAQ
Q:为什么我的 JSON 里有数组,但转换后只有一行?
A:如果一个对象包含对象数组,该数组不会被展开成单独的行。相反,整个数组被字符串化为 JSON 并放置在单个单元格中。例如,{"id": 1, "items": [{"sku": "A"}, {"sku": "B"}]} 会生成一个包含 id 和 items 列的单行。items 单元格包含 [{"sku":"A"},{"sku":"B"}] 作为字符串。
Q:转换后列名出现 address.city 这样的点,能否去掉?
A:不能。因为 JSON 对象可以嵌套。扁平的电子表格列需要一个单一的名称。点路径是标题中表示层次结构的标准方式。
Q:输出 XLSX 中数字显示为文本该怎么办?
A:如果源 JSON 数字被引号包裹(例如 "123"),则视为字符串。请检查 JSON 中数值是否使用数字字面量(无引号)。工具会原样输出类型。
Q:Excel 打开后看到 ### 符号,是数据丢失了吗?
A:不是。### 表示列宽不够,只需手动拖动列宽或双击列分隔线即可显示完整内容。数据本身未丢失。
Q:为什么我传了一个很大的文件,页面冻结了?
A:所有处理在浏览器主线程进行,超大文件会导致界面无响应。请尝试分割成小文件,或使用更快的机器。工具内部也有超时保护,会提示“这次转换耗时太久,请换一个更小的文件。”。
Q:能否支持 CSV 或 XLSX 的输入?
A:该页面只接受 JSON 输入。