Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法在excel中打开Apache POI加密的xlsx_Java_Excel_Apache Poi_Xssf - Fatal编程技术网

Java 无法在excel中打开Apache POI加密的xlsx

Java 无法在excel中打开Apache POI加密的xlsx,java,excel,apache-poi,xssf,Java,Excel,Apache Poi,Xssf,我正在尝试使用ApachePOI创建一个加密的xlsx文件。以下是我的代码,运行良好: public static void Encrypt(String data) throws IOException, GeneralSecurityException, InvalidFormatException { Workbook wb = new XSSFWorkbook(); Sheet sheet1 = wb.createSheet("sheet1"); sheet1.

我正在尝试使用ApachePOI创建一个加密的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()
opc.save(操作系统)之后

但是为什么要使用
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");
 }
}

在写入文件系统之前,必须关闭加密的输出流。在您的情况下,它缺少
os.close()
opc.save(操作系统)之后

但是为什么要使用
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");
 }
}

尝试使用
Try
/
最后
或尝试使用resources语句,然后刷新。不太了解POI加密,但您可能还想尝试在文件实际写入文件系统之前不关闭流。请尝试使用
Try
/
finally
或尝试使用resources语句,然后刷新。我对POI加密了解不多,但您可能还想尝试在文件实际写入文件系统之前不关闭流。哎哟,这很简单。也许我昨天真的很累。谢谢你,先生!有趣的是,代码在使用ApachePOI3.17时没有调用encos.close()的情况下运行良好,但在4.0.1和4.1.1中失败。这意味着一些旧的代码示例现在在ApachePOI4中失败了。@MartinDirichs:嗯,这是一个“Binsenweisheit”又名truism;-)。ApachePOI的更改方式总是导致需要更改以前使用的代码。从来没有太多的向后兼容性。哎哟,这很容易。也许我昨天真的很累。谢谢你,先生!有趣的是,代码在使用ApachePOI3.17时没有调用encos.close()的情况下运行良好,但在4.0.1和4.1.1中失败。这意味着一些旧的代码示例现在在ApachePOI4中失败了。@MartinDirichs:嗯,这是一个“Binsenweisheit”又名truism;-)。ApachePOI的更改方式总是导致需要更改以前使用的代码。从没有太多向后兼容性。