我正在开发一个简单的Java程序来使用(Apache POI)API创建Excel文件。 我使用Oracle 10g作为数据库并使用ojdbc14 JAR文件。
我有一个名为USERINFO的表,有三列,即USERNAME
,PASSWORD
和NAME.
现在使用Apache POI,我已经能够将所有行放在Excel文件中。
由于该文件包含敏感数据,如用户名和密码,我想让它受密码保护。 在论坛上,我发现了如何读取受密码保护的文件,而不是如何创建它们。 那我怎么能做到这一点?
答案 0 :(得分:15)
已更新:自版本3.10起,POI支持XLSX文件的加密和解密。见the "Encryption Support" page on POI's website。以下内容仍与XLS二进制工作簿相关。
根据the "Encryption Support" page on POI's website POI支持读取加密的XLS和XLSX文件。该页面上未提及加密,这意味着它不受支持。这由searching the POI site for "encrypt"支持,它只返回少数几个与解密有关的结果。我还看了一下他们的加密实现的来源,它似乎只处理解密。这并不奇怪; POI专为数据提取和搜索索引而设计,而不是用于创建新的电子表格。
正如其他人所建议的那样,通常可以通过在Excel中创建模板然后使用POI用数据填充它来解决POI中缺少的功能。不幸的是,这对加密不起作用,因为加密电子表格的文件格式完全不同。
如果您愿意为商业软件付费,最新版本的ExtenXLS会对Excel支持的所有加密格式提供完全读写支持。只需构建一个EncryptedWorkBookHandle
而不是正常WorkBookHandle
。这将使用未经修改的JRE支持的最强密码,用于XLS的RC4和用于XLSX的128位AES。如果您想使用256位AES和OOXML,并且已经安装了JCE unlimited policy,则可以使用MSOfficeEncrypter
类进行安装。
JExcelAPI是一种流行的开源Java电子表格API,似乎根本不支持加密。 Aspose.Cells,商业广告supports stong encryption。 Actuate e.Spreadsheet的文档似乎从'net中消失了,所以我不知道它是否支持加密。
由于所有免费提供的Java电子表格API似乎都不支持编写加密电子表格,如果您不愿意使用商业软件,则需要提出解决方法。例如,您可以将电子表格写入加密的ZIP文件中。 java.util.zip
不支持加密,但它看起来像Zip4j。
完全披露:我在ExtenXLS背后的公司Extentech工作。
答案 1 :(得分:8)
创建受密码保护的Excel文件或使用现有模板并使其受密码保护。这将为用户提供“只读”访问权限。这是一个例子,我有一个密码为“秘密”的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());
}
}
}
}
您应该能够编写或修改现有模板。完成后,覆盖模板。如果您的模板应该多次使用,您可能希望将模板复制到其他位置,然后使用代码进行修改。
答案 2 :(得分:4)
我经常发现POI要做更复杂的事情,一个有用的方法是在Excel中使用高级功能(例如宏)创建电子表格,然后使用POI读取电子表格,填充并写出来。 POI通常会维护电子表格功能并添加数据。
我没有试过这个密码,但我怀疑它值得一个实验。
有关详细信息,请参阅busy developer's guide。
答案 3 :(得分:0)
以下程序将在给定的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>
是的,我知道我们可以优化这么多代码。在高层次上,程序正在运行