为现有的xls文件创建密码

时间:2018-03-01 14:31:40

标签: java apache-poi

我在运行时遇到异常。需要保护已经存在的xls文件。

  

java.io.FileNotFoundException:没有这样的条目:" EncryptionInfo",有:   [] 在   org.apache.poi.poifs.filesystem.DirectoryNode.getEntry(DirectoryNode.java:399)     在   org.apache.poi.poifs.filesystem.DirectoryNode.createDocumentInputStream(DirectoryNode.java:188)     在   org.apache.poi.poifs.crypt.EncryptionInfo。(EncryptionInfo.java:94)     在   org.apache.poi.poifs.crypt.EncryptionInfo。(EncryptionInfo.java:76)

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;

public class xlsProtect {

    public static void main(String[] args) {
        try {
            POIFSFileSystem fs = new POIFSFileSystem();
            EncryptionInfo info = new EncryptionInfo(fs);
            Encryptor enc = info.getEncryptor();
            enc.confirmPassword("test"); // s3cr3t is your password to open sheet.

            OPCPackage opc = OPCPackage.open(new File("C:/Users/test/Desktop/pdf/1.xls"), PackageAccess.READ_WRITE);
            OutputStream os = enc.getDataStream(fs);
            opc.save(os);
            opc.close();

            FileOutputStream fos = new FileOutputStream("C:/Users/test/Desktop/pdf/1.xls");
            fs.writeFilesystem(fos);
            fos.close();

            fs.writeFilesystem(fos);
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在您打开.xls后,必须调用Biff8EncryptionKey.setCurrentUserPassword()方法。有关加密两种格式的信息,请参阅以下内容。 我已经使用Excel 2016和Libre Office 6.0测试了.xls - Libre Office目前无法打开CryptoAPI加密文件 - 如果这对您来说是一个问题,我认为该示例可以适应回退到二进制RC4加密。

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.ss.usermodel.WorkbookFactory;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class EncryptTest {
    public static void main(String[] args) throws Exception {
        encryptHSSF();
        encryptXSSF();

        for (final String file : new String[] {"test.xls","test.xlsx"}) {
            try (Workbook wb = WorkbookFactory.create(new File(file), "pass")) {
                System.out.println(wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
            }
        }
    }

    public static void encryptHSSF() throws IOException, EncryptedDocumentException, InvalidFormatException {
        generateFile("test.xls");

        try (HSSFWorkbook hwb = (HSSFWorkbook)WorkbookFactory.create(new File("test.xls"))) {
            Biff8EncryptionKey.setCurrentUserPassword("pass");
            hwb.write();
        }
    }

    public static void encryptXSSF() throws IOException, GeneralSecurityException {
        generateFile("test.xlsx");

        try (POIFSFileSystem fs = new POIFSFileSystem()) {
            EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
            Encryptor enc = info.getEncryptor();
            enc.confirmPassword("pass");

            try (OutputStream os = enc.getDataStream(fs)) {
                try (InputStream is = new FileInputStream("test.xlsx")) {
                    IOUtils.copy(is, os);
                }
            }

            try (FileOutputStream fos = new FileOutputStream("test.xlsx")) {
                fs.writeFilesystem(fos);
            }
        }
    }


    public static void generateFile(final String filename) throws IOException {
        try (Workbook wb = filename.endsWith("x") ? new XSSFWorkbook() : new HSSFWorkbook()) {
            wb.createSheet("test").createRow(0).createCell(0).setCellValue("Test");
            try (FileOutputStream fos = new FileOutputStream(filename)) {
                wb.write(fos);
            }
        }
    }
}