Generating PDF Reports in Kotlin with iText 7
In modern development, there is often a need to create structured PDF documents: reports, invoices, contracts, or analytical summaries. The Kotlin language, thanks to its conciseness and compatibility with Java, is well-suited for this task. One of the most powerful and popular libraries for working with PDF is iText 7 (formerly iTextSharp for .NET). In this article, we will explore how to use it to generate professional PDF reports in Kotlin.
Why iText 7?
- Full control over content: text, tables, images, fonts.
- Performance: the library is optimized for working with large documents.
- Cross-platform: works on JVM, Android, and the web.
- Licensing: AGPL for open-source projects or a commercial license.
Installation (Gradle)
Add the dependency to build.gradle.kts:
dependencies { implementation("com.itextpdf:itext7-core:7.2.5")}Basic Example: "Hello, PDF!"
Let's create a simple PDF document with text:
import com.itextpdf.kernel.pdf.PdfDocumentimport com.itextpdf.kernel.pdf.PdfWriterimport com.itextpdf.layout.Documentimport com.itextpdf.layout.element.Paragraph
fun main() { val writer = PdfWriter("hello.pdf") val pdf = PdfDocument(writer) val document = Document(pdf)
document.add(Paragraph("Hello, PDF world in Kotlin!")) document.close() println("PDF created: hello.pdf")}Creating a Report with Tables and Styles
A real report requires more than just text. Let's add a table, headers, and styles:
import com.itextpdf.kernel.colors.ColorConstantsimport com.itextpdf.kernel.pdf.PdfDocumentimport com.itextpdf.kernel.pdf.PdfWriterimport com.itextpdf.layout.Documentimport com.itextpdf.layout.element.Cellimport com.itextpdf.layout.element.Paragraphimport com.itextpdf.layout.element.Tableimport com.itextpdf.layout.properties.UnitValue
fun generateReport() { val writer = PdfWriter("report.pdf") val pdf = PdfDocument(writer) val document = Document(pdf)
// Title val title = Paragraph("Monthly Sales Report") .setFontSize(20) .setBold() .setTextAlignment(com.itextpdf.layout.properties.TextAlignment.CENTER) document.add(title)
// Table val table = Table(UnitValue.createPercentArray(floatArrayOf(1f, 2f, 1.5f, 1.5f))) table.setWidth(UnitValue.createPercentValue(100))
// Table headers val headers = listOf("ID", "Product", "Quantity", "Price") headers.forEach { header -> val cell = Cell().add(Paragraph(header).setBold()) cell.setBackgroundColor(ColorConstants.LIGHT_GRAY) table.addCell(cell) }
// Data val data = listOf( listOf("1", "Laptop", "3", "150000"), listOf("2", "Mouse", "10", "5000"), listOf("3", "Keyboard", "5", "12500") ) data.forEach { row -> row.forEach { value -> table.addCell(Cell().add(Paragraph(value))) } }
document.add(table) document.close() println("Report created: report.pdf")}
fun main() { generateReport()}Adding Images and Styles
Reports often need to include logos or charts. iText 7 supports images:
import com.itextpdf.kernel.pdf.PdfDocumentimport com.itextpdf.kernel.pdf.PdfWriterimport com.itextpdf.layout.Documentimport com.itextpdf.layout.element.Imageimport com.itextpdf.io.image.ImageDataFactory
fun addImageExample() { val writer = PdfWriter("report_with_image.pdf") val pdf = PdfDocument(writer) val document = Documen