Заголовок таблицы в pdf файле не отображается

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

Пробовала добавлять разные библиотеки, работала с циклами и т.д. Ничего не помогло

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;

public class PerfumeApp extends JFrame {
    private DefaultTableModel tableModel;
    private JTable perfumeTable;
    private JButton addManualButton;
    private JButton generateButton;
    private JButton calculateButton;
    private JButton exportButton; // Кнопка для экспорта в PDF

    private String[][] perfumesData = new String[100][7];
    private int currentCount = 0;
    private Random random = new Random();

    private static final String[] NAMES = {"Light Blue", "Nina", "L'Extase", "Black Orchid", "Gabrielle", "Idole",
            "My Land", "Devotion", "Organza", "Angelique Noire", "Love", "My Way", "Ashore", "Poison Midnight",
            "Floral", "All", "Donna", "The Only One", "Uomo", "K by"};
    private static final String[] BRANDS = {"Dolce&Gabbana", "Nina Ricci", "Tom Ford", "Lancome", "Givenchy",
            "Guerlain", "Chloe", "Giorgio Armani", "Amouage", "Dior", "Beas", "Chirton", "Etro", "Feelme", "Grass",
            "Hermes", "Ispalla", "Kenzo", "Mauboussin", "Neo"};
    private static final String[] GENDERS = {"Men", "Women", "Unisex"};

    public PerfumeApp() {
        setTitle("Perfume Table");
        setLayout(new BorderLayout());

        String[] columnNames = {"Название", "Бренд", "Для кого", "Объем (мл)", "Год выпуска", "Цена (руб.)", "Рейтинг"};
        tableModel = new DefaultTableModel(columnNames, 0);
        perfumeTable = new JTable(tableModel);
        JTableHeader header = perfumeTable.getTableHeader();
        header.setFont(new Font("Arial", Font.BOLD, 16));

        add(new JScrollPane(perfumeTable), BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel();
        addManualButton = new JButton("Добавить");
        generateButton = new JButton("Сгенерировать");
        calculateButton = new JButton("Вычислить");
        exportButton = new JButton("Экспорт в PDF");

        buttonPanel.add(addManualButton);
        buttonPanel.add(generateButton);
        buttonPanel.add(calculateButton);
        buttonPanel.add(exportButton);
        add(buttonPanel, BorderLayout.SOUTH);

        // Обработчики событий
        addManualButton.addActionListener(this::addManualRow);
        generateButton.addActionListener(this::generateRandomRow);
        calculateButton.addActionListener(this::calculateData);
        exportButton.addActionListener(this::exportTableToPDF);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 600);
        setVisible(true);
    }

    private void addManualRow(ActionEvent e) {
        if (currentCount >= perfumesData.length) {
            JOptionPane.showMessageDialog(this, "Достигнуто максимальное количество парфюмов.");
            return;
        }

        String name = JOptionPane.showInputDialog("Введите название");
        String brand = JOptionPane.showInputDialog("Введите бренд");
        String gender = JOptionPane.showInputDialog("Введите, для кого");
        int volume = Integer.parseInt(JOptionPane.showInputDialog("Введите объем (мл)"));
        int year = Integer.parseInt(JOptionPane.showInputDialog("Введите год выпуска"));
        int price = Integer.parseInt(JOptionPane.showInputDialog("Введите цену (руб)"));
        double rating = Double.parseDouble(JOptionPane.showInputDialog("Введите рейтинг (от 1 до 5)"));

        // Добавление данных в двумерный массив
        perfumesData[currentCount] = new String[]{name, brand, gender, String.valueOf(volume), String.valueOf(year), String.valueOf(price), String.valueOf(rating)};
        currentCount++;

        // Добавление строки в модель таблицы
        tableModel.addRow(perfumesData[currentCount - 1]);
    }

