Производительность POI - PullRequest
19 голосов
/ 23 марта 2010

Я использую POI в своем веб-приложении J2EE для создания рабочей книги. Тем не менее, я обнаружил, что создание POI занимает около 3 минут, чтобы создать рабочую книгу с 25K строк (около 15 столбцов в каждой). Это проблема производительности POI, или это оправдано? Известны ли другие API для повышения производительности?

Ответы [ 5 ]

12 голосов
/ 07 июля 2014

Производительность записи больших файлов с помощью POI может быть значительно снижена, если вы используете «потоковый» API POI вместо стандартного. Действительно, по умолчанию POI будет хранить все ваши данные в памяти перед записью всего за один раз в конце. Объем памяти этого может быть смехотворно большим для больших файлов. Вместо этого с помощью потокового API вы можете контролировать использование памяти и постепенную запись данных на диск.

Чтобы создать потоковую книгу, используйте что-то вроде:

  SXSSFWorkbook book = new SXSSFWorkbook(); 
  book.setCompressTempFiles(true);

  SXSSFSheet sheet = (SXSSFSheet) book.createSheet();
  sheet.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk
  // ...
12 голосов
/ 23 марта 2010

Я был бы очень удивлен, увидев, что POI занимает столько времени для создания такого файла.Я только что сгенерировал лист с 30000 строк по 10 ячеек примерно за 18 секунд (если честно, без форматирования).Причиной может быть одна из следующих причин:

  • Возможно ведение журнала POI, как описано здесь
  • вы работаете из подкачки
  • ваша куча виртуальных машин может быть очень низкой
3 голосов
/ 23 марта 2010

Если ни один из других ответов не сработает, посмотрите, будет ли JExcel Энди Хана лучше. Я считаю, что он намного превосходит POI для работы с Excel в Java.

1 голос
/ 04 января 2012

Я сравнил Apache POI с библиотекой JExcel.Похоже, что JExcel примерно в 4 раза быстрее, чем Apache POI, но потребление памяти выглядит примерно одинаково:

@Test
public void createJExcelWorkbook() throws Exception {
        WritableWorkbook workbook = Workbook.createWorkbook(new File("jexcel_workbook.xls"));
        WritableSheet sheet = workbook.createSheet("sheet", 0); 
        for ( int i=0; i < 65535; i++) {
            for ( int j=0; j < 10; j++) {
                Label label = new Label(j, i, "some text " + i + " " + j);
                sheet.addCell(label);
            }
        }
        workbook.write();
        workbook.close();
}

@Test
public void createPoiWorkbook() throws Exception {
    Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("sheet");  
    for ( int i=0; i < 65535; i++) {
        Row row = sheet.createRow(i);
        for ( int j=0; j < 10; j++) {
            Cell cell = row.createCell(j);
             cell.setCellValue("some text " + i + " " + j);
        }
    }   
    FileOutputStream fileOut = new FileOutputStream("poi_workbook.xls");
    wb.write(fileOut);
    fileOut.close();
}

Я протестировал его с JExcel версии 2.6.12 и Apache POI версии 3.7.,Вам необходимо самостоятельно загрузить последние версии библиотеки и выполнить простые тесты, описанные выше, чтобы получить более точные цифры.

<dependency org="org.apache.poi" name="poi" rev="3.7"/>
<dependency org="net.sourceforge.jexcelapi" name="jxl" rev="2.6.12"/>

Примечание: в Apache POI существует ограничение в 65535 строк на листе.

1 голос
/ 23 марта 2010

Мы также используем POI в нашем веб-приложении и не испытываем никаких проблем с производительностью, хотя наши сгенерированные документы намного меньше, чем ваши.Я бы сначала проверил, является ли POI настоящей проблемой здесь.Попробуйте сгенерировать эти документы без издержек J2EE (Unit-Test) и измерить производительность.Вы также можете отслеживать загрузку и использование памяти на вашем сервере J2EE, чтобы определить, не возникают ли проблемы из-за неоптимальных настроек системы.

...