Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am developing a simple Java program to create excel file using (Apache POI) API. I am using oracle 10g as a database and using ojdbc14 jar.

I have a table called USERINFO having 3 columns namely USERNAME,PASSWORD , NAME. Now using APACHE POI , i have been able to put all the rows in excel file.

Since file contain sensitive data such as username and password, i want to make it password protected. On forums , i have found how to read password protected files but not how to create them. So how i can achieve this?

Thanks in advance.

share|improve this question

3 Answers

up vote 4 down vote accepted
+50

According to the "Encryption Support" page on POI's website POI supports reading encrypted XLS and XLSX files. Encrypting is not mentioned on that page, which implies that it's not supported. This is backed up by searching the POI site for "encrypt" which returns only a handful of results all of which are about decryption. I've also taken a look at the sources for their crypto implementation, which appears to only handle decryption. This isn't surprising; POI is designed for data extraction and search indexing, not for creating new spreadsheets.

As others have suggested, it's often possible to work around missing features in POI by creating a template in Excel and then using POI to populate it with data. Unfortunately that won't work for encryption because the file format of encrypted spreadsheets is radically different.

If you're willing to pay for commercial software, the latest version of ExtenXLS has full read and write support for all the encryption formats supported by Excel. Just construct an EncryptedWorkBookHandle instead of the normal WorkBookHandle. That will use the strongest possible cipher supported by an unmodified JRE, RC4 for XLS and 128-bit AES for XLSX. If you want to use 256-bit AES with OOXML and you've installed the JCE unlimited policy you can do so with the MSOfficeEncrypter class.

JExcelAPI, a popular open-source Java spreadsheet API, does not appear to support encryption at all. Aspose.Cells, a commercial offering, supports stong encryption. The documentation for Actuate's e.Spreadsheet seems to have disappeared from the 'net, so I can't tell whether it supports encryption or not.

Since none of the freely available Java spreadsheet APIs seems to support writing encrypted spreadsheets, if you're not willing to use commercial software you'll need to come up with a workaround. You could, for example, write the spreadsheet into an encrypted ZIP file. java.util.zip doesn't support encryption, but it looks like Zip4j does.

Full disclosure: I work for Extentech, the company behind ExtenXLS.

share|improve this answer
Thank you Sam . – vikiiii Jan 25 '12 at 4:24

I've often found with POI that to do more complex stuff, a useful approach is to create the spreadsheet in Excel with the advanced features (e.g. macros), then use POI to read the spreadsheet, populate it and write it out. POI will normally maintain the spreadsheet features and add the data.

I've not tried this for passwords, but I suspect it's worth an experiment.

See the busy developer's guide for more info.

share|improve this answer
Hi Brian, i have no idea about macros or advanced features. Can you give me some link where i can get some help. I am a beginner to POI. – vikiiii Jan 11 '12 at 10:22
All I'm suggesting is creating the spreasheet in Excel with the capabilities you require, then use POI to read it and populate it. i.e. it's very similar to what you're doing but with an existing spreadsheet rather than a new one – Brian Agnew Jan 11 '12 at 10:43
you have told me an optional method of doing it. What i have asked in question is just as an example. Actually in my project there are many tables , so it will be difficult if i create excel file manually for each table. – vikiiii Jan 17 '12 at 10:45

It's an old question but if anyone still needs it-

Create a password protected excel file or use an existing template and make it password protected. This will give the users a "read only" access though. Here's an example where I have an excel file that has a password "secret"-

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;

public class ProtectedExcelFile { 

    public static void main(final String... args) throws Exception {     

        String fname = "C:\\Documents and Settings\\sadutta\\Desktop\\sample.xls";

        FileInputStream fileInput = null;       
        BufferedInputStream bufferInput = null;      
        POIFSFileSystem poiFileSystem = null;    
        FileOutputStream fileOut = null;

        try {           

            fileInput = new FileInputStream(fname);         
            bufferInput = new BufferedInputStream(fileInput);            
            poiFileSystem = new POIFSFileSystem(bufferInput);            

            Biff8EncryptionKey.setCurrentUserPassword("secret");            
            HSSFWorkbook workbook = new HSSFWorkbook(poiFileSystem, true);            
            HSSFSheet sheet = workbook.getSheetAt(0);           

            HSSFRow row = sheet.createRow(0);
            Cell cell = row.createCell(0);

            cell.setCellValue("THIS WORKS!"); 

            fileOut = new FileOutputStream(fname);
            workbook.writeProtectWorkbook(Biff8EncryptionKey.getCurrentUserPassword(), "");
            workbook.write(fileOut);



        } catch (Exception ex) {

            System.out.println(ex.getMessage());      

        } finally {         

              try {            

                  bufferInput.close();     

              } catch (IOException ex) {

                  System.out.println(ex.getMessage());     

              }    

              try {            

                  fileOut.close();     

              } catch (IOException ex) {

                  System.out.println(ex.getMessage());     

              } 
        }       

    }
}

The same way you should be able to write or modify the existing template that you have. After you are done, overwrite the template. If your template should be used many times, you may want to copy the template to some other location and then use the code to modify it.

share|improve this answer

protected by Community Apr 15 at 15:08

This question is protected to prevent "thanks!", "me too!", or spam answers by new users. To answer it, you must have earned at least 10 reputation on this site.

Not the answer you're looking for? Browse other questions tagged or ask your own question.