PDF генерация в Kotlin: обзор библиотек и инструментов

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

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"))                    

Рекомендаций