使用Apache POI读取带保密标签Excel时遇ZipEntry大小异常
问题概述
使用Apache POI读取来自OneDrive、带有保密标签的.xlsx文件时,创建XSSFWorkbook实例时抛出java.util.zip.ZipException: invalid entry size (expected 0 but got 1053 bytes)异常,替换POI Jar包后问题仍存在。
相关代码片段:
FileInputStream fis = new FileInputStream(new File("test.xlsx")); XSSFWorkbook workbook = new XSSFWorkbook(fis);
报错栈信息:
Exception in thread "main" java.io.IOException: Failed to read zip entry source
at org.apache.poi.openxml4j.opc.ZipPackage.(ZipPackage.java:103)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:324)
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:37)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.(XSSFWorkbook.java:295)
at ReadingData.TestClass.main(TestClass.java:31)
Caused by: java.util.zip.ZipException: invalid entry size (expected 0 but got 1053 bytes)
at java.base/java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:399)
at java.base/java.util.zip.ZipInputStream.read(ZipInputStream.java:198)
at org.apache.poi.openxml4j.util.ZipSecureFileThresholdInputStream.read(ZipSecureFile.java:228)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:186)
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource$FakeZipEntry.(ZipInputStreamZipEntrySource.java:132)
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.(ZipInputStreamZipEntrySource.java:56)
at org.apache.poi.openxml4j.opc.ZipPackage.(ZipPackage.java:109)
... 4 more
原因分析
OneDrive的保密标签基于Microsoft信息保护(MIP)机制,会对文件进行加密或附加特殊元数据,导致文件不再是标准的ZIP压缩格式(.xlsx本质是ZIP包),Apache POI的Zip解析器无法识别这种修改后的结构,从而抛出Zip格式异常。
解决方案
1. 移除文件保密标签后读取
如果业务允许,先在OneDrive中移除文件的保密标签:
- 打开OneDrive网页端或本地同步文件夹,右键文件选择「信息」
- 在「保护」选项中移除保密标签,保存后重新下载文件
- 再用原有代码读取处理后的文件
2. 通过Microsoft Graph API获取解密流
利用Graph API直接获取解密后的文件内容流,绕过本地文件的加密格式问题:
// 示例:通过Graph API获取解密后的文件输入流(需自行实现身份验证和API调用) InputStream decryptedStream = getDecryptedFileStreamFromGraph("your-file-id"); XSSFWorkbook workbook = new XSSFWorkbook(decryptedStream);
需要配置Graph API的Files.Read权限,并完成OAuth2身份验证,确保API有权限读取解密后的内容。
3. 使用MIP SDK解密文件
借助Microsoft Information Protection SDK解密带标签的文件,得到标准.xlsx文件后再用POI读取:
- 引入MIP SDK依赖(可通过Maven/Gradle配置)
- 初始化MIP上下文,加载对应的保护策略
- 将加密文件解密到临时目录,再用
FileInputStream读取临时文件
4. 验证文件完整性
- 检查OneDrive同步是否完成,避免读取同步中的临时文件
- 重新下载文件,确认本地文件能正常用Excel打开(若无法打开,说明文件已损坏,需重新获取)
内容的提问来源于stack exchange,提问作者Sayandip Ghatak

