1. Введение
Во время выполнения проекта возникла необходимость в функции, позволяющей пользователям загружать данные смет и документов в формате PDF.
Сначала я думал, что достаточно просто создать PDF-файл, но на самом деле в процессе проверки возникло множество факторов, которые нужно учитывать.
-
Поддержка вывода на корейском
-
Удобство редактирования макета
-
Проблемы с лицензированием
-
Производительность разработки
-
Поддерживаемость
Особенно с учетом характера работы, где часто поступают запросы на изменение форматов документов, важным требованием стало не столько создание PDF, сколько то, насколько легко можно редактировать макет.
В связи с этим мы проверили несколько библиотек PDF и провели процесс выбора подходящей технологии для проекта.
2. Обзор библиотек
iText
iText — это самая известная библиотека PDF в экосистеме Java.
Она богата функциями и имеет много примеров, поэтому уровень сложности реализации был невысоким.
Однако при коммерческом использовании существуют лицензионные ограничения, и для внедрения в проект потребуется дополнительная проверка.
OpenPDF
OpenPDF — это библиотека с открытым исходным кодом на базе iText, доступная для бесплатного использования.
Однако стиль необходимо было писать непосредственно на уровне объектов.
С увеличением сложности структуры документа объем кода возрастал, что, по нашему мнению, увеличивало нагрузку на обслуживание.
Apache PDFBox
PDFBox отличалась высокой производительностью и стабильностью.
Однако, поскольку большинство макетов нужно было разрабатывать на основе координат, затраты на разработку были высокими.
Даже простое изменение позиции требовало исправления координат, что затрудняло гибкое реагирование на изменения дизайна экранов.
OpenHTMLtoPDF
OpenHTMLtoPDF — это библиотека, которая преобразует HTML в PDF.
Самым большим преимуществом было то, что можно было использовать HTML и CSS в чистом виде.
Особенно хорошей находкой стало возможность повторного использования существующих активов публикации, а также то, что редактирование макетов было возможным на уровне HTML, что улучшало удобство обслуживания.
Однако программа не поддерживает весь уровень CSS браузера, поэтому существуют ограничения для некоторых сложных макетов.
3. Окончательный выбор
В конечном итоге мы сравнили в основном OpenPDF и OpenHTMLtoPDF.
|
Элемент |
OpenPDF |
OpenHTMLtoPDF |
|---|---|---|
|
Уровень сложности |
Средний |
Низкий |
|
Редактирование макета |
Сложно |
Легко |
|
Использование HTML |
Невозможно |
Возможно |
|
Бесплатное использование |
Возможно |
Возможно |
|
поддерживаемость |
обычный |
высокий |
Из-за особенностей проекта была необходимость часто изменять PDF-формат, поэтому мы уделили особое внимание производительности разработки и поддерживаемости.
В связи с этим мы выбрали OpenHTMLtoPDF в качестве окончательного решения.
4. Процесс реализации
Реализация состоит из трех основных этапов.
-
Запрос бизнес-данных.
-
Создание HTML-шаблона на основе данных.
-
Конвертация в PDF-файл с помощью OpenHTMLtoPDF.
Применяя эту структуру, мы смогли отделить логику создания PDF от логики отображения экрана, и даже если будут добавлены новые форматы в будущем, можно будет повторно использовать тот же процесс создания, просто добавив новый HTML-шаблон.
5. Проблемы и соображения по безопасности
OpenHTMLtoPDF не поддерживает корейский шрифт по умолчанию.
Поэтому может возникнуть проблема с отображением корейских символов, и для ее решения необходимо добавить шрифт, поддерживающий корейский, в ресурсы, и builder.useFont()Мы можем решить эту проблему, явно сопоставляя шрифты на этапе создания строителя через метод.
Кроме того, OpenHTMLtoPDF — это библиотека для рендеринга HTML и создания PDF.
Таким образом, если пользовательские вводимые значения вставляются в HTML без изменений, это может привести к внедрению нежелательных HTML-тегов и изменению структуры документа.
Чтобы избежать этого, мы применили HtmlUtils.htmlEscape() ко всем пользовательским вводимым значениям при создании HTML, чтобы HTML-теги были преобразованы в строки, и пользовательский ввод не влиял на структуру HTML.
Кроме того, HTML-шаблоны управляются на сервере, и пользовательский ввод предназначен только для вставки в заданные места внутри шаблона.
В частности, для изображений (img), стилей (style) и внешних URL-адресов ресурсов в области, где может происходить рендеринг внешних ресурсов, мы гарантируем, что пользовательские вводимые значения не будут затронуты, чтобы избежать нежелательного доступа к ресурсам.
Это позволяет минимизировать возможность изменения структуры HTML из-за пользовательского ввода и снизить риски безопасности в процессе создания PDF.
6. Результаты применения
После внедрения OpenHTMLtoPDF мы смогли достичь следующих результатов.
-
Возможность быстрой разработки на основе HTML/CSS
-
Снижение затрат на изменение макета
-
Возможность повторного использования материалов в публикации
-
Снижение лицензирования за счет использования бесплатного открытого исходного кода
Особенно в том, что изменения в шаблоне HTML можно было вносить без изменения Java-кода, это было самым большим преимуществом с точки зрения обслуживания.
7. Заключение
Функция генерации PDF может показаться относительно простой задачей.
Однако на самом деле необходимо учитывать множество факторов, таких как лицензирование, поддерживаемость, безопасность и поддержка корейского языка.
Эта работа вновь напомнила мне о важности не просто взгляда на функциональность при выборе технологий, но и о необходимости учитывать долгосрочные затраты на обслуживание и удобство эксплуатации.
Ссылка
1. https://github.com/danfickle/openhtmltopdf
Novin