Генерация PDF отчетов на Kotlin: iText, Apache PDFBox, OpenPDF

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

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

Начать курс

Генерация PDF отчётов на Kotlin: обзор библиотек и практические примеры

Kotlin, будучи современным языком для JVM, отлично подходит для создания серверных приложений, включая генерацию сложных PDF-отчётов. В отличие от Python, где популярны ReportLab или FPDF, в экосистеме Kotlin/Java используются проверенные временем библиотеки: iText, Apache PDFBox и OpenPDF. В этой статье мы разберём каждую из них, покажем примеры кода на Kotlin и дадим рекомендации по выбору.

1. iText (версии 7 и 8)

iText — это де-факто стандарт для генерации PDF на JVM. Библиотека предоставляет мощный API для создания документов с нуля, работы с формами, водяными знаками и цифровыми подписями. Однако начиная с версии 7, iText перешёл на лицензию AGPL (или коммерческую), что важно учитывать при коммерческом использовании.

Пример создания простого PDF с таблицей на Kotlin:

import com.itextpdf.kernel.pdf.PdfDocument
import com.itextpdf.kernel.pdf.PdfWriter
import com.itextpdf.layout.Document
import com.itextpdf.layout.element.Paragraph
import com.itextpdf.layout.element.Table
import com.itextpdf.layout.property.UnitValue

fun generateReportItext(outputPath: String) {
    val writer = PdfWriter(outputPath)
    val pdf = PdfDocument(writer)
    val document = Document(pdf)

    // Заголовок
    document.add(Paragraph("Отчёт о продажах").setFontSize(20))

    // Таблица
    val table = Table(UnitValue.createPercentArray(3)).useAllAvailableWidth()
    table.addCell("Товар")
    table.addCell("Количество")
    table.addCell("Цена")
    table.addCell("Ноутбук")
    table.addCell("10")
    table.addCell("75000")
    table.addCell("Монитор")
    table.addCell("5")
    table.addCell("25000")

    document.add(table)
    document.close()
    println("PDF создан: $outputPath")
}

2. Apache PDFBox

PDFBox — бесплатная библиотека (лицензия Apache 2.0), которая позволяет не только создавать PDF, но и извлекать текст, заполнять формы, рендерить страницы в изображения. API чуть более низкоуровневый, чем у iText, но даёт полный контроль над содержимым.

Пример с изображением и форматированием текста:

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 generateReportPdfBox(outputPath: String) {
    val document = PDDocument()
    val page = PDPage()
    document.addPage(page)

    val contentStream = PDPageContentStream(document, page)
    // Загрузка шрифта (TrueType)
    val font = PDType0Font.load(document, File("fonts/DejaVuSans.ttf"))
    contentStream.setFont(font, 14f)

    // Текст
    contentStream.beginText()
    contentStream.newLineAtOffset(50f, 750f)
    contentStream.showText("Отчёт за январь 2025")
    contentStream.endText()

    // Изображение (логотип)
    val image = PDImageXObject.createFromFile("logo.png", document)
    contentStream.drawImage(image, 50f, 650f, 100f, 50f)

    contentStream.close()
    document.save(outputPath)
    document.close()
    println("PDFBox отчёт готов: $outputPath")
}

3. OpenPDF

OpenPDF — форк старой версии iText (LGPL), который остаётся полностью свободным. Идеально подходит для простых отчётов: текст, таблицы, базовые графические примитивы. API напоминает iText 2.x, но в современном Kotlin-коде это не является проблемой.

Пример создания PDF с параграфами и списком:

import com.lowagie.text.Document
import com.lowagie.text.Paragraph
import com.lowagie.text.pdf.PdfWriter
import java.io.FileOutputStream

fun generateReportOpenPdf(outputPath: String) {
    val document = Document()
    PdfWriter.getInstance(document, FileOutputStream(outputPath))
    document.open()

    document.add(Paragraph("Сводка по проекту"))
    document.add(Paragraph("Дата: 01.02.2025"))
    document.add(Paragraph("Статус: Выполнено"))

    // Список
    document.add(Paragraph("Основные задачи:"))
    document.add(Paragraph("• Разработка модуля авторизации"))
    document.add(Paragraph("• Тестирование API"))
    document.add(Paragraph("• Документирование"))

    document.close()
    println("OpenPDF отчёт сохранён: $outputPath")
}

Сравнение библиотек

  • iText — самый мощный, но требует лицензии для коммерческого использования (AGPL-проекты — бесплатно).

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