epplus报“file is not a valid ooxml file”主因是版本与格式不匹配:5.x不支持.xls,6+需为.xlsm显式启用宏;npoi写日期需手动设dataformat;epplus保存出错多因关系损坏或复用workbook;无office时,epplus轻量但限.xlsx/.xlsm,npoi全格式兼容但api冗余。

EPPlus读取Excel时提示“File is not a valid OOXML file”
这个错误通常不是文件损坏,而是EPPlus版本与Excel文件格式不匹配。EPPlus 5.x 及更早版本不支持 .xls(Excel 97-2003)格式,只支持 .xlsx/.xlsm/.xltx;而 EPPlus 6+ 默认禁用宏支持,打开含宏的 .xlsm 文件会直接报该错。
- 确认文件扩展名是
.xlsx或.xlsm,不是.xls(后者必须换用 NPOI) - 如果是 .xlsm,EPPlus 6+ 需显式启用宏支持:
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;(仅限非商业用途)或设置new ExcelPackage(new FileInfo(path)) { ThrowIfCorrupted = false } - 检查文件是否被 Excel 进程独占锁定——常见于调试时未调用
package.Save()就关闭了程序,残留句柄导致下次读取失败
NPOI写入日期类型单元格显示为数字而非日期格式
NPOI 不会自动应用日期格式,它把 DateTime 写成 OLE 自动化日期序列值(如 45123 表示某天),但单元格样式仍是常规格式,所以 Excel 显示为整数。
- 必须手动设置单元格数据格式:
cell.CellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("yyyy-mm-dd"); - 注意:NPOI 的
DataFormat是字符串模板,不是 .NET 的ToString("yyyy-MM-dd"),也不能用"m/d/yyyy"这类简写(Excel 不识别),推荐用"yyyy-mm-dd"或"yyyy-mm-dd hh:mm:ss" - 如果写入的是
DateTime.Now但显示为 0,大概率是时区或DateTimeKind问题——NPOI 期望本地时间,传入DateTime.UtcNow且未调整会出错
EPPlus保存文件后Excel提示“发现不可读的内容”
这基本是包内关系(Relationship)损坏或内容类型(Content Type)声明不一致,多发生在手动修改 Worksheet 的 Drawings、Comments 或插入图片后未正确关联。
- 避免直接操作
worksheet.Drawings集合,改用worksheet.Drawings.AddPicture()等封装方法 - 若需插入图片,务必使用
package.Workbook.Properties.Creator = "YourApp";初始化文档属性,否则某些 Excel 版本校验失败 - 保存前调用
package.Workbook.CalculateFormulas();(如有公式),否则公式缓存不一致也会触发警告 - 不要在
using (var package = new ExcelPackage(fileInfo))外部保留对package.Workbook的引用并试图复用——EPPlus 的 Workbook 对象不是线程安全的,跨作用域易引发内部状态错乱
在无Office环境部署时如何选库:NPOI vs EPPlus
两者都不依赖 COM 组件,但设计哲学和适用边界明显不同。
- EPPlus 更轻量、API 更现代,适合纯 .xlsx/.xlsm 场景,但 6.0+ 商业授权收紧——若项目用于企业内网系统且不发布到公网,可继续用 5.8.7(MIT 协议,GitHub 上仍可下载)
- NPOI 支持全格式(.xls, .xlsx, .docx, .pptx),适合需要兼容老旧 Excel 文件或混合办公文档的场景,但 API 较底层,设置样式、合并单元格等需更多样板代码
- 注意运行时依赖:EPPlus 6+ 要求 .NET 5+;NPOI 5.x 支持 .NET Framework 4.6.1+ 和 .NET Core 3.1+,但若用 .NET 6+ 且需处理加密 Excel(.xlsx 密码保护),NPOI 目前不支持 AES 加密,只能读取无密码或 RC4 加密的老文件
真正麻烦的从来不是“能不能读写”,而是日期格式、合并单元格跨行逻辑、公式计算上下文、以及 Excel 自己对空行/空列的隐式截断行为——这些细节不会报错,但导出结果和用户预期差一格,就得花半天对齐。










