Excel与JSON互转全攻略:从嵌套映射到类型处理
2026/9/9 12:15:18 网站建设 项目流程

简介:Excel与JSON互转工具主要面向开发人员、数据分析师以及需要频繁处理表格和结构化数据的办公人群,用于解决两种数据格式之间批量转换效率低下的问题;工具同时支持从JSON转换到Excel和从Excel转换到JSON。对于JSON中常见的嵌套对象和数组,可以展开为多级表头,或者拆分到多个工作表;对于包含多个工作表的Excel文件,转换后能够生成对应的JSON数组,同时数值、日期、布尔值等数据类型都会按JSON规范自动适配,避免格式错乱。资源压缩包内共有2个文件,一个Java源代码和一个可直接运行的exe程序,整体大小仅1.92MB。用户既可以双击exe文件快速完成日常转换,也可以查看Java源码理解实现细节,甚至进行二次开发。目前已有454人学习使用,对于接口联调、报表整合、数据迁移和日常办公中的Excel与JSON互转场景,都能有效减少手工复制粘贴和格式调整的时间消耗,是一份轻量实用的小工具。 等了这么长时间才写这篇,是因为“Excel Json 互转工具”这个标题我在搜索框里见过太多次了。每次搜出来的不是要上传文件、还得担心隐私的网页,就是装完发现只能处理单个工作表、嵌套结构一碰就废的小软件。与其等别人把坑踩完,不如我把这几年做数据迁移和接口对接时攒下来的互转经验完整写出来。这篇不讲那些“一键转换”的漂亮话,只讲真实场景下表格和JSON之间到底该怎么转、为什么这么转、以及哪些位置最容易翻车。

1. 表头、行、和JSON对象的对应关系,是“互转”的第一步

一说“Excel Json互转工具”,大部分人的第一反应是:把Excel文件拖到一个页面上,点一下按钮,就能拿到一个整齐的JSON文件。这种工具确实存在,但我做了多年数据处理后越来越觉得,如果只靠这种“一键转换”,十次里有八次拿回来的是不能直接用的数据。

原因其实不在“转换”这个过程,而是在“映射”这个前置步骤。Excel长着一张二维表格,JSON长着一棵带嵌套的树。用一句话概括两者差异:Excel的强项是让你看到每一行每一列的整齐页面,JSON的强项是表达对象和对象之间的包含关系。这两种结构天然就不是一一对应的。而在实际项目中,最常见的对应关系又很固定:

  • 一个工作表对应一个JSON数组
  • 工作表里除表头外的每一行,对应数组中的一个JSON对象
  • 表头单元格是对象的key
  • 单元格值是对应的value

最直观的一次经历,是帮一个团队做数据提取。对方发来一个十几列、几千行的Excel表,丢给我一个接口文档,文档里要求POST一个数组,每个元素有八个字段,其中两个还是嵌套对象,比如address.cityaddress.zip。如果直接把Excel每一行转成一个扁平JSON对象,接口方那边必定报“missing field”之类的错误,因为嵌套的address对象根本没有生成。

所以从那个需求之后,我经手的所有Excel Json互转工具,第一步都不是写代码,而是先画一张映射图:Excel里哪一个sheet对应JSON顶层哪个字段,哪一行哪一列又对应嵌套对象的哪个key。映射图画清楚,后面的代码只是把这个图落地而已。这个“图”完全可以做成可配置的,比如JSON结构的字段层级等于Excel表头的点分式名称,这样工具才能适应不同接口。很多人把互转失败的锅甩给工具,其实锅往往在映射约定没定清楚。先把这一点想透,再谈用什么工具,才算有方向。

2. 正向转换怎么做:一条命令导出一套能直接用的 JSON

2.1 先约定一个“谁都能看懂”的输出结构

正向转换就是Excel到JSON。我推荐用这种结构作为默认输出:

{ "员工表": [ { "工号": "A001", "姓名": "张三", "薪资": 8000 }, { "工号": "A002", "姓名": "李四", "薪资": 9500 } ], "部门表": [ { "部门ID": "D01", "部门名称": "技术部" } ] }

