☰
WinForm JSON转Excel工具源码:批量转换与嵌套扁平化实战
2026/10/13 7:31:27 网站建设 项目流程

简介:这是一份面向WinForm开发初学者与需要批量处理数据人员的JSON转EXCEL工具源码包,解决将JSON格式数据快速导出为Excel表格的实际需求,适合具备一定C#基础、希望学习数据解析与Office文件生成技巧的开发者参考。压缩包共61个文件,约192KB,以cs源码文件为主,配合exe可执行程序、config配置、manifest清单、resx资源、pdb调试符号及csproj工程文件等,结构完整,可直接在Visual Studio中打开编译运行。其中JsonCls.cs与ChangeToExcel.cs承担核心的JSON解析与Excel写入逻辑,Form1相关文件构成界面交互层,便于读者按模块阅读与二次修改。目前已有825人学习下载,说明该方案在同类需求中具有一定参考价值。通过这份源码,读者可以掌握JSON反序列化、数据映射到表格以及WinForm界面搭建的完整思路,并在此基础上扩展批量导入、字段自定义等实用功能。

1. 一个 WinForm 小工具,把 JSON 转 EXCEL 这件事彻底做成了桌面级操作

上周帮一个做数据对接的朋友处理一批接口返回的 JSON 文件,几百个文件堆在文件夹里,每个文件结构还不完全一样,有的字段多有的字段少,嵌套层级也不统一。他原本想用在线转换工具批量搞,结果要么限制文件大小,要么上传后字段顺序全乱,还有的直接把中文编码搞成了乱码。后来我翻出一个 WinForm 写的 JSON 转 EXCEL 小工具,带完整源码,双击运行、选文件、点转换,三秒钟出结果,字段顺序和嵌套结构都保留得清清楚楚。

这个工具解决的核心问题很明确:把 JSON 数组或 JSON 对象批量转成 Excel 能直接打开的表格文件,不需要装 Python、不需要配环境、不需要联网。适合经常跟接口数据打交道的后端、测试、数据分析人员,尤其是那些拿到一堆 JSON 日志或接口响应后要整理成报表的场景。源码基于 .NET Framework 的 WinForm 框架,用 C# 写的,Visual Studio 打开就能编译,想改字段映射规则或者加自定义格式化逻辑都很方便。

2. JSON 转 EXCEL 的底层逻辑:为什么不能直接字符串拼接

2.1 JSON 结构解析与表格扁平化策略

JSON 转 Excel 最核心的难点不是写文件,而是怎么把树形结构压成二维表。一个典型的接口返回可能是这样的:

{ "code": 200, "data": [ { "id": 1001, "name": "张三", "tags": ["VIP", "活跃"], "address": { "city": "北京", "district": "朝阳区" } } ] }

如果直接按最外层字段展开,data 是个数组,里面每个元素才是真正要导出的行。常见做法是递归遍历 JSON 节点,遇到数组就展开成多行,遇到嵌套对象就用“父字段_子字段”的方式拼列名。这个工具在源码里用了一个FlattenJson方法,核心逻辑是维护一个Dictionary<string, object>来存扁平化后的键值对,遇到嵌套对象就递归调用,遇到数组就判断元素类型——如果是对象数组就展开成多行,如果是简单值数组就用逗号拼接。

参数上有一个关键选择:数组元素是对象时,是每个对象单独成行,还是把整个数组序列化成字符串塞进一个单元格。这个工具默认走前者,因为大部分场景下接口返回的数组就是数据行。如果你遇到的是标签数组这种,可以在源码里改ArrayHandlingMode枚举,切成JoinAsString模式。

2.2 WinForm 界面与文件读写流程

整个工具的交互链路很短:主窗体上放一个TextBox显示选中的 JSON 文件路径,一个Button触发转换,一个DataGridView预览前若干行结果,最后用SaveFileDialog选 Excel 保存路径。源码里用的是Newtonsoft.Json做反序列化,用ClosedXML或者NPOI写 xlsx 文件——这两个库都不依赖 Office 安装,适合在内网或没装 Excel 的机器上跑。

读 JSON 的时候有一个容易翻车的点:文件编码。如果 JSON 文件是 UTF-8 带 BOM 的,用File.ReadAllText默认能处理,但如果是 GBK 编码的中文 JSON,直接读会乱码。源码里在读取时加了编码检测逻辑,先试 UTF-8,如果解析失败再试Encoding.Default。写 Excel 的时候,ClosedXML默认用 UTF-8,中文不会出问题,但列宽需要手动设置,否则导出的表格所有列都是一样宽,长文本显示不全。

