Создавайте файлы xlsx в Apache-poi, не архивируя их окончательно

Я использую apache-poi для создания электронной таблицы Excel (формат xlsx). Когда я вызываю свой finish (), это приводит к тому, что электронная таблица фактически создается на диске.

fos = new FileOutputStream(reportName);
workbook = new SXSSFWorkbook(FLUSH_SIZE);

.........

    public void finish() throws IOException
    {
        for (Worksheet next : worksheets)
        {
            SXSSFSheet sheet = (SXSSFSheet)next.getSheet();

            for (int i = 0; i < next.getMapping().size(); i++)
            {
                int columnWidth = next.getMapping().get(i).getColumnWidthFromValue() + FONT_MARGIN_OF_ERROR;
                columnWidth = columnWidth > MAX_COL_WIDTH ? MAX_COL_WIDTH : columnWidth;
                sheet.setColumnWidth(i, columnWidth * COL_WIDTH_MULTIPLIER);
            }
        }
        workbook.write(fos);
        fos.close();
        workbook.dispose();
    }

Однако формат xlsx на самом деле представляет собой заархивированный набор файлов. Поскольку мне нужно внести некоторые дополнительные изменения в электронную таблицу после того, как она была создана с помощью apache-poi (они не могут быть выполнены с помощью apache-poi), есть способ заставить apache-poi создавать файлы, но не заархивировать их как xlsx. Поскольку первое, что мне нужно сделать, это разархивировать их, текущая обработка неэффективна, так как poi заархивирует файлы, тогда я должен распаковать их, внести изменения, а затем снова заархивировать их сам.

Нет, потому что XLSX - это заархивированный набор файлов. Файлы никогда не записываются вне формата zip. Что вы не можете понять, как делать с POI? Может, мы сможем вам с этим помочь.

jmarkmurphy 15.03.2018 13:30

Вы говорите, что они сначала записываются непосредственно в zip-архив, а не на диск?

Paul Taylor 15.03.2018 13:33

Если да, то ладно, но было бы полезно записать их на диск, а не в zip-архив. Я использую SXSSF, потому что некоторые электронные таблицы большие и для их создания с использованием подхода dom требуется слишком много памяти. Я хочу форматировать как таблицу, но это не поддерживается с помощью SXXF, и впоследствии это выглядит довольно просто - stackoverflow.com/questions/49093442/…

Paul Taylor 15.03.2018 13:36

Почему бы не использовать методы OPC, предоставляемые POI, для захвата нужных фрагментов файла?

Gagravarr 15.03.2018 13:38

@Gagravarr, что ты имеешь в виду? Я не знаю об этом

Paul Taylor 15.03.2018 13:40

Используя PackagePart sheetpart = opcpackage.getPartsByName(Pattern.compile("/xl/worksheets/sh‌​eet"+sheetnr+".xml")‌​).get(0);, вы можете получить из пакета один из XML-файлов листов. Пример: stackoverflow.com/questions/46601782/…

Axel Richter 15.03.2018 15:15

Правильно, но мне не нужно извлекать лист, на самом деле мне не нужно ничего извлекать из электронной таблицы, так как я создаю ее и имею все данные, мне нужно для каждого листа добавить table.xml в застежка-молния. На самом деле, когда я пишу, это только что пришло мне в голову, могу ли я просто добавить новые файлы в существующий zip-файл без необходимости его распаковывать?

Paul Taylor 15.03.2018 15:20

Также возможна установка новых деталей. В stackoverflow.com/questions/44491860/… я вставляю /word/comments.xml в архив *.docx. Но простого добавления файла xml недостаточно. Также необходимо установить отношения. Но для table*.xml почему бы просто не использовать XSSFTable?

Axel Richter 15.03.2018 15:32

Но как, я не могу использовать XSSFTable, когда я изначально создаю, потому что я использую SXSSF, а его нет в SXSSFSheet. Если я использую его позже, я предполагаю, что для открытия существующей электронной таблицы в памяти потребуется использование poi и, следовательно, снова возникнут проблемы с памятью. На самом деле, что интересно, еще одна вещь, которую я хочу сделать, - это добавить комментарии, они действительно могут быть добавлены при использовании SXSSF, но нагрузка на память слишком высока, поскольку все они хранятся в памяти до тех пор, пока не будет создана электронная таблица.

Paul Taylor 15.03.2018 15:50

@ Пол Тейлор: Значит, вы создаете рабочую тетрадь с нуля? Тогда вы узнаете, как должны быть структурированы таблицы. Затем вы можете сначала создать XSSFWorkbook с пустыми XSSFSheet, имеющими отношения к XSSFTable. Этот объем данных не очень велик (только структура, а не данные). Затем вы можете создать SXSSFWorkbook из этого XSSFWorkbook, а затем выполнить потоковую передачу большого количества данных в листы.

Axel Richter 15.03.2018 17:10

@AxelRichter, это звучит как хорошее решение, на самом деле я попробую это, спасибо.

Paul Taylor 15.03.2018 17:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
11
309
0

Другие вопросы по теме