Apache Ошибка выдачи POI при попытке защитить паролем книги XLSX небольшого размера (~ = 80 МБ) - PullRequest
0 голосов
/ 27 апреля 2020

с использованием java 8 и apache POI и POI-OO XML 3.14

Вот мой метод:

    private static void encryptXlsx(String inputPath, String outputPath, String password) throws IOException, InvalidFormatException, GeneralSecurityException {
    //create a new workbook
    Workbook wb = WorkbookFactory.create(new File(inputPath));


    //Add password protection and encrypt the file
    POIFSFileSystem fs = new POIFSFileSystem();
    EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
    Encryptor enc = info.getEncryptor();
    enc.confirmPassword(password); // s3cr3t is your password to open sheet.

    OPCPackage opc = OPCPackage.open(new File(inputPath), PackageAccess.READ_WRITE);
    OutputStream os = enc.getDataStream(fs);
    opc.save(os);
    opc.close();

    FileOutputStream fos = new FileOutputStream(outputPath);
    fs.writeFilesystem(fos);
    fos.close();
}

Стек ошибок:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3044)
at org.apache.xmlbeans.impl.store.Cur$CurLoadContext.attr(Cur.java:3065)
at org.apache.xmlbeans.impl.store.Locale$SaxHandler.startElement(Locale.java:3263)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.reportStartTag(Piccolo.java:1082)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseAttributesNS(PiccoloLexer.java:1802)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseOpenTagNS(PiccoloLexer.java:1521)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseTagNS(PiccoloLexer.java:1362)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseXMLNS(PiccoloLexer.java:1293)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.parseXML(PiccoloLexer.java:1261)
at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.yylex(PiccoloLexer.java:4812)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yylex(Piccolo.java:1290)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yyparse(Piccolo.java:1400)
at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.parse(Piccolo.java:714)
at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3479)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1277)
at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1264)
at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
at org.apache.poi.POIXMLTypeLoader.parse(POIXMLTypeLoader.java:92)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument$Factory.parse(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFSheet.read(XSSFSheet.java:173)
at org.apache.poi.xssf.usermodel.XSSFSheet.onDocumentRead(XSSFSheet.java:165)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.parseSheet(XSSFWorkbook.java:417)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.onDocumentRead(XSSFWorkbook.java:382)
at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:178)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:249)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:293)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:252)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:231)
at XlsxEncryptExample.encryptXlsx(XlsxEncryptExample.java:36)
at XlsxEncryptExample.main(XlsxEncryptExample.java:28)

Процесс завершен с кодом выхода 1

Если кто-нибудь может указать мне способ чтения этого файла без использования такого большого объема памяти, библиотеку, защищающую паролем лучше, чем POI, или любой другой возможный способ. Я был бы благодарен.

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

Как я понимаю, документация POI обычно считывает всю электронную таблицу в память. В нем говорится:

. Обратите внимание, что система пользовательских моделей занимает больший объем памяти, чем низкоуровневая eventusermodel, но имеет главное преимущество: с ней гораздо проще работать. Также имейте в виду, что поскольку новые файлы Excel OO XML (.xlsx), поддерживаемые XSSF, основаны на XML, объем памяти для их обработки выше, чем для более старых двоичных файлов с поддержкой HSSF (.xls).

Компания продолжает предлагать альтернативы с малым объемом памяти.

0 голосов
/ 28 апреля 2020
private static void encryptXlsx(String inputPath, String outputPath, String password) throws IOException, InvalidFormatException, GeneralSecurityException {
//create a new workbook
//Workbook wb = WorkbookFactory.create(new File(inputPath));


//Add password protection and encrypt the file
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword(password); // s3cr3t is your password to open sheet.

OPCPackage opc = OPCPackage.open(new File(inputPath), PackageAccess.READ_WRITE);
OutputStream os = enc.getDataStream(fs);
opc.save(os);
opc.close();

FileOutputStream fos = new FileOutputStream(outputPath);
fs.writeFilesystem(fos);
fos.close();

}

Мне кажется, что устранение требования к фабрике рабочих книг мне помогло. Оказывается, вам не нужно загружать весь файл, чтобы защитить его паролем. Тем не менее, это не решает проблему для тех, кто хочет манипулировать содержимым файла, поэтому я оставляю вопрос нерешенным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...