// 读取 JSON 文件并处理编码 private string ReadJsonFile(string path) { byte[] bytes = File.ReadAllBytes(path); // 先尝试 UTF-8 解码 string content = Encoding.UTF8.GetString(bytes); // 如果解析失败,回退到系统默认编码 try { JToken.Parse(content); return content; } catch { return Encoding.Default.GetString(bytes); } }

这段代码的逻辑是先按 UTF-8 读,用JToken.Parse做一次语法校验,如果抛异常说明编码不对,再用系统默认编码重新读。参数上Encoding.Default在中文 Windows 上通常是 GBK,能覆盖大部分国产系统导出的 JSON 文件。

3. 从源码到可执行文件:编译、运行与批量转换实操

3.1 环境准备与项目编译

拿到源码包后,目录结构一般是这样的:一个.sln解决方案文件,一个 WinForm 项目文件夹,里面包含Form1.cs、Program.cs和packages.config。用 Visual Studio 2019 或 2022 打开.sln,如果提示缺少 NuGet 包,在解决方案上右键选择“还原 NuGet 包”,会自动下载Newtonsoft.Json和ClosedXML。

编译目标框架一般是.NET Framework 4.7.2或4.8,这两个版本在 Win10 和 Win11 上都自带运行时,不需要额外装。如果你用的是 Windows 7,可能需要手动装 .NET Framework 4.8 的运行时。编译时如果报ClosedXML版本冲突,检查packages.config里的版本号,常见做法是统一升到0.95.4以上,低版本对 xlsx 的样式支持有 bug。

# 如果用命令行编译,可以用 msbuild msbuild JsonToExcel.sln /p:Configuration=Release /p:Platform="Any CPU" # 编译产物在 bin\Release 目录下

命令行编译适合集成到自动化流程里,/p:Configuration=Release指定发布配置,生成的 exe 不依赖 VS 环境。注意Platform要跟解决方案里的一致,有些老项目只配了 x86,写Any CPU会报错。

3.2 单文件转换与批量处理

工具的主界面操作很直接:点“选择 JSON 文件”按钮,弹出一个OpenFileDialog,可以多选。选完后TextBox里会显示文件数量,点“开始转换”后,每个 JSON 文件生成一个同名的 xlsx 文件,默认保存在 JSON 文件所在目录。源码里用了一个BackgroundWorker来做异步转换,避免界面卡死,转换进度会显示在进度条上。

批量转换时有一个参数值得注意:是否合并所有 JSON 到一个 Excel 文件。默认是每个 JSON 单独一个 sheet,如果你有几百个文件,Excel 打开会很慢。源码里提供了一个MergeAllToSingleSheet的复选框,勾上之后所有 JSON 的数据行会追加到同一个 sheet 里,并在第一列加上来源文件名。这个功能在源码里的实现是维护一个List<DataTable>,最后用ClosedXML的AppendData方法一次性写入。

// 批量转换的核心循环 foreach (string jsonFile in jsonFiles) { string jsonContent = ReadJsonFile(jsonFile); JToken root = JToken.Parse(jsonContent); // 根据根节点类型决定解析策略 JArray dataArray = root is JArray ? (JArray)root : (JArray)root["data"]; DataTable table = FlattenToDataTable(dataArray); if (mergeAll) { table.Columns.Add("SourceFile", typeof(string)).SetOrdinal(0); foreach (DataRow row in table.Rows) row["SourceFile"] = Path.GetFileName(jsonFile); allTables.Add(table); } else { SaveToExcel(table, Path.ChangeExtension(jsonFile, ".xlsx")); } }

这段代码里root["data"]是一个硬编码的字段名,如果你的 JSON 根节点下不是data而是result或rows,需要改这个键名。更稳妥的做法是在界面上加一个输入框让用户填根节点路径,源码里预留了RootNodePath属性,默认值是"data"。SetOrdinal(0)把来源文件列挪到第一列,方便在 Excel 里筛选。

3.3 字段映射与自定义列顺序

默认情况下,工具按照 JSON 里字段第一次出现的顺序生成列。但实际业务里经常需要固定列顺序,比如先显示 ID、再显示名称、最后显示时间。源码里提供了一个ColumnOrder字符串数组,在Form1.cs的构造函数里可以改:

// 自定义列顺序,不在列表里的字段会追加到末尾 private string[] preferredOrder = new string[] { "id", "name", "create_time", "status" };

转换时FlattenToDataTable方法会先按preferredOrder里的字段名建列,然后再遍历 JSON 对象补充其他字段。如果 JSON 里字段名大小写不一致,比如Id和id混用,源码里用StringComparer.OrdinalIgnoreCase做了忽略大小写的匹配。这个细节在对接不同团队接口时特别有用,省得因为大小写问题多出两列空数据。

4. 避坑与排查:JSON 转 EXCEL 常见的五类翻车现场

4.1 转换后 Excel 打开报“文件格式无效”

