PDF генерация в Kotlin: обзор библиотек и практические примеры
Генерация PDF-документов — одна из частых задач в современных приложениях: от создания отчётов и счетов до экспорта данных. Kotlin, будучи современным JVM-языком, предоставляет разработчикам доступ к мощным Java-библиотекам для работы с PDF. В этой статье мы рассмотрим основные инструменты для генерации PDF в Kotlin, их особенности и примеры использования.
Популярные библиотеки для работы с PDF в Kotlin
Поскольку Kotlin полностью совместим с Java, вы можете использовать любую Java-библиотеку для PDF. Наиболее популярные варианты:
- iText (версия 7/8) — коммерческая библиотека с открытым исходным кодом (AGPL). Предоставляет широкие возможности: создание документов с нуля, работа с формами, водяными знаками, шифрованием. Для коммерческого использования требуется покупка лицензии.
- Apache PDFBox — бесплатная библиотека (Apache 2.0). Позволяет создавать PDF, извлекать текст, заполнять формы. Работает на более низком уровне, чем iText, но даёт полный контроль над содержимым.
- OpenPDF — форк iText 4 (LGPL/MPL). Лёгкая библиотека для базовых задач: создание текста, таблиц, изображений. Подходит для простых проектов без сложной вёрстки.
- Jetpack Compose + PDF — современный подход: вы описываете UI на Compose, а затем конвертируете его в PDF с помощью Android-библиотек (например,
android.graphics.pdf.PdfDocument). Подходит для Android-приложений.
Настройка проекта и подключение зависимостей
Для демонстрации будем использовать iText 7 и Apache PDFBox. Добавьте зависимости в build.gradle.kts:
// Для iText 7
implementation("com.itextpdf:itext7-core:8.0.4")
// Для Apache PDFBox
implementation("org.apache.pdfbox:pdfbox:3.0.2")
Пример 1: Создание PDF с текстом (iText 7)
Создадим простой документ с заголовком и параграфом:
import com.itextpdf.kernel.pdf.PdfDocument
import com.itextpdf.kernel.pdf.PdfWriter
import com.itextpdf.layout.Document
import com.itextpdf.layout.element.Paragraph
fun createSimplePdf() {
val writer = PdfWriter("output.pdf")
val pdf = PdfDocument(writer)
val document = Document(pdf)
document.add(Paragraph("Привет, мир!"))
document.add(Paragraph("Это PDF, созданный с помощью iText в Kotlin."))
document.close()
}
Пример 2: Работа с таблицами и кириллицей (iText 7)
Для корректного отображения кириллицы необходимо загрузить шрифт, поддерживающий Unicode. Используем стандартный шрифт FreeSans или любой TTF-шрифт:
import com.itextpdf.kernel.font.PdfFontFactory
import com.itextpdf.kernel.pdf.PdfDocument
import com.itextpdf.kernel.pdf.PdfWriter
import com.itextpdf.layout.Document
import com.itextpdf.layout.element.Cell
import com.itextpdf.layout.element.Paragraph
import com.itextpdf.layout.element.Table
fun createTableWithCyrillic() {
val writer = PdfWriter("table.pdf")
val pdf = PdfDocument(writer)
val document = Document(pdf)
// Загрузка шрифта с поддержкой кириллицы
val font = PdfFontFactory.createFont("fonts/FreeSans.ttf", "Identity-H")
document.setFont(font)
val table = Table(2) // две колонки
table.addCell(Cell().add(Paragraph("Имя")))
table.addCell(Cell().add(Paragraph("Возраст")))
table.addCell(Cell().add(Paragraph("Анна")))
table.addCell(Cell().add(Paragraph("25")))
table.addCell(Cell().add(Paragraph("Иван")))
table.addCell(Cell().add(Paragraph("30")))
document.add(table)
document.close()
}
Пример 3: Создание PDF с изображением (Apache PDFBox)
PDFBox требует более детальной работы с координатами, но даёт гибкость:
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.pdmodel.PDPage
import org.apache.pdfbox.pdmodel.PDPageContentStream
import org.apache.pdfbox.pdmodel.font.PDType0Font
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject
import java.io.File
fun createPdfWithImage() {
val document = PDDocument()
val page = PDPage()
document.addPage(page)
val contentStream = PDPageContentStream(document, page)
// Загрузка шрифта с кириллицей
val font = PDType0Font.load(document, File("fonts/FreeSans.ttf"))