使用C#的NPOI访问带敏感标签限制的Excel文件报错
EOF in header错误 使用C#结合NPOI访问带有敏感标签限制的Excel文件时,触发如下错误:
ICSharpCode.SharpZipLib.Zip.ZipException: 'EOF in header'
at ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputBuffer.ReadLeByte()
at ICSharpCode.SharpZipLib.Zip.ZipInputStream.SkipUntilNextEntry()
at ICSharpCode.SharpZipLib.Zip.ZipInputStream.GetNextEntry()
at NPOI.OpenXml4Net.Util.ZipInputStreamZipEntrySource..ctor(ZipInputStream inp)
at NPOI.OpenXml4Net.OPC.ZipPackage..ctor(Stream in1, PackageAccess access)
at NPOI.OpenXml4Net.OPC.OPCPackage.Open(Stream stream, Boolean readOnly)
at NPOI.Util.PackageHelper.Open(Stream stream, Boolean readOnly)
at NPOI.XSSF.UserModel.XSSFWorkbook..ctor(Stream fileStream, Boolean readOnly)
用户提供的写入文件代码如下:
using (FileStream fs = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write)) { var contentType = workbook.GetProperties().CoreProperties.ContentType; workbook.Write(fs); }
错误原因
带敏感标签的Excel属于受信息保护的加密Office文件,NPOI默认的Zip解析逻辑无法处理这种加密结构,直接读取会导致Zip头部解析失败,触发EOF错误。另外,若写入文件时未正确刷新缓冲区或流未正常关闭,可能导致文件损坏,后续读取时也会出现该错误。
解决方案
处理加密文件:转存为未加密格式
带敏感标签的Excel需要先解密,可借助Microsoft.Office.Interop.Excel将文件另存为普通xlsx格式,再用NPOI读取:using Microsoft.Office.Interop.Excel; var excelApp = new Application(); var encryptedWorkbook = excelApp.Workbooks.Open(tempFilePath); // 若文件有密码,添加Password参数:Password: "your-password" encryptedWorkbook.SaveAs("unencrypted_file.xlsx", XlFileFormat.xlOpenXMLWorkbook); encryptedWorkbook.Close(); excelApp.Quit(); // 读取转存后的文件 using (var fs = new FileStream("unencrypted_file.xlsx", FileMode.Open, FileAccess.Read)) { var workbook = new XSSFWorkbook(fs); // 执行后续业务操作 }修正写入逻辑:避免文件损坏
确保写入时强制刷新缓冲区,使用FileMode.CreateNew避免覆盖不完整文件:using (FileStream fs = new FileStream(tempFilePath, FileMode.CreateNew, FileAccess.Write)) { workbook.Write(fs); fs.Flush(); // 强制将缓冲区内容写入磁盘 }注意:如果workbook本身是从加密文件读取的损坏实例,需先解决读取环节的问题再写入。
升级依赖库
旧版本NPOI依赖的SharpZipLib对加密Zip的处理存在缺陷,升级到最新稳定版NPOI(2.6.2及以上),新版本可能优化了受保护Office文件的解析逻辑,或更换了更可靠的Zip处理组件。
内容的提问来源于stack exchange,提问作者Harini Muralidharan

