使用 Apache POI 创建受密码保护的 Excel 文件?

发布于 2024-12-26 03:50:14 字数 328 浏览 2 评论 0原文

我正在开发一个简单的 Java 程序来使用 (Apache POI) API 创建 Excel 文件。 我使用 Oracle 10g 作为数据库并使用 ojdbc14 JAR 文件。

我有一个名为 USERINFO 的表,包含三列,即 USERNAMEPASSWORDNAME。 现在使用 Apache POI,我已经能够将所有行放入 Excel 文件中。

由于该文件包含用户名和密码等敏感数据,因此我想对其进行密码保护。 在论坛上,我找到了如何读取受密码保护的文件,但没有找到如何创建它们。 那么我怎样才能实现这一目标呢?

I am developing a simple Java program to create an Excel file using (Apache POI) API.
I am using Oracle 10g as a database and using the ojdbc14 JAR file.

I have a table called USERINFO, having three columns, namely USERNAME, PASSWORD, and NAME.
Now using Apache POI, I have been able to put all the rows in an Excel file.

Since the file contains 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦里人 2025-01-02 03:50:14

更新:自 3.10 版起,POI 支持 XLSX 文件的加密和解密。请参阅POI 网站上的“加密支持”页面。以下内容仍然与 XLS 二进制工作簿相关。

根据POI网站上的“加密支持”页面 POI支持读取加密的XLS和XLSX文件。该页面上没有提到加密,这意味着它不受支持。这是通过在 POI 网站搜索“加密”来支持的 只返回少数结果,所有结果都与解密有关。我还查看了他们的加密实现的来源,它似乎只处理解密。这并不奇怪; POI 旨在用于数据提取和搜索索引,而不是用于创建新的电子表格。

正如其他人所建议的,通常可以通过在 Excel 中创建模板,然后使用 POI 填充数据来解决 POI 中缺少的功能。不幸的是,这不适用于加密,因为加密电子表格的文件格式完全不同。

如果您愿意付费购买商业软件,请使用最新版本的 ExtenXLS< /a> 对 Excel 支持的所有加密格式具有完整的读写支持。只需构造一个 EncryptedWorkBookHandle 而不是普通的 WorkBookHandle。这将使用未经修改的 JRE、XLS 的 RC4 和 XLSX 的 128 位 AES 支持的最强密码。如果您想将 256 位 AES 与 OOXML 结合使用,并且已安装 JCE 无限制策略 您可以使用 MSOfficeEncrypter 类来执行此操作。

JExcelAPI 是一种流行的开源 Java 电子表格 API,似乎根本不支持加密。 Aspose.Cells,商业产品, 支持强加密< /a>. Actuate 的 e.Spreadsheet 的文档似乎已经从网络上消失了,所以我无法判断它是否支持加密。

由于免费提供的 Java 电子表格 API 似乎都不支持编写加密电子表格,因此如果您不愿意使用商业软件,则需要想出一个解决方法。例如,您可以将电子表格写入加密的 ZIP 文件中。 java.util.zip 不支持加密,但它看起来像 Zip4j 确实如此。

全面披露:我在 Extentech 工作,该公司是 ExtenXLS 背后的公司。

Updated: As of version 3.10 POI supports encryption as well as decryption for XLSX files. See the "Encryption Support" page on POI's website. The below is still relevant for XLS binary workbooks.

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.

生来就爱笑 2025-01-02 03:50:14

创建受密码保护的 Excel 文件或使用现有模板并使其受密码保护。但这将为用户提供“只读”访问权限。下面是一个示例,其中我有一个具有密码“secret”的 Excel 文件:

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

您应该能够以相同的方式编写或修改现有的模板。完成后,覆盖模板。如果您的模板需要多次使用,您可能需要将模板复制到其他位置,然后使用代码对其进行修改。

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.

无所的.畏惧 2025-01-02 03:50:14

我经常发现,要使用 POI 执行更复杂的操作,一种有用的方法是使用高级功能(例如宏)在 Excel 中创建电子表格,然后使用 POI 读取电子表格、填充并写出。 POI 通常会维护电子表格功能并添加数据。

我还没有尝试过这个密码,但我怀疑它值得一试。

有关详细信息,请参阅繁忙开发人员指南

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.

惟欲睡 2025-01-02 03:50:14

以下程序将在给定的 excel 路径中生成受密码保护的 excel 文件

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class MyTest1 {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\Raju\\Desktop\\workbook1.xlsx");
        try {
            file.createNewFile();
            OutputStream fileOut = new FileOutputStream(file);
            XSSFWorkbook wb = new XSSFWorkbook();
            Sheet sheet = wb.createSheet();
            Row row = sheet.createRow(0);
            Cell cell = row.createCell(0);
            cell.setCellValue("Venu");
            wb.write(fileOut);
            wb.close();
            fileOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try (POIFSFileSystem fs = new POIFSFileSystem()) {
            EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
            // EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile,
            // CipherAlgorithm.aes192, HashAlgorithm.sha384, -1, -1, null);
            Encryptor enc = info.getEncryptor();
            enc.confirmPassword("hello");
            // Read in an existing OOXML file and write to encrypted output stream
            // don't forget to close the output stream otherwise the padding bytes aren't
            // added
            try (OPCPackage opc = OPCPackage.open(file, PackageAccess.READ_WRITE);
                    OutputStream os = enc.getDataStream(fs)) {
                opc.save(os);
            } catch (InvalidFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (GeneralSecurityException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            // Write out the encrypted version
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fs.writeFilesystem(fos);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
        System.out.println("Excel file exported");
    }
}

使用 maven 依赖

<dependency>
 <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>

项 是的,我知道我们可以优化这么多代码。在高水平上,该程序正在运行

The Following Program will generate the password protected excel file in given excel path

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class MyTest1 {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\Raju\\Desktop\\workbook1.xlsx");
        try {
            file.createNewFile();
            OutputStream fileOut = new FileOutputStream(file);
            XSSFWorkbook wb = new XSSFWorkbook();
            Sheet sheet = wb.createSheet();
            Row row = sheet.createRow(0);
            Cell cell = row.createCell(0);
            cell.setCellValue("Venu");
            wb.write(fileOut);
            wb.close();
            fileOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try (POIFSFileSystem fs = new POIFSFileSystem()) {
            EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
            // EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile,
            // CipherAlgorithm.aes192, HashAlgorithm.sha384, -1, -1, null);
            Encryptor enc = info.getEncryptor();
            enc.confirmPassword("hello");
            // Read in an existing OOXML file and write to encrypted output stream
            // don't forget to close the output stream otherwise the padding bytes aren't
            // added
            try (OPCPackage opc = OPCPackage.open(file, PackageAccess.READ_WRITE);
                    OutputStream os = enc.getDataStream(fs)) {
                opc.save(os);
            } catch (InvalidFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (GeneralSecurityException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            // Write out the encrypted version
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fs.writeFilesystem(fos);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
        System.out.println("Excel file exported");
    }
}

Used maven dependency

<dependency>
 <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>

Yes, I am aware that we can optimize so much code. At high level the program is working

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文