Pull to refresh

Вышла новая версия Apache POI 3.8

Reading time 5 min
Views 31K
26 Марта вышел новый релиз библиотеки Apache POI — версии 3.8.

Apache POI — это библиотека на языке Java для чтения и записи документов Microsoft Office,
таких как Excel, PowerPoint и Word. С помощью POI вы можете программно создавать новые
или изменять существующие документы, индексировать текст, обрабатывать вложенные
(embedded) объекты (документы, картинки и т.д.) и много чего другого.

Предыдущая стабильная версия Apache POI вышла полтора года назад, в Октябре 2010 года,
поэтому изменений накопилось порядочно. Исправлено более 200 багов, добавлены многочисленные
новые фичи и улучшена общая производительность.


Что нового в POI 3.8?



SXSSF -реализация Spreadsheet API для создания .xlsx файлов большого объема
( > 100K записей) при ограниченном объеме памяти.



Стандартная реализация генератора .xlsx файлов (XSSF) строит в памяти модель всего документа,
т.е. для каждой записи (row) и ячейки (cell) в памяти сидит моделька. Поскольку формат .xlsx основан
на XML, за каждой моделькой стоит XML bean, получаются довольно развесистые структуры и при
генерации больших объемов данных есть шанс получить OutOfMemoryError.

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

Небольшой пример: при запуске с ключем -Xmx128M код ниже вылетает с OutOfMemoryError примерно
после генерации 200000 ячеек:

  Workbook workbook = new XSSFWorkbook(); // keep the whole model in memory 

  Sheet sheet = workbook.createSheet();
  // generate a grid of 1M rows x 256 columns
  for(int i = 0; i < 1000000; i++) {
      Row row = sheet.createRow(i);
      for(int j = 0; j < 256; j++){
          Cell cell = row.createCell(j);
          cell.setCellValue(i*j);
      }
  }

  //  the code never gets to this point because of OutOfMemoryError 
  FileOutputStream out = new FileOutputStream("workbook.xlsx");
  workbook.write(out);
  out.close();


то же самое, но с использованием SXSSF работает без проблем даже с ключем -Xmx64M:
   // keep last 100 rows in memory, flush older rows to disk
    Workbook workbook = new SXSSFWorkbook(100); 

    Sheet sheet = workbook.createSheet();
    // generate a grid of 1M rows x 256 columns
    for(int i = 0; i < 1000000; i++) {
        Row row = sheet.createRow(i);
        for(int j = 0; j < 256; j++){
            Cell cell = row.createCell(j);
            cell.setCellValue(i*j);
        }
    }

    // Voila!  
    FileOutputStream out = new FileOutputStream("workbook.xlsx");
    workbook.write(out);
    out.close();


Обновления в калькуляторе формул (Formula Evaluator)



Поддержка новых функций:

IRR,NPV,MROUND,VAR,VARP,CLEAN,CHAR,ADDRESS,HOUR,MINUTE,SECOND,RATE,WORKDAY,NETWORKDAYS,SUMIFS,RANK

Всего POI поддерживает 140 функций из примерно 300 поддерживаемых в Excel 2010.
Полный список поддерживаемых функций можно посмотреть здесь

Функции определяемые пользователем (User-Defined Functions)

Что делать если формула содержит функцию, которая не поддерживается?
По умолчанию калькулятор формул выкидывает NotImplementedException и происходит это в двух случаях:
  • Функция определена в Excel-е, но не реализована в POI
  • Функция определена в VBA макросе или во внешней add-in библиотеке


POI 3.8 предоставляет вам возможность программно реализовать нужную вам функцию
и зарегистрировать ее в калькуляторе. Примерно так:

  /**
   * CUBEMEMBER: функция для OLAP анализа, не поддерживается в POI-3.8
   */
  FreeRefFunction CUBEMEMBER = new FreeRefFunction() {
      public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
          if(args.length != 3) {
              // функция CUBEMEMBER принимает 3 аргумента
              return ErrorEval.VALUE_INVALID;
          }
          // TODO: implement me

          // пока функция не реализована возвращаем #NUM!
          return ErrorEval.NUM_ERROR;
      }
  };
  WorkbookEvaluator.registerFunction("CUBEMEMBER", CUBEMEMBER);
  // теперь вместо NotImplementedException калькулятор будет вызывать пользовательский код 


