C# 读写 Excel 文件,别用 Microsoft.Office.Interop.Excel —— 它依赖本地 Office 安装、线程不安全、服务器部署极易崩溃,且性能差。
真正可靠、轻量、跨平台的方案是 EPPlus(.NET 5+ 推荐)或 NPOI(兼容 .NET Framework)。下面按实际使用场景分点说明。
EPPlus 读取 Excel:支持 .xlsx,不依赖 Office
EPPlus 5.x 仅支持 .NET Framework,6.x+ 要求 .NET 5 或更高版本,且默认禁用旧加密格式(如 Excel 97-2003 的 .xls) 读取时需注意:ExcelPackage.LicenseContext = LicenseContext.NonCommercial(开源版仅限非商业用途),商用必须购买许可证 工作表索引从 1 开始,不是 0;空行/列不会自动跳过,需手动判断
<code>worksheet.Cells[row, col].Value是否为
null示例:读取第一张表的 A1 单元格
using (var package = new ExcelPackage(new FileInfo("data.xlsx")))
{
var worksheet = package.Workbook.Worksheets[1];
var value = worksheet.Cells[1, 1].Value?.ToString();
}EPPlus 写入 Excel:避免 Save() 失败的常见原因
目标路径的父目录必须已存在,否则Save()抛出
DirectoryNotFoundException若文件已打开(比如被 Excel 进程占用),会抛出
IOException,建议加
FileShare.ReadWrite单元格赋值类型要匹配:写字符串用
.Value = "text",写日期用
DateTime类型,别传字符串
"2024-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"));NPOI 替代方案:需要兼容 .xls 或 .NET Framework 4.8
NPOI 支持.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。
