我们如何使用 POI API 读取受保护的密码 excel 文件 (.xls)
-
05-07-2019 - |
题
我刚刚学习了 POI,发现 HSSF 的读取和创建 excel 文件(.xls)非常简单。但是,当我想读取受密码保护的Excel时,我发现了一些问题。我花了一个小时在互联网上找到这个解决方案。
请你帮我解决这个问题。如果您能给我一个代码片段,我非常高兴。
谢谢。
解决方案
POI 将无法读取加密内容 作业簿 - 这意味着如果您保护了 全部的 工作簿(而不仅仅是一张工作表),那么它将无法读取它。否则,它应该有效。
其他提示
看 http://poi.apache.org/cryption.html - 如果您使用的是足够新的 Apache POI 副本(例如 3.8),则可以解密加密的 .xls 文件 (HSSF) 和 .xlsx 文件 (XSSF)(证明您拥有密码!)
目前您无法写出加密的 Excel 文件,只能写出未加密的文件
这是一个完整的示例代码,它读入受保护的 Excel 文件,使用密码解密并写出不受保护的 Excel 文件
public static void readProtectedBinFile() {
try {
InputStream inp = new FileInputStream("c:\\tmp\\protectedFile.xls");
org.apache.poi.hssf.record.crypto.Biff8EncryptionKey.setCurrentUserPassword("abracadabra");
Workbook wb;
wb = WorkbookFactory.create(inp);
// Write the output to a file
FileOutputStream fileOut;
fileOut = new FileOutputStream("c:\\tmp\\unprotectedworkbook.xlsx");
wb.write(fileOut);
fileOut.close();
} catch (InvalidFormatException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
在您写下问题时,使用 Apache POI 并不容易。从那时起,支持已经取得了长足的进步
如今,如果您想打开受密码保护的 Excel 文件,是否 .xls
或者 .xlsx
, ,您知道密码,您所需要做的就是使用 WorkbookFactory.create(文件,密码), ,例如
File input = new File("password-protected.xlsx");
String password = "nice and secure";
Workbook wb = WorkbookFactory.create(input, password);
这将识别文件的类型,使用给定的密码对其进行解密,然后为您打开它。然后您就可以正常阅读内容了
这是读取 Excel 文件的代码,检查 .xls 和 .xlsx(有密码保护或没有密码保护)作为完整的示例代码。
private Workbook createWorkbookByCheckExtension() throws IOException, InvalidFormatException {
Workbook workbook = null;
String filePath = "C:\\temp\\TestProtectedFile.xls";
String fileName = "TestProtectedFile.xls";
String fileExtensionName = fileName.substring(fileName.indexOf("."));
if (fileExtensionName.equals(".xls")) {
try {
FileInputStream fileInputStream = new FileInputStream(new File(filePath));
workbook = new HSSFWorkbook(fileInputStream);
} catch (EncryptedDocumentException e) {
// Checking of .xls file with password protected.
FileInputStream fileInputStream = new FileInputStream(new File(filePath));
Biff8EncryptionKey.setCurrentUserPassword("password");
workbook = new HSSFWorkbook(fileInputStream);
}
} else if (fileExtensionName.equals(".xlsx")){
// Checking of .xlsx file with password protected.
String isWorkbookLock = "";
InputStream is = null;
is = new FileInputStream(new File(filePath));
if (!is.markSupported()) {
is = new PushbackInputStream(is, 8);
}
if (POIFSFileSystem.hasPOIFSHeader(is)) {
POIFSFileSystem fs = new POIFSFileSystem(is);
EncryptionInfo info = new EncryptionInfo(fs);
Decryptor d = Decryptor.getInstance(info);
try {
d.verifyPassword("password");
is = d.getDataStream(fs);
workbook = new XSSFWorkbook(OPCPackage.open(is));
isWorkbookLock = "true";
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
if (isWorkbookLock != "true") {
FileInputStream fileInputStream = new FileInputStream(new File(filePath));
workbook = new XSSFWorkbook(fileInputStream);
}
}
return workbook;
}
拉维是对的。看来您可以读取受密码保护的文件,但不能读取 POI 加密的文件。看 http://osdir.com/ml/user-poi.apache.org/2010-05/msg00118.html. 。以下代码打印出文件的痕迹
POIFSLister lister = new POIFSLister();
lister.viewFile(spreadsheetPath, true);
如果您得到提及加密的输出,则无法使用 POI 打开该文件。