现象:转换生成的 xlsx 文件用 Excel 打开时提示“文件格式或文件扩展名无效”,点“是”之后能打开但内容可能缺失。

原因:ClosedXML在写入时如果流没有正确关闭或释放,文件尾部会缺少必要的元数据。源码里如果用了using包裹XLWorkbook但中间抛了异常,流可能没 flush 完。

解决:确保SaveAs之后调用workbook.Dispose(),或者用using (var workbook = new XLWorkbook())包住整个写入过程。另外检查保存路径是否有中文或特殊字符,某些老版本ClosedXML对中文路径支持不好,换成英文路径测试。

4.2 嵌套层级过深导致列名爆炸

现象:JSON 嵌套了五六层,转换出来的 Excel 列名变成a_b_c_d_e_f这种超长字符串,列数上百,根本没法看。

原因:扁平化策略是递归拼接所有父级字段名,没有做深度限制。

解决:在源码里加一个MaxDepth参数,默认设 3 层,超过的层级直接序列化成 JSON 字符串塞进一个单元格。修改FlattenJson方法,传入当前深度,超过阈值就JsonConvert.SerializeObject整个子树。

4.3 日期字段变成一串数字

现象:JSON 里的"create_time": "2024-01-15T10:30:00"转换到 Excel 后显示成45306.4375这种数字。

原因:ClosedXML在写入时自动识别了日期格式,但单元格格式没设对,Excel 按数值显示了。

解决:在写入 DataTable 之前,把日期字符串转成DateTime类型,并在ClosedXML里设置cell.Style.DateFormat.Format = "yyyy-MM-dd HH:mm:ss"。如果不想自动转换,就把列类型设成string,强制按文本写入。

4.4 大文件转换内存溢出

现象:一个 200MB 的 JSON 文件,转换到一半程序崩溃,报OutOfMemoryException。

原因:JToken.Parse会把整个 JSON 加载到内存,加上 DataTable 和 Excel 工作簿,内存占用是文件大小的 5 到 10 倍。

解决:对于超大 JSON,改用流式解析。Newtonsoft.Json提供了JsonTextReader,可以逐条读取数组元素,每读一条就写一行到 Excel,不用一次性加载全部。源码里如果没做这个优化,可以自己加一个StreamingMode开关。

4.5 中文乱码但字段名正常

现象:Excel 里字段名是正常中文,但数据内容里的中文变成问号或方块。

原因:JSON 文件本身是 GBK 编码,但ReadJsonFile方法只试了 UTF-8 和Encoding.Default,而Encoding.Default在某些系统上不是 GBK。

解决:显式指定Encoding.GetEncoding("GBK")来读取,或者用Ude库做编码自动检测。更稳妥的做法是在界面上让用户手动选编码,源码里加一个ComboBox绑定Encoding.GetEncodings()。

5. 进阶玩法:把转换逻辑抽成类库,集成到自己的 WinForm 项目里

这个工具最大的价值不是 exe 本身,而是源码里的JsonToExcelConverter类。你可以把它抽出来编译成 DLL,直接在自己的 WinForm 或 WPF 项目里引用,不用重新造轮子。我一般会做三件事:第一,把FlattenToDataTable改成泛型方法,支持传入自定义的字段映射字典;第二,加一个ProgressChanged事件,方便在自己的界面上更新进度条;第三,把ClosedXML换成MiniExcel,后者写入速度更快,内存占用更低,适合数据量大的场景。

// 抽成类库后的调用示例 var converter = new JsonToExcelConverter(); converter.RootNodePath = "data"; converter.MaxDepth = 3; converter.ColumnOrder = new[] { "id", "name", "amount" }; converter.ProgressChanged += (sent, total) => { myProgressBar.Value = (int)(sent * 100.0 / total); }; converter.ConvertBatch(jsonFiles, outputDir, mergeAll: true);

这段调用里RootNodePath指定从哪个节点开始取数组,MaxDepth控制嵌套展开深度,ColumnOrder固定列顺序。ProgressChanged事件每处理完一个文件触发一次,sent是已处理数,total是总数。ConvertBatch的第三个参数mergeAll为true时所有数据合并到一个 sheet,为false时每个 JSON 单独一个文件。

验证转换结果是否正确,我习惯用一个小技巧:把原始 JSON 用jq命令统计行数和字段数,再跟 Excel 里的行数和列数对比。jq '.data | length'得到数组长度,jq '.data[0] | keys | length'得到第一行的字段数。如果 Excel 行数对不上,多半是数组展开逻辑有问题;如果列数对不上,检查嵌套对象是不是被漏掉了。

从那以后我每次拿到新的 JSON 数据源,都强制先用这个工具转一遍前 10 条看看结构,确认字段映射没问题再批量跑全量。希望帮到你。

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

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

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

立即咨询