5

I have an excel spreadsheet that is password-protected. I need to open this spreadsheet and read the data from it. I've been attempting to use the POI API to no avail. A Java solution would be preferred but any ideas would be helpful.

Edit: Yes, I have the password. The file is password protected in excel; a password must be entered to view the spreadsheet.

Edit2: I am unable to open it with POI with the password, I am looking for an alternate solution.

dhorn
  • 687
  • 1
  • 5
  • 13
  • 1
    It's not clear from your question whether you actually have the password and just having problems transmitting it to POI. It also seems like a duplicate of http://stackoverflow.com/questions/1204382/how-can-we-read-protected-password-excel-file-xls-with-poi-api – Uri Apr 09 '10 at 16:59
  • Excel has several protection mechanisms where a password is used. Are you referring to the file-protection, allowing the file to be opened only with the supplied password? – M.A. Hanin Apr 09 '10 at 17:06
  • See edits regarding questions. – dhorn Apr 09 '10 at 17:14

4 Answers4

7

POI should be able to open both protected xls files (using org.apache.poi.hssf.record.crypt) and protected xlsx files (using org.apache.poi.poifs.crypt). Have you tried these?

If you're using HSSF (for a xls file), you need to set the password before opening the file. You do this with a call to:

 org.apache.poi.hssf.record.crypto.Biff8EncryptionKey.setCurrentUserPassword(password);

After that, HSSF should be able to open your file.

For XSSF, you want something like:

    POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("protect.xlsx"));
    EncryptionInfo info = new EncryptionInfo(fs);
    Decryptor d = Decryptor.getInstance(info);
    d.verifyPassword(Decryptor.DEFAULT_PASSWORD);
    XSSFWorkbook wb = new XSSFWorkbook(d.getDataStream(fs));

Full details are given on the POI Encryption documentation page

Gagravarr
  • 47,320
  • 10
  • 111
  • 156
  • This looks most correct for POI. EncryptionInfo was introduced in POI in v3.7 or v3.8 – Jeromy Evans Aug 16 '11 at 09:09
  • how to set password on the unprotected excel file? Is there any method in this org.apache.poi.hssf.record.crypto.Biff8EncryptionKey package – happy Jun 26 '12 at 08:21
  • I think you need to use `Decryptor d = Decryptor.getInstance(info);` instead in line #3 – Yar Jun 15 '16 at 01:09
  • @HoomanYar Whoops, perils of copying from the unit tests which are in the same package! Thanks, now fixed – Gagravarr Jun 15 '16 at 07:57
  • @Gagravarr I have never used this and I am not familiar with this. So, how can I replicate it in a few words? Create a specific file (filetype??) that has this script in it and run it in my server? Cheers – Datacrawler Sep 28 '16 at 13:40
1

I tried to set password for excel file from java script, this script will only work on IE and Excel get should installed in the client system.

<script>
function setPasswordToExcel(password,excelFileName,newFileName)
{
   var Excel;
    Excel = new ActiveXObject("Excel.Application"); 
    Excel.Visible = false;
    var obj = Excel.Workbooks.Open(excelFileName);
    obj.Password =password;
    obj.SaveAs(newFileName);
    obj.Close();
    Excel.Close();
    return 1;
}       
 setPasswordToExcel("stephen","C:/test1.xls","C:\\test2.xls");
</script>
1

addthe excel file in ODBC Sources (from control panel->Administrative Tools) and then execute the code:

// program to extract data from excel file

import java.sql.Connection ;
import java.sql.Statement  ;
import java.sql.ResultSet  ;
import java.sql.ResultSetMetaData ;
import java.sql.DriverManager ;
import java.sql.SQLException ;

public class ExtractExcelData {

    public static void main (String[] args) {
        try {
            Class.forName(DRIVER);
            connection = DriverManager.getConnection(URL,userName,password);
        }
        catch (ClassNotFoundException cnfe) {
            System.err.println("unable to load excel  driver");
            return  ;
        }
        catch (SQLException se) {
            System.err.println("cannot connect to excel file");
            return  ;
        }

        try {
            statement = connection.createStatement();
            String select = "SELECT * FROM [Sheet1$]";
            resultSet = statement.executeQuery(select);
            metaData = resultSet.getMetaData();

            int count = metaData.getColumnCount();
            while ( resultSet.next() ) {

                String col1 =  resultSet.getString(1) ; 
                String col2 =  resultSet.getString(2) ; 
                String col3 =  resultSet.getString(3) ; 

                System.out.println( col1 ) ;
                System.out.println( col2 ) ;
                System.out.println( col3 ) ;

                System.out.println();
            }
        }
        catch (SQLException se) {
            System.err.println("cannot execute query");
            return ;
        }

        try {
            statement.close();
            resultSet.close();
        }
        catch (SQLException se ) {
            System.err.println("unable to close excel file");
            return  ;
        }
    }

    private static final String userName = "" ;
    private static final String password = "" ;
    private static final String URL = "jdbc:odbc:testexcel" ;
    private static final String DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver" ;

    private static Connection connection ;
    private static Statement statement ;
    private static ResultSet resultSet ;
    private static ResultSetMetaData metaData ;
}
Wajdy Essam
  • 4,280
  • 3
  • 28
  • 33
0

You can use JExcelApi.

It has been a while since I have done this, so I may not be telling you how to do it correctly, but there is definitely a way to do this using JExcelApi. Try the source below:

Workbook workbook = Workbook.getWorkbook(new File("/path/to/protected.xls"));
workbook.setProtected(false);
WritableWorkbook copy = Workbook.createWorkbook(new File("/path/to/unprotected.xls"), workbook);
WritableSheet[] sheets = copy.getSheets();

for (WritableSheet sheet : sheets){
    sheet.getSettings().setProtected(false);
}

copy.write();
copy.close();

Of course, you will need to import necessary classes and catch necessary exceptions.

Kevin Crowell
  • 10,082
  • 4
  • 35
  • 51
  • Awesome, I'll give this a shot. – dhorn Apr 09 '10 at 17:28
  • Is there any method to set password on excel?? – happy Jun 27 '12 at 09:23
  • I tried this but I am not able to set the password.Please see http://stackoverflow.com/questions/11256259/how-to-set-password-on-workbook-worksheet-of-excel-in-java-using-jexcel-api – happy Jun 29 '12 at 04:58
  • why you are copying protected file into unprotected one, is it the only option? i'd like to avoid creating any new files, even temporarily.. assuming i have a password and i need just to read the data from the file - can it be done in jxl without this weird copying..? – javagirl Jul 23 '14 at 11:05
  • @Kevin Crowell What is the filetype of this file? – Datacrawler Sep 19 '16 at 12:58
  • @ApoloRadomer The example is for an excel file (xls) but xlsx would be the same. – Kevin Crowell Sep 19 '16 at 17:13
  • @KevinCrowell I was talking about the script actually. – Datacrawler Sep 20 '16 at 10:11
  • @KevinCrowell I was not able to load JExcelApi and make the JS run on my server. I want to visit a link on wamp that will remove the password from an xlsx file. It did not work with PHP and PHPExcel. I cannot include MACRO in my PHP script it make it work. Only JS can help it I guess. But I am pretty stuck. – Datacrawler Sep 20 '16 at 10:12