I've just learned POI and find the HSSF is very simple to read and create excel file (.xls).
However, I found some problem when want to read excel protected with password.
It took me an hour to find this solution on internet.
Please could you help me to solve this problem.
I'm very glad if you could give me a code snippet.
Thank you.
POI will not be able to read encrypted workbooks - that means that if you have protected the entire workbook (and not just a sheet), then it won't be able to read it. Otherwise, it should work.
See http://poi.apache.org/encryption.html - if you're using a recent enough copy of Apache POI (eg 3.8) then encrypted .xls files (HSSF) and .xlsx files (XSSF) can be decrypted (proving you have the password!)
At the moment you can't write out encrypted excel files though, only un-encrypted ones
At the time you wrote your question, it wasn't easy to do with Apache POI. Since then, support has come on a long way
These days, if you want to open a password protected Excel file, whether .xls
or .xlsx
, for which you know the password, all you need to do is use WorkbookFactory.create(File,Password), eg
File input = new File("password-protected.xlsx");
String password = "nice and secure";
Workbook wb = WorkbookFactory.create(input, password);
That'll identify the type of the file, decrypt it with the given password, and open it for you. You can then read the contents as normal
Here is a complete example code that reads in a protected excel file, decrypts using a password and writes out unprotected excel file
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();
}
}
That is the code for Read Excel file with checking of .xls and .xlsx (with password protected or without password protected) as complete example code.
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;
}
Ravi is right. It seems you can read password protected, but not encrypted files with POI. See http://osdir.com/ml/user-poi.apache.org/2010-05/msg00118.html. The following code prints out a trace of the file
POIFSLister lister = new POIFSLister();
lister.viewFile(spreadsheetPath, true);
If you get an output mentioning encryption then you cannot open the file with POI.