一个sheet生成一组数据,表头当作key。这样不管下游是接口、数据库还是数据分析脚本,都能一眼看出数据来源。如果你只需要其中某个工作表,也可以输出成纯粹的数组,不要把sheet层带进去,要看目标系统预期什么形态。

2.2 我封装的转换脚本骨架

直接用pandas读写Excel比自己逐行解析容易得多,前提是把几个参数控好。

import json import pandas as pd # dtype=str 是防止手机号、工号、订单号被当成数字 df_dict = pd.read_excel( "input.xlsx", sheet_name=None, dtype=str, keep_default_na=False ) result = {} for sheet_name, df in df_dict.items(): result[sheet_name] = df.to_dict(orient="records") with open("output.json", "w", encoding="utf-8") as f: json.dump(result, f, ensure_ascii=False, indent=2)

这段代码做了一件极其关键的事:所有单元格先按字符串读入,避免Excel把“00123”这种编号变成123。等到JSON阶段,真正需要数值的字段再用int()、float()做二次转换。如果你不加这个dtype,早晚有一天会被“0001丢失前导零”这种事坑一次。

有人可能觉得这样太啰嗦,不如直接用DataFrame的to_json。to_json确实快,但它的输出默认包含索引,日期会变成时间戳,对阅读不友好。实际做数据对接时,我更愿意自己控制输出结构。输出JSON记得加上ensure_ascii=False,否则中文全变成\u5f20\u4e09,调试接口的时候根本看不出哪个字段对应哪个值。

2.3 日期、公式和合并单元格,不预处理一定会翻车

Excel里的公式单元格,如果用openpyxl直接读,默认拿到的是公式字符串,而不是计算后的值。在互转场景里,除非你要做表格工具本身的数据迁移,否则多数情况要的是“最终显示值”。pandas在read_excel时会自动读取缓存的计算结果,这是好事。但如果你用openpyxl直接逐行读,就要注意取cell.value时可能拿到的是=SUM(A1:A10)

日期列同样需要小心。pandas会把日期读成datetime对象,json.dump会直接报错,因为原生JSON不支持日期类型。我的处理方式是先统一转字符串,同时保留显示格式:

for col in df.columns: if pd.api.types.is_datetime64_any_dtype(df[col]): df[col] = df[col].dt.strftime("%Y-%m-%d") elif pd.api.types.is_timedelta64_dtype(df[col]): df[col] = df[col].astype(str)

合并单元格在read_excel中通常只有左上角有值,其他位置是空值。如果你希望合并区域每个单元格都输出同一个值,必须先对Excel做反向填充。这个没有现成捷径,我是用openpyxl先遍历merged_cells.ranges,再把范围内的值统一回填,最后再转DataFrame。这类非典型数据,正则替换解决不了,只能先预处理。

3. 反向转换才是重头戏:JSON 变成 Excel 会遇到四种“不听话”

正向转换大多数通用工具都能做,因为Excel的结构相对固定。反向转换才是一堆人搜“JSON转Excel为什么失败”的根源。

3.1 嵌套对象:先压平还是拆成多张表?

一份JSON经常长这样:

{ "users": [ { "id": 1, "name": "张三", "address": { "city": "上海", "zip": "200000" } } ] }

address嵌套了一个对象。常见做法是用pandas.json_normalize把嵌套对象摊平成列名address.cityaddress.zip,再写Excel。对于两层嵌套,这个办法非常高效。

import pandas as pd data = { "users": [...] } df = pd.json_normalize(data["users"]) df.to_excel("output.xlsx", index=False)

但如果嵌套深度超过三层,或者同一字段在不同记录里类型不一样(这次是对象,下次是字符串),json_normalize很容易给出意料之外的列组合。更稳的方案是:把每个嵌套对象单独拆成一张子表,比如users表和addresses表,通过id关联。这样结构客户能理解,后期想做数据分析也方便。不能一概而论哪种更优,只能看下游需求。

