在XSSF工作簿上设置密码保护

时间:2016-11-09 16:27:57

标签: java excel apache apache-poi

我想为使用poi 3.14创建的xlsx文件添加密码保护。 文件声称,这是可能的:

http://poi.apache.org/encryption.html

使用这个例子我试过这样:

    public static void main(String[] args)
{
    try(Workbook wb = new XSSFWorkbook())
    {

        //<...>
        try(ByteArrayOutputStream baos = new ByteArrayOutputStream())
        {
            wb.write(baos);
            byte[] res = baos.toByteArray();
            try(ByteArrayInputStream bais = new ByteArrayInputStream(res))
            {
                try(POIFSFileSystem fileSystem = new POIFSFileSystem(bais);) // Exception happens here
                {
                    EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
                    Encryptor enc = info.getEncryptor();
                    enc.confirmPassword("pass");
                    OutputStream encryptedDS = enc.getDataStream(fileSystem);
                    OPCPackage opc = OPCPackage.open(new File("example.xlsx"), PackageAccess.READ_WRITE);
                    opc.save(encryptedDS);
                    opc.close();
                }
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

不幸的是,示例中的代码与XLSX文件不兼容,因此我收到以下异常:

The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)

有人可以帮忙吗?我无法为XLSX找到正确的替代方案......

谢谢大家的帮助。这是我的工作成果:

    public static void main(String[] args)
{
    try(Workbook wb = new XSSFWorkbook())
    {
        Sheet sheet = wb.createSheet();
        Row r = sheet.createRow(0);
        Cell cell = r.createCell(0);
        cell.setCellType(Cell.CELL_TYPE_STRING);
        cell.setCellValue("Test");
        try(POIFSFileSystem fileSystem = new POIFSFileSystem();)
        {
            EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard);
            Encryptor enc = info.getEncryptor();
            enc.confirmPassword("pass");
            OutputStream encryptedDS = enc.getDataStream(fileSystem);
            wb.write(encryptedDS);
            FileOutputStream fos = new FileOutputStream("C:/example.xlsx");
            fileSystem.writeFilesystem(fos);
            fos.close(); 
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

1 个答案:

答案 0 :(得分:2)

你误读了documentation on encrypting in OOXML file。因此,当您只需要保存时,您错误地尝试使用错误的代码加载文件

没有任何错误处理,您的代码基本上是

// Prepare
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile, CipherAlgorithm.aes192, HashAlgorithm.sha384, -1, -1, null);

Encryptor enc = info.getEncryptor();
enc.confirmPassword("foobaa");

// Create the normal workbook
Workbook wb = new XSSFWorkbook();
Sheet s = wb.createSheet();
// TODO Populate

// Encrypt
OutputStream os = enc.getDataStream(fs);
wb.save(os);
opc.close();

// Save
FileOutputStream fos = new FileOutputStream("protected.xlsx");
fs.writeFilesystem(fos);
fos.close();  
相关问题