Excel Ant tasks

Расширения для Ant-а предназначены для пересчета и проверки формул без написания Java кода.
У этого функционала интересная история: он пришел из научного проекта в котором Excel файлы
создаются third-party софтом, не POI. Файлы содержат как сами данные, так и формулы и нужно
проверять их корректность на серверной стороне, при этом проверяющий не является программистом
на Java и знает только чуть-чуть синтаксис Ant.
С помощью Excel Ant tasks задача сводится к написанию build файлов. Target-ы взаимодействующие
с POI выглядят так:

  <target name="Habratest">
    <excelant fileName="habratest.xls">
      <test >
        <evaluate cell="'Habratest'!$B$4" expectedValue="790.7936" precision="1.0e-4" />
      </test>
    </excelant>
  </target>   


на выходе Ant-а мы увидим следующее:

Habratest:
[excelant] Using input file: habratest.xls
    [test] setting globalPrecision to 0.0010 in the evaluator
[evaluate] test precision = 1.0E-4 global precision = 0.0010
[evaluate] Using evaluate precision of 1.0E-4 over the global precision of 0.0010
[excelant] 1/1 tests passed.


XSLF — Java API для работы с файлами .pptx (PowerPoint 2007-2010)



Теперь POI поддерживает полнофункциональный User API для работы с файлами в формате .pptx.
Вы можете программно создавать новые или редактировать существующие .pptx файлы,
вставлять или менять слайды, текст, картинки, таблицы и прочее.

Ниже неполный список поддерживаемых фич:

  • Создание новых слайдов, в т.ч. с предопределенным дизайном (Заголовок, Заголовок и Текст,
    Заголовок и Картинка и т.п.)
  • Вставка картинок
  • Вставка текстовых блоков с поддержкой параграфов и блоков форматирования
  • Объединение слайдов из нескольких презентаций
  • Таблицы
  • Полная поддержка геометрических объектов определенных в PowerPoint-е:
    от примитивов (rectangle, ellipse) до объектов с произвольной геометрией (freeforms)
  • PPTX2PNG: Конвертация слайдов в картинки


Последнюю фичу, PPTX2PNG, хотелось бы отметить особо: эта утилита с Java main() интерфейсом
конвертирует слайды в картинки PNG, но вы можете взять этот код за основу и написать конвертер
в другие графические форматы (SVG, Flash, HTML5 Canvas и пр.). Все, что вам нужно — это передать
подкласс от java.awt.Graphics2D в метод slide.draw(Graphics2D graphics);

Например, этот пример демонстриурет как конвертировать .pptx слайды в SVG с использованием SVGGraphics2D драйвера из Apache Batik

Конвертеры .doc файлов MS Word в HTML, XSL-FO и текст


Эта функциональность уже упоминалась на Хабре, поэтому отмечу только основное:

  • Word-to-HTML Converter, конвертирующий документ Word в HTML, можно даже с картинками;
  • Word-to-Text Converter, который является заменой для прошлого WordExtractor, корректно обрабатывающий
    вложенные OLE-документы, разбиение на абзацы, коды полей (в том числе гиперссылки);
  • Word-to-FO Converter, конвертирующий документ Word в файл XSL FO, также возможно с картинками.
    Дальше этот файл можно передать на обработку в Apache FOP для конвертации Word в PDF.


Багфиксы, багфиксы и еще больше багфиксов....


Была проведена огромная работа по улучшению стабильности библиотеки в целом
— более 250 изменений с предыдущей версии 3.7. В первую очередь это касается читаемости документов.
Баг-репорты вида «POI не читает мой файл и валится c exception» уже редкость и, я надеюсь, скоро исчезнут совсем :)

Вы нашли баг или хотите поделиться идеями как улучшить проект? Заходите к нам на сайт http://poi.apache.org/, подписывайтесь на листы рассылки и шлите
патчи в Багзилу. You are always welcome!
Tags:
Hubs:
+14
Comments 11
Comments Comments 11

Articles