    private void generateRandomRow(ActionEvent e) {
        if (currentCount >= perfumesData.length) {
            JOptionPane.showMessageDialog(this, "Достигнуто максимальное количество парфюмов.");
            return;
        }

        String name = NAMES[random.nextInt(NAMES.length)];
        String brand = BRANDS[random.nextInt(BRANDS.length)];
        String gender = GENDERS[random.nextInt(GENDERS.length)];
        int volume = 30 + (random.nextInt(8) * 10);
        int year = 1990 + random.nextInt(34);
        int price = 3000 + random.nextInt(17001);
        double rating = Math.round((1 + (5 - 1) * random.nextDouble()) * 10.0) / 10.0;

        // Добавление данных в двумерный массив
        perfumesData[currentCount] = new String[]{name, brand, gender, String.valueOf(volume), String.valueOf(year), String.valueOf(price), String.valueOf(rating)};
        currentCount++;

        // Добавление строки в модель таблицы
        tableModel.addRow(perfumesData[currentCount - 1]);
    }

    private void calculateData(ActionEvent e) {
        if (currentCount == 0) {
            JOptionPane.showMessageDialog(this, "Таблица пуста.");
            return;
        }

        int[] counts = new int[6];
        calculateCounts(0, counts);

        String result = String.format(
                "Количество парфюмов с высоким рейтингом: %d\n" +
                        "Количество парфюмов со средним рейтингом: %d\n" +
                        "Количество парфюмов с низким рейтингом: %d\n" +
                        "Количество парфюмов для мужчин: %d\n" +
                        "Количество парфюмов для женщин: %d\n" +
                        "Количество унисекс парфюмов: %d",
                counts[0], counts[1], counts[2], counts[3], counts[4], counts[5]
        );

        JOptionPane.showMessageDialog(this, result);
    }

    private void calculateCounts(int index, int[] counts) {
        if (index >= currentCount) {
            return;
        }

        double rating = Double.parseDouble(perfumesData[index][6]);
        String gender = perfumesData[index][2];

        if (rating >= 4) {
            counts[0]++;
        } else if (rating >= 3) {
            counts[1]++;
        } else {
            counts[2]++;
        }

        switch (gender) {
            case "Men":
                counts[3]++;
                break;
            case "Women":
                counts[4]++;
                break;
            case "Unisex":
                counts[5]++;
                break;
        }

        calculateCounts(index + 1, counts);
    }

    private void exportTableToPDF(ActionEvent e) {
        String filePath = JOptionPane.showInputDialog("Введите путь для сохранения PDF-файла:");
        if (filePath == null || filePath.trim().isEmpty()) {
            JOptionPane.showMessageDialog(this, "Путь не может быть пустым.");
            return;
        }

        Document document = new Document();
        try {
            PdfWriter.getInstance(document, new FileOutputStream(filePath));
            document.open();

            // Добавление заголовка PDF-документа
            document.add(new Paragraph("Данные о парфюмах"));
            document.add(new Paragraph(" ")); // Пустой параграф для отступа

            // Создание таблицы для PDF
            PdfPTable pdfTable = new PdfPTable(7); // 7 столбцов

            // Заголовки столбцов
            for (String columnName : new String[]{"Название", "Бренд", "Для кого", "Объем (мл)", "Год выпуска", "Цена (руб.)", "Рейтинг"}) {
                pdfTable.addCell(columnName);
            }

            // Данные в таблице
            for (int i = 0; i < currentCount; i++) {
                for (String cellData : perfumesData[i]) {
                    pdfTable.addCell(cellData);
                }
            }

            document.add(pdfTable); // Добавление таблицы в документ

        } catch (DocumentException | IOException ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "Ошибка при сохранении PDF.");
        } finally {
            document.close();
            JOptionPane.showMessageDialog(this, "Таблица успешно экспортирована в PDF.");
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new PerfumeApp());
    }
}

Ответы (1 шт):

Автор решения: Min Jimin

Всё, я нашла проблему: не поддерживался русский язык в шапке таблицы, надо было все файлы со шрифтами ttf закинуть в папку проекта, тогда всё получилось.

→ Ссылка