Невозможно открыть защищенный паролем файл xlsx, созданный из Apache Poi, с помощью инструмента Excel

Я создал защищенный паролем файл xlsx, используя структуру Apache POI, ниже добавил свой код. однако я не могу открыть сгенерированный файл с помощью инструмента Excel. Я могу открыть его с помощью бесплатного инструмента Plan Maker. любые советы приветствуются.

У меня есть используемые ниже банки: ooxml-schemas-4.1.2.jar, SparseBitSet-1.1.jar, xmlbeans-3.1.0.jar

package com.pega.gcs.createworkbook;

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;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ProtectedExcelFile {

    public static void main(final String... args) throws Exception {

        String fname = "FromJavaSecure1.xlsx";
        String label="Sheet1-Abc";  
        String cellvalue="Cell1";  

        org.apache.poi.xssf.usermodel.XSSFSheet     sheet;  
        org.apache.poi.xssf.usermodel.XSSFRow       row;  
        org.apache.poi.xssf.usermodel.XSSFCell      cell;

        org.apache.poi.hssf.usermodel.HSSFSheet     hsheet;  
        org.apache.poi.hssf.usermodel.HSSFRow       hrow;  
        org.apache.poi.hssf.usermodel.HSSFCell      hcell;

        FileInputStream fileInput = null;
        BufferedInputStream bufferInput = null;
        POIFSFileSystem poiFileSystem = null;
        FileOutputStream fileOut = null;

        try {


            try(

                    HSSFWorkbook workbook = new HSSFWorkbook();
               ) 
            {
                     hsheet=workbook.createSheet(label); hrow=hsheet.createRow(0);
                     hcell=hrow.createCell(0); hcell.setCellValue(cellvalue);

         Biff8EncryptionKey.setCurrentUserPassword("secret");

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

person Raja    schedule 01.04.2020    source источник
comment
Попробуйте использовать XSSF и файл .xlsx? Необходимый фрагмент кода см. на странице poi.apache.org/encryption.html.   -  person Gagravarr    schedule 01.04.2020
comment
Попробуйте String fname = "FromJavaSecure1.xls"; вместо String fname = "FromJavaSecure1.xlsx";. Поскольку вы создаете HSSFWorkbook в двоичном формате BIFF, этот файл не может называться *.xlsx. Только файл XSSFWorkbook в формате файла Office Open XML должен называться *.xlsx.   -  person Axel Richter    schedule 01.04.2020
comment
Спасибо @Gagravarr, на странице шифрования poi.html есть хорошие примеры. Мне удалось решить эту проблему.   -  person Raja    schedule 02.04.2020
comment
Привет @AxelRichter, на самом деле я пробовал оба расширения xls и xlsx. Я использовал сам XSSFWorkbook. в любом случае, я публикую ниже свой рабочий код.   -  person Raja    schedule 02.04.2020


Ответы (1)


После ссылки на https://poi.apache.org/encryption.html удается получить ниже код работает для моего требования.

   /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package excelpasswordgeneration;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
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.Workbook;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 *
 * @author venu
 */
public class ExcelPasswordGeneration {

    public static void main(String[] args) throws Exception {

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



            String label = "Sheet1-Raja";
            String cellvalue = "Cell1";

            org.apache.poi.xssf.usermodel.XSSFSheet sheet;
            org.apache.poi.xssf.usermodel.XSSFRow row;
            org.apache.poi.xssf.usermodel.XSSFCell cell;
            try (
                    XSSFWorkbook workbook = new XSSFWorkbook()) {
                sheet = workbook.createSheet(label);
                row = sheet.createRow(0);
                cell = row.createCell(0);
                cell.setCellValue(cellvalue);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                workbook.write(out);


               // 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(new ByteArrayInputStream(out.toByteArray()));
                    OutputStream os = enc.getDataStream(fs)) {
                opc.save(os);
            }
            // Write out the encrypted version
            try (FileOutputStream fos = new FileOutputStream("sample-encrypted.xlsx")) {
                fs.writeFilesystem(fos);
            }

            }

        }
    }

}
person Raja    schedule 02.04.2020