我需要取消保护受保护的xlsx file.e.g Book1.xlsx 下面的代码第一次运行正常,Reads Book1.xlsx,解密它并再次将其写入相同的文件名。
public static void unprotectXLSXSheet(String fileName, String password) {
try{
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(fileName));
EncryptionInfo info = new EncryptionInfo(fs);
Decryptor d = Decryptor.getInstance(info);
d.verifyPassword(password);
InputStream is = d.getDataStream(fs);
System.out.println(is.available());
XSSFWorkbook wb = new XSSFWorkbook(OPCPackage.open(is));
FileOutputStream fileOut;
fileOut = new FileOutputStream(fileName);
wb.write(fileOut);
fileOut.flush();
fileOut.close();
}catch(FileNotFoundException ex){
ex.printStackTrace();
}catch(IOException ex){
ex.printStackTrace();
但是当相同的代码尝试访问新创建的不受保护的Book1.xlsx(或任何其他未受保护的xlsx文件)时,它会失败并显示
Exception in thread "main" org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:131)
at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:104)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:138)
at com.wolseley.Excel.TestMainDummy.unprotectXLSXSheet(TestMainDummy.java:113)
at com.wolseley.Excel.TestMainDummy.main(TestMainDummy.java:52)
我需要帮助阅读xlsx文件并使用密码解锁,如上所述。
答案 0 :(得分:5)
基本上,以下代码行不适用于Office 2007+ XML文档:
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(fileName));
所以你首先需要检查输入流中的标题是否支持调用它:
POIFSFileSystem.hasPOIFSHeader(is)
并且仅在以上返回true时才解密。 hasPOIFSHeader
方法需要一个支持标记/重置的输入流,因此请检查它并将其包装在PushbackInputStream
中,如果没有。
把它们放在一起然后变成这样:
public static void unprotectXLSXSheet(String fileName, String password) throws Exception {
InputStream is = null;
FileOutputStream fileOut = null;
try {
is = new FileInputStream(fileName);
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);
d.verifyPassword(password);
is = d.getDataStream(fs);
}
System.out.println(is.available());
XSSFWorkbook wb = new XSSFWorkbook(OPCPackage.open(is));
fileOut = new FileOutputStream(fileName);
wb.write(fileOut);
fileOut.flush();
} finally {
if (is != null) {
is.close();
}
if (fileOut != null) {
fileOut.close();
}
}
}
答案 1 :(得分:0)
旧的Stack Overflow旧答案可能会帮助您解决这个问题。
Reading property sets from Office 2007+ documents with java poi
您想要的课程是POIXMLProperties,类似于:
OPCPackage pkg = OPCPackage.open(new File("file.xlsx"));
POIXMLProperties props = new POIXMLProperties(pkg);
System.out.println("The title is " + props.getCorePart().getTitle());
从POIXMLProperties,您可以访问所有内置属性,也可以访问自定义属性!