C# Excel转JSON工具源码:NPOI解析、类型推断与嵌套字段实战
发布时间:2026/10/20 12:44:43 锦皓数字建站

简介这是一份面向C#开发者与数据处理初学者的Excel转JSON工具源码包针对需要将结构化表格数据导入Web应用或NoSQL数据库的场景提供可直接运行的转换方案。压缩包共36个文件约193KB包含6个cs源码文件、3个exe可执行程序、2个dll与2个pdb调试文件以及csproj、sln、config、resx等工程配置与资源文件另附1个json示例与1个txt说明整体结构完整便于直接编译或二次开发。资源核心演示了通过OleDbConnection读取Excel、借助DataTable与JavaScriptSerializer完成序列化的完整链路并提示了.xls与.xlsx在连接字符串上的差异以及错误处理、性能优化、数据清洗等实践要点。目前已有936人学习下载适合希望掌握文件I/O与数据序列化、快速搭建转换工具的中级开发者参考。1. 从一份 Excel 配置表到 JSON为什么我劝你先别急着写解析器策划丢过来一个 200 行的 Excel要求当天转成 JSON 塞进 Unity 和前端两个项目里。多数人第一反应是打开在线转换网站或者随手写个StreamReader按逗号切分。我见过太多这样的脚本在遇到合并单元格、多级表头、单元格里带换行符时直接翻车最后排查半天发现是编码问题。这份 C# 实现的 Excel 转 JSON 工具加源码解决的正是这个场景把.xlsx按表头映射成结构化 JSON支持多 Sheet、类型推断和嵌套字段适合做游戏配置表、运营数据导入、前后端联调时的中间层。它不是玩具脚本而是一个能直接嵌进你现有 .NET 项目的可编译方案下面我按实际拆包顺序讲清楚怎么用、参数怎么调、坑在哪。2. 拆开这个工具C# 解析 Excel 的技术选型与目录结构2.1 为什么不用 OleDb 和 EPPlus 免费版C# 读 Excel 常见三条路OleDb、EPPlus、NPOI。OleDb依赖机器上装 Office 驱动服务器部署时经常报「未在本地计算机上注册 Microsoft.ACE.OLEDB.12.0」而且读.xlsx时对列类型推断极其玄学一列里混了数字和文本就整列变null。EPPlus从 5.0 起转商业授权公司项目里用着心里不踏实。这份源码选的是NPOI纯托管库不依赖 Office跨平台跑在 Linux 容器里也没问题读.xls和.xlsx用同一套 API对一线部署最省心。选型确定后整个工具的核心逻辑就三块工作簿加载、Sheet 遍历、单元格到 JSON 节点的映射。源码里把这三块拆成了独立类方便你只取其中一段塞进自己的项目。2.2 源码目录与关键类职责解压后主要看这几个文件文件职责你可能会改的地方ExcelReader.cs加载工作簿、遍历 Sheet 和行表头行号、起始行JsonBuilder.cs把行数据按表头拼成 JSON 对象嵌套分隔符、类型转换TypeInferer.cs推断单元格是数字、布尔还是字符串日期格式、空值策略Program.cs命令行入口接收路径参数批量处理逻辑ExcelReader里有个容易忽略的点它默认把第一行当表头但很多配置表前两行是标题和说明真正表头在第三行。源码里用HeaderRowIndex控制默认 0你改成 2 就能跳过前两行。这个参数不设对后面所有字段名全是「标题」「说明」这种废字段。2.3 环境准备与编译命令工具基于 .NET 6NPOI版本 2.6.1。如果你机器上只有 .NET Framework把TargetFramework改成net472也能编但NPOI要降到 2.5.6。恢复和编译命令如下# 进入源码根目录恢复 NuGet 包 dotnet restore # 编译 Release 版本输出到 bin/Release/net6.0 dotnet build -c Release # 直接运行传入 Excel 路径和输出目录 dotnet run --project ./ExcelToJson.csproj -- ./config.xlsx ./outputdotnet restore会拉NPOI和Newtonsoft.Json两个包国内源慢的话在NuGet.config里换个镜像。dotnet run后面的--是分隔符前面是 dotnet 参数后面才是传给程序的。很多人第一次用忘了这个--结果参数被 dotnet 自己吃掉程序报「未提供输入文件」。提示编译前确认NPOI包版本和TargetFramework匹配net6.0 配 2.6.1net472 配 2.5.6混用会在运行时抛FileLoadException。3. 把 Excel 映射成 JSON表头规则、类型推断与嵌套字段3.1 表头命名约定与多级表头处理这份工具对表头的解析规则很直接第一行每个非空单元格就是一个字段名支持用parent.child表示嵌套。比如表头写item.id、item.name、item.price生成的 JSON 就是{item: {id: 1, name: 剑, price: 100}}。多级表头如果写成两行合并单元格NPOI读出来第一行是「item」第二行是「id」工具会把它们拼成item.id前提是你在ExcelReader里把HeaderRowCount设为 2。实际配置表里经常出现同名字段比如两个 Sheet 都有id。工具默认按 Sheet 名做顶层键输出结构是{Sheet1: [...], Sheet2: [...]}。如果你想要扁平数组把WrapBySheetName设为false但这样多 Sheet 会合并成一个数组字段冲突时后面的覆盖前面的用之前想清楚。3.2 类型推断数字、布尔、日期的边界TypeInferer的推断顺序是先看单元格格式再看字符串内容。数字格式直接转double布尔格式转true/false日期格式转yyyy-MM-dd HH:mm:ss字符串。文本格式里如果内容是123它也会转成数字这是很多人踩坑的地方——ID 字段001会被转成1前导零丢失。解决办法是在表头加类型标记比如id:string工具看到:string后缀就强制按字符串处理。支持的标记有:string、:int、:float、:bool、:date。不写标记就走自动推断。我一般建议 ID、编号、手机号这类字段全部显式标:string省得后面联调时对不上。// TypeInferer.cs 核心推断逻辑节选 public static object Infer(ICell cell, string header) { // 表头带类型标记时优先按标记转换 if (header.Contains(:string)) return cell.ToString(); if (header.Contains(:int)) return (int)cell.NumericCellValue; // 无标记时按单元格类型走 switch (cell.CellType) { case CellType.Numeric: // 日期格式单独处理避免被当成数字 if (DateUtil.IsCellDateFormatted(cell)) return cell.DateCellValue.ToString(yyyy-MM-dd HH:mm:ss); return cell.NumericCellValue; case CellType.Boolean: return cell.BooleanCellValue; default: return cell.StringCellValue; } }这段代码里DateUtil.IsCellDateFormatted是关键不加这行日期会变成44927这种序列号。header.Contains判断类型标记时用的是简单包含所以字段名里别出现:string这种字样否则会被误判。3.3 空值、换行与特殊字符处理Excel 单元格里的换行符\n在NPOI里读出来是\n直接塞进 JSON 字符串会导致 JSON 解析失败。工具在JsonBuilder里做了转义把\n转成\\n转成\。但如果你在单元格里写了制表符或不可见字符转义逻辑覆盖不到生成的 JSON 看着正常前端JSON.parse就报错。我一般会在转换后加一步校验# 用 jq 校验生成的 JSON 是否合法 jq empty ./output/Sheet1.json # 不合法时 jq 会打印错误行号定位到具体字符空单元格默认输出null如果你希望空字符串就输出在JsonBuilder里把NullValueHandling改成EmptyString。这个参数在前后端联调时很关键前端如果没做null判断一个空单元格就能让页面白屏。注意合并单元格只有左上角有值其他位置读出来是空。工具不会自动填充合并区域需要你在 Excel 里先取消合并并补全数据或者在ExcelReader里加填充逻辑。4. 避坑排查转换失败、乱码与性能问题的五条血泪经验4.1 现象程序报「未找到可读的 Sheet」原因文件被占用或格式不对Excel 文件被 WPS 或 Office 打开时NPOI读会抛IOException提示文件被占用。解决方法是转换前确保文件关闭或者用FileShare.ReadWrite打开流using var fs new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); var workbook new XSSFWorkbook(fs);另一个原因是文件实际是.csv改了后缀成.xlsxNPOI按 xlsx 解析直接失败。用file命令或看文件头PK判断不是PK开头的就不是真 xlsx。4.2 现象中文变成乱码原因编码没指定或字体问题NPOI读.xls老格式时如果文件是 GBK 编码保存的读出来中文全是问号。解决办法是在HSSFWorkbook构造时传Encoding.GetEncoding(GBK)。.xlsx本身是 UTF-8一般不会乱码但如果单元格字体设了特殊符号集读出来可能缺字。这种情况在源文件里把字体改成「宋体」或「微软雅黑」再转。4.3 现象大文件转换内存暴涨原因一次性加载整个工作簿XSSFWorkbook会把整个文件读进内存10 万行以上的表能把 4G 内存吃满。NPOI提供了SXSSFWorkbook流式读但只支持写不支持读。读大文件常见做法是先用ExcelDataReader流式读成DataTable再逐行转 JSON。或者把大表拆成多个小 Sheet分批次转。我一般超过 5 万行就拆表别跟内存较劲。4.4 现象生成的 JSON 字段顺序和 Excel 不一致原因字典无序JsonBuilder内部用Dictionary存字段Dictionary不保证插入顺序生成的 JSON 字段顺序是乱的。如果下游依赖字段顺序比如做 diff 对比把Dictionary换成ListKeyValuePair或OrderedDictionary。Newtonsoft.Json序列化Dictionary时按哈希顺序输出这个坑在需要版本对比的场景里特别明显。4.5 现象布尔值TRUE被转成字符串原因单元格格式是文本Excel 里手动输入TRUE时如果单元格格式是「文本」NPOI读出来是字符串TRUE而不是布尔true。工具的类型推断只看单元格格式不看内容。解决办法是在表头标:bool强制转换。或者在 Excel 里把该列格式改成「常规」重新输入。5. 进阶把转换嵌进 CI 和自定义输出格式5.1 用命令行参数做批量转换Program.cs支持传入目录而不是单个文件它会遍历目录下所有.xlsx并输出到指定文件夹。批量转换时建议加--skip-empty跳过空 Sheet加--indent输出带缩进的 JSON 方便人工检查。完整参数dotnet run --project ./ExcelToJson.csproj -- \ ./configs \ # 输入目录 ./output \ # 输出目录 --skip-empty \ # 跳过空 Sheet --indent \ # 格式化输出 --header-row 2 # 表头在第 3 行这些参数在Program.cs里用CommandLineParser解析你可以照着加自己的参数比如--sheet-filter只转指定 Sheet。5.2 自定义输出从 JSON 到 C# 常量类很多项目转完 JSON 还要再写一层 C# 常量类手动写容易漏字段。工具留了一个IOutputFormatter接口实现它就能输出任意格式。下面这个实现把 JSON 转成 C# 的static readonly字段public class CSharpConstFormatter : IOutputFormatter { public string Format(string sheetName, JArray rows) { var sb new StringBuilder(); sb.AppendLine($public static class {sheetName}Config); sb.AppendLine({); foreach (JObject row in rows) { // 用第一列的值做字段名其余列拼成初始化表达式 var fieldName row.Properties().First().Value.ToString(); var values string.Join(, , row.Properties().Skip(1) .Select(p ${p.Name} {p.Value})); sb.AppendLine($ public static readonly object {fieldName} new {{ {values} }};); } sb.AppendLine(}); return sb.ToString(); } }这个格式化器输出的代码可以直接贴进 Unity 或服务端项目省掉手写常量类的时间。注意字段名如果含中文或特殊字符要自己做合法化处理C# 标识符不允许数字开头。5.3 验证转换结果三步检查法转完别急着交付我习惯走三步第一步用jq校验 JSON 合法性第二步用jq .[0]看第一条数据结构对不对第三步拿 Excel 里最复杂的那行带换行、带特殊字符、带空值单独比对。这三步走完基本能拦住 90% 的问题。从那以后我每次转完配置表都强制走一遍jq empty加首条数据抽查再也没出现过前端解析失败回头返工的情况。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。