Генерируем отчеты с помощью FreeMarker
Инструментарий для генерации отчетов вариативен: JasperReports, BIRT, Pentaho. Наш backend-разработчик — Мари — решила попробовать альтернативный способ — FreeMarker. В этой статье она рассмотрела основные плюсы и минусы этого инструмента. Максимально необычно, но интересно :)
В одном из проектов, на исследование был получен FreeMarker. И предложен он был для генерации отчетов. Казалось бы, зачем?
Но интерес был сильнее, а времени на исследование и пробы было достаточно.
Итак, приступим.
Как говорит официальная документация:
Apache FreeMarker — это механизм шаблонов: библиотека Java для генерации текстового вывода (HTML-страницы, xml, файлы конфигурации, исходный код и. т.д).
Схема простая: у нас есть шаблон, в него мы можем сложить любые данные и получить любой доступный выходной формат (их вполне достаточно, чтобы выбрать подходящий).
В данной статье я расскажу обо всем, что нашла в рамках исследования.
Сегодня перед нами стояла задача разработки web-приложения, способного генерировать отчеты в двух форматах: .csv, .pdf.
Как мы уже знаем, сам FreeMarker так не умеет 🙁 Но для чего же нам тогда руки?
Начнем с более простой задачи. Судя по Википедии:
CSV — текстовый формат, предназначенный для представления табличных данных.
А значит, если соблюсти синтаксис формата, нам достаточно выходного формата plaintext.
Для примера будем генерировать отчеты по коммунальным счетчикам и их показателям.
Нам потребуются следующие зависимости (сам FreeMarker и инструмент для генерации документов). Если ваше приложение не использует spring boot, зависимость, конечно, будет другая (находится по первой ссылке в гугле).
Начнем с шаблона:
Как разделитель (#assign delimiter) используем “;” но его можно задавать вне шаблона как и остальные данные, например csvRecords. Заголовки для первой строки лежат в другом шаблоне, чтобы использовать их при генерации таблицы в других документах, шаблон выглядит так:
В блоке <#compress > вызываются макросы writeHeaders, writeColumns для записи заголовка и всех пришедших данных соответственно. FreeMarker дает много возможностей для работы с коллекциями, это хорошо описано в его официальной документации.
Для того, чтобы заполнить шаблон данными, собираем коллекцию из пар “имя в шаблоне” - “значение”. В данном примере происходит это так:
Теперь дело за малым, создаем файл и заполняем необходимыми данными. При этом, не забываем указывать кодировку (!!!), иначе никакой кириллицы мы не увидим.
На выходе получаем файл формата .csv, который можем открыть в табличном редакторе. Кажется, это было достаточно просто.
С pdf-файлами дела сложнее. Мной был выбран такой путь: сначала генерируем html, затем из него pdf (можно было попробовать воспользоваться xml, но как-нибудь в другой раз). Теперь к FreeMarker добавляется библиотека xhtmlrenderer.
Шаблон для такого отчета выглядит уже как html-документ. Как оказалось, для использования в шаблоне нужно закрывать все теги, например:
Но логика заполнения данными все та же, складываем в коллекцию все необходимое:
Для записи в файл можно генерировать как html-файл, так и строку (в данном примере строка, но разницы никакой), отличие лишь в том, какой *Writer вы будете использовать.
Запись в файл выглядит достаточно просто, но тут уже стоит обратить внимание на используемый шрифт. Выбрать нужно тот, который поддерживает используемый алфавит (указываем его и тут, и в шаблоне).
На выходе снова получаем файл.
Казалось бы, можно остановиться. Но как же картинки? Их же можно вставить через шаблон. Вставлять будем как base64. Добавляем в шаблон эту строку, не забывая закрыть тег 🙂
Загружаем картинку из ресурсов (или любого другого места), преобразуем и вставляем в ту же коллекцию с данными для шаблона.
Следующие действия такие же как и раньше. Но на выходе уже документ с душой.
Интерес повел меня еще дальше, и я нашла, что картинки тоже можно генерировать, с помощью той же библиотеки. Для примера создадим печать, у нас же отчет как-никак.
Шаблон формата xhtml, но с html тоже будет работать (все так же не забываем про шрифты и кодировку).
Работаем с шаблоном так же как и выше
А вот генерация картинки выглядит уже вот так. Здесь так же обращаю внимание на шрифт! Также можно задать размер изображения.
Полученное изображение так же преобразуем в base64 и вставляем или используем с другими целями. У меня получилось так:
Какие итоги могу подвести:
- работать с шаблонами мне показалось очень удобным, при должной фантазии можно создавать достаточно сложные шаблоны для разных целей
- доступные выходные форматы дают много возможностей для творчества, можно преобразовать практически во все что угодно, при правильном подходе.
- использовать их в проекте, если отчеты небольшие и простые, вполне себе разумно и не сложно.
- нужно быть внимательным с кодировкой, шрифтами и путям к файлам 🙁 Я не уделила этому внимания первоначально и потратила достаточно времени на то, чтобы разобраться в чем же дело.
- самое интересное в самом простом.
Каждый проект уникален, и для каждого решения есть свой подходящий инструмент. Здесь FreeMarker оправдал наш выбор полностью.
Работали с FreeMarker? Как вам?
Если вы узнали что-то новое и вам было полезно, будем рады положительное оценке под записью 🙂