3.2 数组字段:一个 JSON 数组不是 Excel 的一个格子

JSON里的数组,比如tags: ["开发", "Java", "后端"],没法原样塞进一个单元格。通常有两条路:一是拆成多列,比如tags_1tags_2;二是用逗号或分号拼接成一个字符串,放进一个单元格。如果你以后要把这个Excel再导回数据库,多列方案更友好;如果只是给人看,拼接更好读。两条路都行,但代码里必须明确决定,不能靠工具默认行为。

顺带提一个我在Excel里转JSON数组字段时用的技巧:如果数组是字符串数组,我会把整列当作一个字符串,用json.loads解析后再考虑拆分或保持数组。这样能避免Excel单元格里那种前后带空格、换行符的脏数据直接混进JSON。

3.3 null、布尔值和大数字,最容易在“转换成功”时埋雷

JSON的null,在不同工具里可能变成空字符串,也可能变成文本“null”。Excel单元格本身有“是否为空”的状态,所以我的约定是:null一律写成空单元格,不要填字符串。JSON的true/false,在Excel里对应布尔值,但有些互转工具会输出“True”“False”的字符串,这在数据清洗时很恼人。我自己的做法是读取的时候先把字符串型"true""false"还原成Python布尔值,再交给DataFrame。

大数字是另一个坑。JSON里的数字超过JavaScript安全整数范围时,很多在线工具会丢精度,因为浏览器端JS先处理一步。你要导出的可能是雪花ID或身份证号,如果转出来变成1.2345678e+19,数据已经废了。所以我在处理这类字段时,先读取为字符串,再根据字段名决定是否转数字。

3.4 文件编码:为什么有时打开 CSV 全是乱码

如果你反向转换后直接写了一个UTF-8编码的CSV或文本,双击Excel打开很可能乱码,因为Excel对UTF-8的支持,尤其在Windows环境,并不那么“无感”。解决办法是写入编码为UTF-8 with BOM,也就是Python里的encoding="utf-8-sig"。如果写的是xlsx,通常用pandas/openpyxl没有乱码问题。但一旦用了CSV方案,就一定记得加BOM。“为什么我转出来的文件乱码”这类搜索高频出现,多半就是少了这一步。

4. 为什么不直接用在线互转工具,而是自己写脚本

网上搜“Excel Json互转工具”,能搜到一大把在线转换器。最初我也用过,用得不太满意,原因可以拿来说说。

方案能处理多sheet吗能自定义嵌套吗数据隐私适合场景
在线转换网站多数不行基本不行数据要传服务器临时、脱敏数据
Excel自带的Power Query + JSON可做,但配置繁琐能,但学习成本高本地处理个人日常清洗
自己写的Python脚本完全可控完全可控本地处理重复交付、接口对接

在线工具最大的问题不是功能,而是它把“转换”做成了一个黑盒。你拿到结果后,不知道它为什么这样处理空值、不知道它怎么处理数字精度、也不知道它是否偷偷丢掉了某些列。在单次转换少量数据时无所谓,但一旦你要交付给客户或者录入数据库系统,你没办法解释结果里为什么少了一行。

于是我自己写了一个小工具。这个工具不需要界面,一条Python命令,输入文件、指定sheet名、输出JSON,完成。麻烦是麻烦了点,但每次跑出来的结果都可复现,这是在线工具给不了的。如果你不想碰代码,我再推荐一个折中方案:Power Query。Excel自带的Power Query可以把JSON当作数据源导入,并且能通过界面操作调整嵌套层级。但Power Query的JSON解析对数组支持得好,对深层内嵌对象支持得不够直观,遇到schema不稳定的JSON,写完步骤后很容易报未找到列。所以我觉得,在线工具适合一次性的小规模操作;Power Query适合长期维护的报表数据流;Python脚本则适合需要精确可控的接口对接和数据交付。

5. 如果要做成一个正规的小工具,字段映射、空值策略和类型转换得这么设计

5.1 用映射表代替硬编码列名

