Медленные XSSFWorkbook и WorkbookFactory при чтении файлов xlsx

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

Workbook wb = WorkbookFactory.create(new File("spreadsheet.xlsx"));

и

File file = new File("C:\\spreadsheet.xlsx");
OPCPackage opcPackage = OPCPackage.open(file.getAbsolutePath());
XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);

и любой из подходов занимает около 5-6 минут (если приложению не хватает памяти) для обработки простого и довольно небольшого файла электронной таблицы.xlsx (200 КБ).

Что мне нужно сделать, чтобы исправить это? (Я использую Apache POI 3.9)

/*****************************/

Процесс занимает много времени в следующем месте:

public class XSSFSheet extends POIXMLDocumentPart implements Sheet{
...
protected void read(InputStream is) throws IOException {
    try {
      -->>> worksheet = WorksheetDocument.Factory.parse(is).getWorksheet();
    } catch (XmlException e){
        throw new POIXMLException(e);
    }
}
...

Я не могу отлаживать дальше. VisualVM также говорит то же самое..!


person Mohammad Najar    schedule 26.02.2014    source источник
comment
Я только что попробовал на своей машине файл .xlsx размером 305 КБ с кучей Java в несколько сотен МБ, и POI открыл его менее чем за секунду! Я могу только предложить вам перепроверить, действительно ли вы используете ту версию Apache POI, о которой вы думаете, а затем использовать профилировщик, чтобы увидеть, куда идет время.   -  person Gagravarr    schedule 27.02.2014
comment
Спасибо, Гаграварр. Я уже увеличил размер кучи до 512 МБ. У меня около 25000 строк данных, и каждая строка имеет 20 столбцов (просто используйте 111 в каждой ячейке). Это занимает довольно много времени. В реальной ситуации у меня будет более 50 тысяч строк данных.   -  person Mohammad Najar    schedule 27.02.2014
comment
Я открыл xlsx файлов с более чем 30 тысячами строк и более чем 100 столбцами менее чем за несколько секунд. Я понятия не имею, как это может быть так медленно для вас. Я бы посоветовал вам попробовать профилировать с помощью VisualVM и посмотреть, что делает его таким медленным.   -  person Jonathan Drapeau    schedule 27.02.2014
comment
На моей машине с помощью SSPerformanceTest я могу сгенерировать файл .xls из 25 тыс. строк и 20 столбцов за 3 секунды, а файл .xlsx — за 7 секунд. Затем я использовал ToCSV, чтобы прочитать его с помощью HSSF или XSSF и сгенерировать CSV, с .xls это заняло 4 секунды, с .xlsx — 9 секунд. Итак, похоже, проблема все еще на вашей стороне, а не в Apache POI!   -  person Gagravarr    schedule 27.02.2014
comment
Генерация xlsx происходит довольно быстро. Вот только с чтением у меня проблемы. Я попробовал это на двух разных коробках и получил одинаковые результаты. Поэтому я хочу убедиться, что все вы использовали фрагмент кода, который я разместил выше, для чтения файлов!   -  person Mohammad Najar    schedule 27.02.2014


Ответы (1)


Одним из факторов, который может влиять на время загрузки, является то, что данные были вставлены в рабочий лист, так что используемый диапазон включает каждую строку, т. е. когда вы используете количество строк sheet.usedrange, он возвращает> 1 000 000 строк. Не уверен, как это происходит, но я обнаружил, что мне нужно выполнить промежуточный шаг, на котором перед загрузкой книги я «очистил» ее с помощью некоторого сценария vba. Рабочая книга содержит около 20 листов по 5000 строк в каждом, каждый из которых заполнен разными частями бизнеса, и загрузка занимает довольно много времени (может быть, 4 минуты), но в данном случае это приемлемо. Прежде чем я добавил этап очистки, он работал более 30 минут, что было неприемлемо....

Пользователь запускает процесс, о котором я говорю, но нажимает две кнопки. Первый убирает, второй делает все остальное. Первый процесс запускается с помощью Runtime.getruntime.exec и создает пустой текстовый файл, который второй процесс не запустит, если не будет тестового файла.

person Benjamin James    schedule 16.03.2015