如何使用Java org.apache.poi处理带打开密码和编辑密码的xlsx文件
基于Apache POI处理双重密码保护XLSX文件的实现方案
XLSX的两层密码对应两类保护逻辑:第一层是文件级加密保护(即打开密码),第二层是编辑权限保护(即编辑密码,可作用于工作簿或单个工作表)。你之前的代码仅处理了第一层文件解密,操作受编辑保护的内容时就会抛出异常,按以下步骤处理即可:
1. 完成第一层文件打开密码解密
你已跑通的逻辑可保留,参考代码如下:
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.crypt.EncryptionInfo; import org.apache.poi.poifs.crypt.Decryptor; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.io.InputStream; // 第一层:解密文件打开密码 POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("你的文件路径.xlsx")); EncryptionInfo encryptionInfo = new EncryptionInfo(fs); Decryptor decryptor = Decryptor.getInstance(encryptionInfo); if (!decryptor.verifyPassword("你的打开密码")) { throw new RuntimeException("文件打开密码校验失败"); } InputStream decryptedInputStream = decryptor.getDataStream(fs); XSSFWorkbook workbook = new XSSFWorkbook(decryptedInputStream);
2. 处理第二层编辑密码校验与保护解除
编辑密码分为工作簿级和工作表级两类,根据你的保护场景对应处理:
2.1 工作簿级编辑保护处理
如果是限制工作簿结构修改(比如新增/删除工作表)的保护,用以下代码处理:
// 校验并解除工作簿编辑保护 if (workbook.isWorkbookProtected()) { if (!workbook.validateWorkbookProtectionPassword("你的编辑密码")) { throw new RuntimeException("工作簿编辑密码校验失败"); } // 解除保护后即可正常编辑工作簿结构 workbook.removeWorkbookProtection(); }
2.2 工作表级编辑保护处理
如果是限制单元格内容修改的工作表保护,遍历所有工作表处理即可:
import org.apache.poi.xssf.usermodel.XSSFSheet; for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) { XSSFSheet sheet = workbook.getSheetAt(sheetIndex); if (sheet.getProtectSheet()) { if (!sheet.validateSheetProtectionPassword("你的编辑密码")) { throw new RuntimeException("工作表《" + sheet.getSheetName() + "》编辑密码校验失败"); } // 解除保护后即可正常编辑单元格内容、调整行/列格式 sheet.removeSheetProtection(); } }
注意事项
- 若仅需读取文件内容无需修改,不需要解除第二层编辑保护,可直接读取单元格内容,不会触发异常
- 若使用POI 5.x版本,部分校验方法名可能存在微调,比如
validateSheetProtectionPassword在部分小版本中为verifySheetProtectionPassword,可参考你引入版本的官方API文档调整 - 建议使用POI 4.1.2及以上版本,低版本对双重密码保护的XLSX文件兼容性存在已知缺陷
内容的提问来源于stack exchange,提问作者Andie
相关产品推荐
相关产品推荐

