还在为 Excel 和 C# 对象之间的转换而头疼吗?据统计,80% 的 C# 开发在处理 Excel 数据时都遇到过这些痛点:手写繁琐的读取代码、复杂的格式转换、错误处理困难……


Install-Package Ganss.Excel// 仅需一行代码,Excel秒变对象集合!var products = new ExcelMapper("products.xlsx").Fetch<Product>();核心原理:ExcelMapper 自动匹配 Excel 列名与 C# 属性名(忽略大小写),无需额外配置!
publicclassProduct{ publicint id { get; set; } // 产品编号 publicstring Name { get; set; } // 产品名称 publicstring category { get; set; } // 类型 publicint qty { get; set; } // 数量 publicdecimal Price { get; set; } // 价格 [Column("创建日期")] public DateTime createdate { get; set; } // 创建日期 publicoverridestringToString() { return$"{Name},{category},{Price},{qty},{createdate}"; }}
注意:对于日期类型,一定在 Excel 中设置为 datetime 格式,否则可能解析失败。
[Column("价格")]publicdecimal Price { get; set; } // 价格[Column("创建日期")]public DateTime createdate { get; set; } // 创建日期实战提醒:当 Excel 列名与属性名不一致时,[Column] 特性是最佳选择!
publicclassProduct{ [Column(1)] publicint id { get; set; } // 产品编号 publicstring Name { get; set; } // 产品名称 [Column(Letter = "C")] publicstring category { get; set; } // 类型 publicint qty { get; set; } // 数量 [Column("价格")] publicdecimal Price { get; set; } // 价格 [Column("创建日期")] public DateTime createdate { get; set; } // 创建日期 publicoverridestringToString() { return$"{id},{Name},{category},{Price},{qty},{createdate}"; }}// 设置无表头模式var products = new ExcelMapper("products.xlsx") { HeaderRow = false}.Fetch<Product>();

using Ganss.Excel;using NPOI.SS.Formula.Functions;namespaceAppExcelMapper{publicclassPerson {publicstring Name { get; set; }public DateTime Birthday { get; set; }public Address Address { get; set; } // 嵌套对象 }publicclassAddress {publicstring Street { get; set; }publicstring City { get; set; }publicstring Zip { get; set; } }internalclassProgram {staticvoidMain(string[] args) {var customers = new ExcelMapper("user.xlsx").Fetch<Person>();foreach (var item in customers) { Console.WriteLine(item.Name + "," + item.Address.City); } } }}

这个比较好用了。。


以下是一个完整的工业管理示例,涵盖设备、计划、质检三大核心模块,并实现自动化报告生成:
using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Linq;using Ganss.Excel;namespaceAppExcelMapper{///<summary>/// 生产设备信息模型///</summary>publicclassProductionEquipment {publicint Id { get; set; } [Column("设备编号")]publicstring EquipmentCode { get; set; } [Column("设备名称")]publicstring EquipmentName { get; set; } [Column("设备类型")]publicstring Type { get; set; } [Column("生产线")]publicstring ProductionLine { get; set; } [Column("运行状态")]publicstring Status { get; set; } [Column("生产效率")] [DataFormat("0.00%")]publicdecimal Efficiency { get; set; } [Column("最后维护日期")]public DateTime LastMaintenanceDate { get; set; } [Column("下次维护日期")]public DateTime NextMaintenanceDate { get; set; } [Column("设备价值")] [DataFormat("¥#,##0.00")]publicdecimal Value { get; set; }publicoverridestringToString() {return$"{EquipmentCode} - {EquipmentName} [{Status}] 效率:{Efficiency:P2}"; } }///<summary>/// 生产计划模型///</summary>publicclassProductionPlan { [Column("计划编号")]publicstring PlanId { get; set; } [Column("产品编码")]publicstring ProductCode { get; set; } [Column("产品名称")]publicstring ProductName { get; set; } [Column("计划数量")]publicint PlannedQuantity { get; set; } [Column("已完成数量")]publicint CompletedQuantity { get; set; } [Column("开始日期")]public DateTime StartDate { get; set; } [Column("预计完成日期")]public DateTime ExpectedEndDate { get; set; } [Column("实际完成日期")]public DateTime? ActualEndDate { get; set; } [Column("负责人")]publicstring Supervisor { get; set; } [Column("优先级")]publicstring Priority { get; set; }publicoverridestringToString() {bool IsOverdue = DateTime.Now > ExpectedEndDate && ActualEndDate == null;return$"{PlanId} - {ProductName} 进度:{(PlannedQuantity > 0 ? (decimal)CompletedQuantity / PlannedQuantity : 0):P1} " +$"{(IsOverdue ? "[已延期]" : "")}"; } }///<summary>/// 质量检测记录模型///</summary>publicclassQualityInspection { [Column("检测编号")]publicstring InspectionId { get; set; } [Column("产品批次")]publicstring BatchNumber { get; set; } [Column("检测项目")]publicstring InspectionItem { get; set; } [Column("标准值")]publicdecimal StandardValue { get; set; } [Column("实测值")]publicdecimal ActualValue { get; set; } [Column("偏差")] [DataFormat("0.000")]publicdecimal Deviation { get; set; } [Column("检测结果")]publicstring Result { get; set; } [Column("检测员")]publicstring Inspector { get; set; } [Column("检测时间")]public DateTime InspectionTime { get; set; } [Column("备注")]publicstring Remarks { get; set; }publicoverridestringToString() {return$"{InspectionId} - {InspectionItem}: {Result} (偏差:{Deviation:F3})"; } }///<summary>/// 工业生产管理服务类///</summary>publicclassIndustrialManagementService {privatereadonlystring _dataPath;publicIndustrialManagementService(string dataPath = "Data") { _dataPath = dataPath; }///<summary>/// 导入设备信息///</summary>public List<ProductionEquipment> ImportEquipmentData() {try {var filePath = Path.Combine(_dataPath, "设备清单.xlsx");var equipments = new ExcelMapper(filePath).Fetch<ProductionEquipment>().ToList(); Console.WriteLine($"成功导入 {equipments.Count} 条设备信息");return equipments; }catch (Exception ex) { Console.WriteLine($"设备数据导入失败: {ex.Message}");returnnew List<ProductionEquipment>(); } }///<summary>/// 导入生产计划///</summary>public List<ProductionPlan> ImportProductionPlans() {try {var filePath = Path.Combine(_dataPath, "生产计划.xlsx");var plans = new ExcelMapper(filePath).Fetch<ProductionPlan>().ToList(); Console.WriteLine($"成功导入 {plans.Count} 条生产计划");return plans; }catch (Exception ex) { Console.WriteLine($"生产计划导入失败: {ex.Message}");returnnew List<ProductionPlan>(); } }///<summary>/// 导入质量检测数据///</summary>public List<QualityInspection> ImportQualityInspections() {try {var filePath = Path.Combine(_dataPath, "质量检测.xlsx");var inspections = new ExcelMapper(filePath).Fetch<QualityInspection>().ToList(); Console.WriteLine($"成功导入 {inspections.Count} 条质量检测记录");return inspections; }catch (Exception ex) { Console.WriteLine($"质量检测数据导入失败: {ex.Message}");returnnew List<QualityInspection>(); } }///<summary>/// 生成设备维护报告///</summary>publicvoidGenerateMaintenanceReport(List<ProductionEquipment> equipments) {try {// 筛选需要维护的设备var maintenanceNeeded = equipments .Where(e => e.NextMaintenanceDate <= DateTime.Now.AddDays(7)) .OrderBy(e => e.NextMaintenanceDate) .ToList();var reportPath = Path.Combine(_dataPath, $"维护计划_{DateTime.Now:yyyyMMdd}.xlsx");new ExcelMapper().Save(reportPath, maintenanceNeeded, "设备维护计划"); Console.WriteLine($"维护报告已生成: {reportPath}"); Console.WriteLine($"需要维护的设备数量: {maintenanceNeeded.Count}"); }catch (Exception ex) { Console.WriteLine($"维护报告生成失败: {ex.Message}"); } }///<summary>/// 生成生产进度报告///</summary>publicvoidGenerateProgressReport(List<ProductionPlan> plans) {try {// 添加进度分析var progressReport = plans.Select(p => new { p.PlanId, p.ProductName, p.PlannedQuantity, p.CompletedQuantity, p.Supervisor, p.Priority }).ToList();var reportPath = Path.Combine(_dataPath, $"生产进度_{DateTime.Now:yyyyMMdd}.xlsx");new ExcelMapper().Save(reportPath, progressReport, "生产进度报告"); Console.WriteLine($"生产进度报告已生成: {reportPath}"); }catch (Exception ex) { Console.WriteLine($"生产进度报告生成失败: {ex.Message}"); } }///<summary>/// 生成质量分析报告///</summary>publicvoidGenerateQualityReport(List<QualityInspection> inspections) {try {// 质量统计分析var qualityStats = inspections .GroupBy(i => i.InspectionItem) .Select(g => new { 检测项目 = g.Key, 总检测次数 = g.Count(), 平均偏差 = g.Average(i => Math.Abs(i.Deviation)), 最大偏差 = g.Max(i => Math.Abs(i.Deviation)) }).ToList();var reportPath = Path.Combine(_dataPath, $"质量分析_{DateTime.Now:yyyyMMdd}.xlsx");new ExcelMapper().Save(reportPath, qualityStats, "质量统计分析"); Console.WriteLine($"质量分析报告已生成: {reportPath}"); }catch (Exception ex) { Console.WriteLine($"质量分析报告生成失败: {ex.Message}"); } }///<summary>/// 创建示例数据文件///</summary>publicvoidCreateSampleDataFiles() {try { Directory.CreateDirectory(_dataPath);// 创建示例设备数据var sampleEquipments = new List<ProductionEquipment> {new ProductionEquipment { Id = 1, EquipmentCode = "EQ001", EquipmentName = "数控车床A1", Type = "数控设备", ProductionLine = "A线", Status = "运行中", Efficiency = 0.92m, LastMaintenanceDate = DateTime.Now.AddDays(-30), NextMaintenanceDate = DateTime.Now.AddDays(60), Value = 850000m },new ProductionEquipment { Id = 2, EquipmentCode = "EQ002", EquipmentName = "冲压机B1", Type = "冲压设备", ProductionLine = "B线", Status = "运行中", Efficiency = 0.88m, LastMaintenanceDate = DateTime.Now.AddDays(-45), NextMaintenanceDate = DateTime.Now.AddDays(5), Value = 620000m },new ProductionEquipment { Id = 3, EquipmentCode = "EQ003", EquipmentName = "焊接机器人C1", Type = "自动化设备", ProductionLine = "C线", Status = "维护中", Efficiency = 0.95m, LastMaintenanceDate = DateTime.Now.AddDays(-2), NextMaintenanceDate = DateTime.Now.AddDays(88), Value = 1200000m } };new ExcelMapper().Save(Path.Combine(_dataPath, "设备清单.xlsx"), sampleEquipments, "设备信息");// 创建示例生产计划数据var samplePlans = new List<ProductionPlan> {new ProductionPlan { PlanId = "P202401001", ProductCode = "PRD001", ProductName = "精密轴承", PlannedQuantity = 1000, CompletedQuantity = 850, StartDate = DateTime.Now.AddDays(-15), ExpectedEndDate = DateTime.Now.AddDays(5), Supervisor = "张工", Priority = "高" },new ProductionPlan { PlanId = "P202401002", ProductCode = "PRD002", ProductName = "连接器组件", PlannedQuantity = 2000, CompletedQuantity = 1200, StartDate = DateTime.Now.AddDays(-20), ExpectedEndDate = DateTime.Now.AddDays(10), Supervisor = "李工", Priority = "中" } };new ExcelMapper().Save(Path.Combine(_dataPath, "生产计划.xlsx"), samplePlans, "生产计划");// 创建示例质量检测数据var sampleInspections = new List<QualityInspection> {new QualityInspection { InspectionId = "QC001", BatchNumber = "B20240101", InspectionItem = "尺寸精度", StandardValue = 10.000m, ActualValue = 10.002m, Result = "合格", Inspector = "质检员A", InspectionTime = DateTime.Now.AddHours(-2) },new QualityInspection { InspectionId = "QC002", BatchNumber = "B20240102", InspectionItem = "表面粗糙度", StandardValue = 1.600m, ActualValue = 1.580m, Result = "合格", Inspector = "质检员B", InspectionTime = DateTime.Now.AddHours(-1) } };new ExcelMapper().Save(Path.Combine(_dataPath, "质量检测.xlsx"), sampleInspections, "质量检测"); Console.WriteLine("示例数据文件创建成功!"); }catch (Exception ex) { Console.WriteLine($"示例数据创建失败: {ex.Message}"); } } }///<summary>/// 主程序入口///</summary>classProgram {staticvoidMain(string[] args) { Console.WriteLine("=== 工业生产管理系统 - ExcelMapper 示例 ===\n");var service = new IndustrialManagementService();// 创建示例数据 Console.WriteLine("1. 创建示例数据文件..."); service.CreateSampleDataFiles(); Console.WriteLine();// 导入各类数据 Console.WriteLine("2. 导入设备信息...");var equipments = service.ImportEquipmentData();foreach (var equipment in equipments.Take(3)) { Console.WriteLine($" - {equipment}"); } Console.WriteLine(); Console.WriteLine("3. 导入生产计划...");var plans = service.ImportProductionPlans();foreach (var plan in plans) { Console.WriteLine($" - {plan}"); } Console.WriteLine(); Console.WriteLine("4. 导入质量检测数据...");var inspections = service.ImportQualityInspections();foreach (var inspection in inspections) { Console.WriteLine($" - {inspection}"); } Console.WriteLine();// 生成各种报告 Console.WriteLine("5. 生成管理报告..."); service.GenerateMaintenanceReport(equipments); service.GenerateProgressReport(plans); service.GenerateQualityReport(inspections); Console.WriteLine(); Console.WriteLine("\n=== 系统演示完成 ==="); Console.WriteLine("请检查 Data 文件夹中生成的报告文件!"); Console.ReadLine(); } }}


ExcelMapper 三大核心优势:
1、零配置启动 —— 约定优于配置,自动映射同名属性
2、灵活可扩展 —— 支持特性、代码、索引等多种映射方式
3、性能卓越 —— 基于 NPOI 纯托管库,无需 Office 环境
最佳实践建议:
优先使用约定映射,减少配置代码
大文件处理时设定行范围限制
生产环境务必加上异常处理
无论是快速原型开发,还是构建企业级工业管理系统,ExcelMapper 都能显著提升开发效率,让你专注于业务逻辑,而非 Excel 读写细节。
#ExcelMapper、C#、#Excel、#NPOI、#数据导入、#数据导出、#对象映射、#工业自动化、.NET、#模板填充
作者:技术老小子

Avalonia 工业级实战:从 PLC 通信到 Web HMI 的完整方案
一个值得收藏的 WinForms 界面框架:流式菜单 + 分割容器 + 多标签页
C# 做动态数据看板?这个 WinForms 多图表方案值得参考
C# 面向自动化产线上位机开源项目(支持报警、日志与多语言)
真正能落地的 .NET 8/9/10 企业平台:集成权限、流程引擎与实时通信
WPF 工业组态界面既专业又现代?HandyControl + ElementUI 风格
不玩虚的,这款开源 .NET 低代码平台,开箱即用流程引擎、BI 报表、权限控制
WPF 双模式工业温湿度监控上位机,支持独立运行与 MES 对接
WinForm 过时了?3月技术盘点:类IDE上位机、3D仿真与 Modbus调试工具
不靠框架,一套能用的 WinForm 企业人事管理系统(附源码)
基于 WinForms 实现多设备、多语言的 HMI 上位机框架
WPF 桌面也能做工业级看板?LiveCharts 让数据可视化更出彩
C# 统一工业 CAN 设备通信:跨平台、多厂商、高性能的通信库
WinForm + PLC + SQLite 的上位机项目,真的值得你收藏!
.NET 8 + WPF 做工业机器人3D仿真?HelixToolkit 真香
AI 辅助开发如何重塑 .NET 9 + WPF 企业级应用架构?
WinForm 自适应布局神器:告别手动计算,轻松实现专业界面
用 C# + WinForms 手撸一个轻量级矢量图绘制系统
WPF + MVVM 工业生产监控平台,用户控件动态加载与流畅动画实现
VisionMaster 通讯太麻烦?.NET 8 + TCP 为工业视觉定制的轻量通信方案
谁说 .NET 桌面过时了?AI 协作开发 WPF + SQLite 监控工具
觉得有收获?不妨分享让更多人受益
关注「DotNet技术匠」,共同提升技术实力



