java - Apache POI加密的xlsx无法在excel中打开
问题描述
我正在尝试使用 Apache POI 创建一个加密的 xlsx 文件。这是我的代码,运行良好:
public static void Encrypt(String data) throws IOException, GeneralSecurityException, InvalidFormatException {
Workbook wb = new XSSFWorkbook();
Sheet sheet1 = wb.createSheet("sheet1");
sheet1.createRow(0).createCell(0).setCellValue(data);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos);
bos.close();
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile, CipherAlgorithm.aes256, HashAlgorithm.sha512, 256, 16, ChainingMode.cbc);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("pass");
OPCPackage opc = OPCPackage.open(new ByteArrayInputStream(bos.toByteArray()));
OutputStream os = enc.getDataStream(fs);
opc.save(os);
opc.close();
FileOutputStream fos = new FileOutputStream("provawrite.xlsx");
fs.writeFilesystem(fos);
fos.close();
}
问题是当我打开生成的文件时,excel一直抱怨文件已损坏。我还尝试EncryptionInfo
使用不同的加密模式更改实例化,但没有任何变化。
有人可以给我一个提示吗?!?
解决方案
在写出文件系统之前,必须关闭加密的输出流。在您的情况下,它缺少os.close();
after opc.save(os);
。
但是为什么要绕道使用ByteArrayOutputStream
呢?
以下对我有用:
import java.io.*;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.poifs.crypt.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class XSSFEncryption {
public static void doEncrypt(String data) throws Exception {
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("pass");
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("sheet1");
sheet.createRow(0).createCell(0).setCellValue(data);
// write the workbook into the encrypted OutputStream
OutputStream encos = enc.getDataStream(fs);
workbook.write(encos);
workbook.close();
encos.close(); // this is necessary before writing out the FileSystem
OutputStream os = new FileOutputStream("provawrite.xlsx");
fs.writeFilesystem(os);
os.close();
fs.close();
}
public static void main(String[] args) throws Exception {
doEncrypt("Test");
}
}
推荐阅读
- java - Mac 上带有 JRE11 的 Eclipse 2020-09 正在启动 300% CPU java 进程
- r - 使用只有一个变量的 ggplot2 在 R 中绘制小平面网格
- websocket - 有没有办法在 WebSocket 中支持多路复用?类似于 http/2 中的流 id
- android - 具有不同项目计数的 Android 嵌套 Recyclerview
- gnuplot - Gnuplot 按角度拉伸椭圆选项
- c# - 一种使用 Json.NET 转换不总是相同类型的 json 字段的方法
- c# - Unity 中的 C# 属性:设置值行为异常
- python - 在 Windows 上删除和重新安装 Python-Sphinx
- python - 在新轴上连接两个熊猫数据框
- firemonkey - 在 C++ Builder 的 FMX 媒体播放器中注册新的媒体编解码器