【问题标题】:Password Protected Excel File受密码保护的 Excel 文件
【发布时间】:2011-02-06 05:57:23
【问题描述】:

我有一个受密码保护的 Excel 电子表格。我需要打开这个电子表格并从中读取数据。我一直在尝试使用 POI API 无济于事。最好使用 Java 解决方案,但任何想法都会有所帮助。

编辑:是的,我有密码。该文件在excel中受密码保护;必须输入密码才能查看电子表格。

Edit2:我无法使用 POI 和密码打开它,我正在寻找替代解决方案。

【问题讨论】:

  • 从您的问题中不清楚您是否真的拥有密码并且只是在将密码传输到 POI 时遇到问题。它也似乎是 stackoverflow.com/questions/1204382/… 的副本
  • Excel 有几种使用密码的保护机制。您是指文件保护,只允许使用提供的密码打开文件?
  • 查看有关问题的编辑。

标签: java excel apache-poi


【解决方案1】:

POI 应该能够打开受保护的 xls 文件(使用 org.apache.poi.hssf.record.crypt)和受保护的 xlsx 文件(使用 org.apache.poi.poifs .crypt)。你试过这些吗?

如果您使用 HSSF(用于 xls 文件),则需要在打开文件之前设置密码。为此,您需要调用:

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

之后,HSSF 应该可以打开您的文件了。

对于 XSSF,您需要以下内容:

    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));

详情请见POI Encryption documentation page

【讨论】:

  • 这看起来最适合 POI。在 v3.7 或 v3.8 的 POI 中引入了 EncryptionInfo
  • 如何在未受保护的excel文件上设置密码?这个org.apache.poi.hssf.record.crypto.Biff8EncryptionKey包有什么方法吗
  • 我认为你需要在第 3 行使用 Decryptor d = Decryptor.getInstance(info); 代替
  • @HoomanYar 哎呀,从同一个包中的单元测试复制的危险!谢谢,现已修复
  • @Gagravarr 我从来没有用过这个,我不熟悉这个。那么,我怎样才能用几句话来复制它呢?创建一个包含此脚本的特定文件(文件类型??)并在我的服务器中运行它?干杯
【解决方案2】:

在ODBC Sources中添加excel文件(从控制面板->管理工具),然后执行代码:

// 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 ;
}

【讨论】:

  • 不推荐这种仅限 Windows 的解决方案。
【解决方案3】:

我尝试通过java脚本为excel文件设置密码,这个脚本只能在IE上运行,并且Excel get应该安装在客户端系统中。

<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>

【讨论】:

    【解决方案4】:

    您可以使用JExcelApi

    我已经有一段时间没有这样做了,所以我可能不会告诉你如何正确地做到这一点,但肯定有一种方法可以使用 JExcelApi 做到这一点。试试下面的来源:

    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();
    

    当然,您需要导入必要的类并捕获必要的异常。

    【讨论】:

    • 太棒了,我试试看。
    • 有没有办法在excel上设置密码??
    • 我试过了,但我无法设置密码。请参阅stackoverflow.com/questions/11256259/…
    • 为什么要将受保护的文件复制到未受保护的文件中,这是唯一的选择吗?我想避免创建任何新文件,即使是暂时的..假设我有密码并且我只需要从文件中读取数据 - 可以在 jxl 中完成而不需要这种奇怪的复制..?
    • @Kevin Crowell 这个文件的文件类型是什么?
    猜你喜欢
    • 1970-01-01
    • 2013-02-23
    • 2013-11-09
    • 1970-01-01
    • 2018-12-18
    • 2016-08-19
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多