我常遇到的情况是:Excel的列头叫“员工姓名”,但JSON接口要求的字段是employee_name。这种差异如果靠改Excel表头,每接一个新需求就改一次文件,不现实。更好的办法是做一个映射表:

field_map = { "员工姓名": "employee_name", "入职时间": "hire_date", "薪资": "salary" }

转换时,遍历Excel每一列,如果列头在映射表里,就输出为映射后的key;不在映射表里的列可以选择忽略还是原样输出。映射表还可以支持类型转换,比如“薪资”字段统一转float,这样就把转换逻辑从具体表格中剥离开来,变成可配置的规则。

5.2 空值策略三选一,但不要混用

一个Excel数据源里,空单元格到底要不要出现在JSON里,我认为应该由下游决定。如果下游要求字段齐整,那空值输出null;如果下游用Python的dict.get访问字段,那字段缺失也不影响,反而更省空间。我发现很多报错,比如failed to deserialize the json body into the target type: missing field,就是序列化时缺了Excel里的某一列,而输入方又要求该字段必须存在。这种问题,责任不在数据也不在工具,而在转换时没有把“空值”明确成null而不是“不输出该字段”。

所以在设计工具时,我加了一个空值策略参数:missingnullempty_string三选一。默认使用null,适配大多数接口契约。

5.3 做完转换之后,必须做一次类型抽样

做互转工具最容易掉以轻心的环节,是类型确认。Excel单元格看起来是“123”,实际可能是文本,也可能是数字;JSON里的“1.00”转回Excel也分分钟变成“1”。因此我的建议是,在工具转换之后,加一道“抽查”步骤:随机挑两三行,肉眼核对字段类型,再拿一份目标系统的示例JSON做diff。别嫌麻烦,数据转换的事故大多是最后交付时才发现。

6. 顺手再加这几个能力,互转的闭环才算完整

在我自己的版本里,后续又加了几个实用功能,这里一并分享:

  • 按sheet选择性导出。只转指定的几个sheet,而不是全部。
  • 行列过滤。比如某列的值等于某个条件才输出该行。
  • 嵌套层级控制。用parent.child这样的列头,在正向转换时生成嵌套JSON,而不是摊平结构。
  • Excel模板生成。拿到一份JSON样例,自动生成对应的Excel模板,带好表头,下游的人填完数据再导回JSON,形成闭环。

尤其是最后一点,很多团队都在做“Excel填报->JSON入库”的流程,本质就是先根据JSON字段生成Excel模板,再让业务人员填单,最后程序回读。这个闭环一旦跑通,小团队也能在没有任何后台界面的情况下实现数据采集。

嵌套层级控制的实现也不复杂,只需要在读取表头时按.拆分:

def build_nested(records): nested = [] for row in records: obj = {} for key, value in row.items(): parts = key.split(".") tmp = obj for p in parts[:-1]: tmp = tmp.setdefault(p, {}) tmp[parts[-1]] = value nested.append(obj) return nested

这段代码不处理数组,但已经能覆盖大多数“两三层嵌套”的接口结构。如果遇到数组嵌套,就需要配合额外配置,判断当前字段是对象还是数组。我在实际项目里是单独维护了一份字段结构描述文件,类似JSON Schema,字段层级和类型都写清楚。

这也是为什么我坚持不推荐一个“什么都能转”的万能工具:结构越复杂,约定就要越明确,否则表面上转成功了,其实没有人敢真正使用那份输出。如果你也在做Excel和JSON的互转,我建议先别着急找工具,拿出一张真实的表,摘出最麻烦的一列,想清楚它转到JSON后应该是什么形态,再用我上面说的方式去写自己的脚本。工具从来都不是问题本身,数据映射才是。用坏过几次在线工具之后,我现在的原则是:本地能跑通的事,绝不上传第三方平台;手上有一份可复现的脚本,比什么“智能转换工具”都可靠。以后每遇到一种奇怪格式,就往脚本里补一条规则,慢慢你会发现,它已经变成你自己最顺手的私有数据转换器。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询