iText 7 для Java: полное руководство с примерами

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

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

Начать курс

iText 7 для Java: Полное руководство по созданию и редактированию PDF

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

Зачем нужна iText 7? В современном мире PDF является универсальным форматом для обмена документами, гарантирующим неизменность отображения на любых устройствах. Ручное создание PDF-файлов трудоемко и неэффективно, особенно при работе с большими объемами данных. iText 7 автоматизирует этот процесс, предоставляя Java-разработчикам полный контроль над каждым аспектом документа: от добавления текста и изображений до создания интерактивных форм и управления правами доступа. Она незаменима в системах документооборота, электронной коммерции, банковском деле и любых других приложениях, где требуется генерация или обработка PDF.

Библиотека поддерживает все последние спецификации PDF, включая PDF 2.0. Она также предоставляет дополнительные модули (add-ons) для работы с HTML-конвертацией (pdfHTML), оптическим распознаванием символов (pdfOCR), созданием SVG (pdfSVG) и обработкой изображений (pdfImage). Важно отметить, что iText 7 распространяется под двойной лицензией: AGPL (требует открытия исходного кода вашего приложения) и коммерческой (для проприетарного использования).

Установка

Для установки iText 7 в ваш проект на Java используется система сборки Maven или Gradle. Ниже приведена точная команда для добавления зависимостей в файл pom.xml (Maven).

<!-- pom.xml -->
<dependencies>
    <!-- Основной модуль iText 7 -->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itext7-core</artifactId>
        <version>8.0.4</version> <!-- Проверьте актуальную версию на Maven Central -->
        <type>pom</type>
    </dependency>
</dependencies>

Для Gradle (build.gradle):

implementation 'com.itextpdf:itext7-core:8.0.4'

Если вам нужны только определенные модули (например, kernel, layout, io), вы можете подключать их по отдельности:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>kernel</artifactId>
    <version>8.0.4</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>layout</artifactId>
    <version>8.0.4</version>
</dependency>

Быстрый старт: минимальный рабочий пример

Следующий код создает простой PDF-документ с текстом "Hello, World!" и сохраняет его в файл HelloWorld.pdf.

import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;

import java.io.FileNotFoundException;

public class HelloWorld {
    public static void main(String[] args) throws FileNotFoundException {
        // 1. Создаем PdfWriter, который будет записывать данные в файл
        PdfWriter writer = new PdfWriter("HelloWorld.pdf");
        
        // 2. Создаем PdfDocument — объект, представляющий сам PDF-документ
        PdfDocument pdf = new PdfDocument(writer);
        
        // 3. Создаем Document — высокоуровневый объект для добавления элементов (текст, таблицы и т.д.)
        Document document = new Document(pdf);
        
        // 4. Добавляем абзац с текстом
        document.add(new Paragraph("Hello, World!"));
        
        // 5. Закрываем документ (обязательно!)
        document.close();
        
        System.out.println("PDF создан успешно!");
    }
}

Основные классы и методы

Ниже приведены ключевые классы и методы iText 7, которые вы будете использовать чаще всего.

1. PdfWriter

Сигнатура: PdfWriter(String filename) или PdfWriter(OutputStream outputStream)

Что делает: Создает объект, который управляет записью байтов PDF в файл или поток вывода. Это точка входа для создания нового PDF-документа.

PdfWriter writer = new PdfWriter("output.pdf");
// или в OutputStream:
PdfWriter writer = new PdfWriter(new FileOutputStream("output.pdf"));

2. PdfReader

Сигнатура: PdfReader(String filename) или PdfReader(InputStream inputStream)

Что делает: Создает объект для чтения существующего PDF-документа. Используется для редактирования или анализа PDF.

PdfReader reader = new PdfReader("existing.pdf");
PdfDocument pdfDoc = new PdfDocument(reader, new PdfWriter("modified.pdf"));

3. PdfDocument

Сигнатура: PdfDocument(PdfWriter writer) или PdfDocument(PdfReader reader, PdfWriter writer)

Что делает: Представляет собой модель PDF-документа. Управляет страницами, метаданными и другими глобальными свойствами.

PdfDocument pdf = new PdfDocument(new PdfWriter("doc.pdf"));
// Добавление новой страницы
PdfPage page = pdf.addNewPage();
// Установка метаданных
pdf.getDocumentInfo().setTitle("My Document");

4. Document

Сигнатура: Document(PdfDocument pdfDoc)

Что делает: Высокоуровневый контейнер для добавления элементов (текст, таблицы, изображения) на страницы. Автоматически управляет переносом строк и разбиением на страницы.

Document document = new Document(pdf);
document.add(new Paragraph("Some text"));
document.add(new Table(new float[]{1, 2}));
document.close();

5. Paragraph

Сигнатура: Paragraph(String text) или Paragraph()

Что делает: Представляет собой блок текста. Поддерживает форматирование (шрифт, размер, цвет, выравнивание) и добавление встроенных элементов (например, Text или Image).

Paragraph p = new Paragraph("Hello")
    .setFontSize(20)
    .setBold()
    .setFontColor(ColorConstants.RED);
document.add(p);

6. Table

Сигнатура: Table(float[] columnWidths) или Table(int numColumns)

Что делает: Создает таблицу с заданными ширинами столбцов. Ячейки добавляются с помощью метода addCell().

