C#读写Excel推荐EPPlus(.NET 5+)或NPOI(兼容.NET Framework),避免使用线程不安全、依赖Office安装的Interop;EPPlus需注意许可证、索引从1开始、空值判断;NPOI需注意流不关闭、行/单元格需手动创建;二者均不自动计算公式,文件需校验魔数防损坏。
C# 读写 Excel 文件,别用 Microsoft.Office.Interop.Excel —— 它依赖本地 Office 安装、线程不安全、服务器部署极易崩溃,且性能差。
真正可靠、轻量、跨平台的方案是 EPPlus(.NET 5+ 推荐)或 NPOI(兼容 .NET Framework)。下面按实际使用场景分点说明。
ExcelPackage.LicenseContext = LicenseContext.NonCommercial(开源版仅限非商业用途),商用必须购买许可证worksheet.Cells[row, col].Value 是否为 null
using (var package = new ExcelPackage(new FileInfo("data.xlsx")))
{
var worksheet = package.Workbook.Worksheets[1];
var value = worksheet.Cells[1, 1].Value?.ToString();
}Save() 抛出 DirectoryNotFoundException
IOException,建议加 FileShare.ReadWrite
.Value = "text",写日期用 DateTime 类型,别传字符串 "2025-01-01" 后指望自动识别Save() 前完成,且
ExcelPackage 对象操作var package = new ExcelPackage();
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
worksheet.Cells[1, 1].Value = "Hello";
worksheet.Column(1).Width = 15;
package.SaveAs(new FileInfo("output.xlsx"));.xls(HSSF)和 .xlsx(XSSF),但 HSSF 已停止维护,新项目一律用 XSSF
.xls 时若遇到 Invalid header signature,大概率是文件实际为 .xlsx 却用了 HSSFWorkbook
XSSFWorkbook 构造函数接收 Stream,但该流不能被关闭,否则后续读取报 ObjectDisposedException;推荐用 new MemoryStream(byteArray) 并设 leaveOpen: true
row = sheet.GetRow(0) ?? sheet.CreateRow(0); cell = row.GetCell(0) ?? row.CreateCell(0);
using (var fs = new FileStream("data.xlsx", FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous))
using (var workbook = new XSSFWorkbook(fs))
{
var sheet = workbook.GetSheetAt(0);
var cell = sheet.GetRow(0)?.GetCell(0);
var value = cell?.StringCellValue;
}EPPlus 和 NPOI 都不处理 Excel 公式计算结果(比如 =SUM(A1:A10) 只返回公式字符串,除非调用 EvaluateFormulaCell)。如果业务依赖实时计算值,要么预先把 Excel 用 Excel 打开另存为“值”,要么换用 ClosedXML(但它的公式支持也有限)。
另外,任何库都无法绕过 Excel 文件本身的损坏风险——上传文件前务必校验 ContentType 和魔数(如 .xlsx 开头应为 PK\x03\x04),否则解析时直接 InvalidDataException。