Дублирование ячеек формулы Apache POI очень медленное - PullRequest
3 голосов
/ 25 февраля 2012

Я создаю файл excel с использованием Apache POI 3.8, и мне нужно реплицировать некоторые существующие строки n раз.

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

Проблема в том, что производительность ужасна, для генерации 4000 строк требуется 2 часа.

Я точно определил, что проблема не в части регулярного выражения, как я изначально думал, а в дублировании ячеек формулы.

Я на самом деле использую это для репликации ячеек формулы:

case Cell.CELL_TYPE_FORMULA:
    newCell.setCellType(oldCell.getCellType());
    newCell.setCellFormula(oldCell.getCellFormula());
    break; 

Если я скопирую формулу в виде текста:

case Cell.CELL_TYPE_FORMULA:
    newCell.setCellType(Cell.CELL_TYPE_STRING);
    newCell.setCellValue("="+oldCell.getCellFormula());
    break;

вместо этого это довольно быстро, даже с моим регулярным выражением.

В любом случае, это несовершенное решение, потому что в формуле есть английские ключевые слова (например, IF ()), когда мне нужно написать в итальянском формате.

Более того, ячейки с такой формулой должны быть принудительно пересмотрены в Excel с помощью чего-то вроде "заменить все -> '=' на '='".

Кажется, проблема связана с setCellFormula () из-за HSSFFormulaParser.parse ().

Что странно, время разбора, кажется, растет в геометрической прогрессии:

100 rows ->  6785ms
200 rows -> 23933ms
300 rows -> 51388ms
400 rows -> 88586ms

Похоже, что каждый раз, когда я копирую формулу, библиотека POI переоценивает или повторно анализирует или повторно что-то для всех предыдущих строк.

Кто-нибудь знает, как можно решить эту проблему? Заранее спасибо.

1 Ответ

3 голосов
/ 27 февраля 2012

О, боже ... кажется, я нашел это ...

Оригинал был:

// If the row exist in destination, push down all rows by 1 else create a new row
if (newRow != null) {
    worksheet.shiftRows(destinationRowNum, worksheet.getLastRowNum(), 1);
} else {
    newRow = worksheet.createRow(destinationRowNum);
}

Я прокомментировал все, оставив только

newRow = worksheet.createRow(destinationRowNum);

И теперь у меня осталось 60 секунд, чтобы обработать все строки!

Возможно, в моем шаблоне есть грязь, из-за которой POI смещает все на каждой итерации.

...