Table table = new Table(new float[]{1, 3, 2});
table.addCell("Name");
table.addCell("Description");
table.addCell("Price");
table.addCell("Item 1");
table.addCell("Description of item 1");
table.addCell("$10.00");
document.add(table);

7. Cell

Сигнатура: Cell() или Cell(int rowspan, int colspan)

Что делает: Представляет собой ячейку таблицы. Позволяет задавать фон, границы, выравнивание и добавлять вложенные элементы.

Cell cell = new Cell(1, 2) // rowspan=1, colspan=2
    .add(new Paragraph("Merged Cell"))
    .setBackgroundColor(ColorConstants.LIGHT_GRAY);
table.addCell(cell);

8. Image

Сигнатура: Image(ImageData imageData)

Что делает: Вставляет изображение в документ. ImageData создается фабричным методом ImageDataFactory.create(String path).

ImageData imageData = ImageDataFactory.create("logo.png");
Image img = new Image(imageData)
    .setWidth(100)
    .setHeight(50);
document.add(img);

9. List

Сигнатура: List()

Что делает: Создает маркированный или нумерованный список. Элементы добавляются методом add(String item) или add(ListItem item).

List list = new List()
    .setListSymbol(ListNumberingType.DECIMAL);
list.add("First item");
list.add("Second item");
document.add(list);

10. PdfAcroForm

Сигнатура: PdfAcroForm.getAcroForm(PdfDocument pdfDoc, boolean createIfNotExist)

Что делает: Управляет интерактивными формами (AcroForms) в PDF. Позволяет добавлять текстовые поля, флажки, раскрывающиеся списки и т.д.

PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfTextFormField nameField = PdfTextFormField.createText(pdf, new Rectangle(36, 700, 100, 20), "name", "Enter name");
form.addField(nameField);

Реальный практический пример: Генерация счета-фактуры

В этом примере мы создадим полноценный PDF-документ счета-фактуры, содержащий логотип, заголовок, таблицу с товарами и итоговую сумму.

import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.font.PdfFont;
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.borders.Border;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.UnitValue;

import java.io.FileNotFoundException;
import java.io.IOException;

public class InvoiceGenerator {

    public static void main(String[] args) throws IOException {
        String dest = "invoice.pdf";
        PdfWriter writer = new PdfWriter(dest);
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf);

        // Загрузка шрифта для поддержки кириллицы (если нужно)
        PdfFont font = PdfFontFactory.createFont("fonts/arial.ttf", "Cp1251", true);
        document.setFont(font);

        // 1. Заголовок счета
        Paragraph header = new Paragraph("СЧЕТ-ФАКТУРА № 12345")
                .setFontSize(24)
                .setBold()
                .setTextAlignment(TextAlignment.CENTER);
        document.add(header);

        // 2. Информация о компании и клиенте
        document.add(new Paragraph("Продавец: ООО \"Ромашка\""));
        document.add(new Paragraph("Покупатель: ИП Иванов И.И."));
        document.add(new Paragraph("Дата: 15.10.2024"));
        document.add(new Paragraph("Срок оплаты: 30 дней"));
        document.add(new Paragraph(" ")); // Пустая строка для отступа

        // 3. Таблица с товарами
        Table table = new Table(new float[]{1, 4, 2, 2, 2});
        table.setWidth(UnitValue.createPercentValue(100));

        // Заголовки таблицы
        String[] headers = {"№", "Наименование", "Кол-во", "Цена", "Сумма"};
        for (String h : headers) {
            Cell cell = new Cell().add(new Paragraph(h).setBold().setFontSize(10));
            cell.setBackgroundColor(ColorConstants.LIGHT_GRAY);
            cell.setTextAlignment(TextAlignment.CENTER);
            table.addCell(cell);
        }

        // Данные товаров
        Object[][] items = {
                {1, "Товар А", 2, 1000.00, 2000.00},
                {2, "Товар Б (услуга)", 1, 5000.00, 5000.00},
                {3, "Товар В", 5, 300.00, 1500.00}
        };

        for (Object[] item : items) {
            table.addCell(new Cell().add(new Paragraph(String.valueOf(item[0]))).setTextAlignment(TextAlignment.CENTER));
            table.addCell(new Cell().add(new Paragraph((String) item[1])));
            table.addCell(new Cell().add(new Paragraph(String.valueOf(item[2]))).setTextAlignment(TextAlignment.CENTER));
            table.addCell(new Cell().add(new Paragraph(String.format("%.2f", (Double) item[3]))).setTextAlignment(TextAlignment.RIGHT));
            table.addCell(new Cell().add(new Paragraph(String.format("%.2f", (Double) item[4]))).setTextAlignment(TextAlignment.RIGHT));
        }

        document.add(table);

        // 4. Итоговая строка
        double total = 0;
        for (Object[] item : items) {
            total += (Double) item[4];
        }

        Table totalTable = new Table(new float[]{5, 2});
        totalTable.setWidth(UnitValue.createPercentValue(100));
        totalTable.addCell(new Cell().add(new Paragraph("Итого:").setBold()).setBorder(Border.NO_BORDER).setTextAlignment(TextAlignment.RIGHT));
        totalTable.addCell(new Cell().add(new Paragraph(String.format("%.2f", total)).setBold()).setBorder(Border.NO_BORDER).setTextAlignment(TextAlignment.RIGHT));
        document.add(totalTable);

        //                    

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