Я не могу создать PDF/A

Я пытаюсь создать PDF/A-1b на Java, я пробовал много разных вещей, но ни один из них мне не помог, каждый PDF-файл, который я генерирую, не способен пройти проверку PDF/A. (Я использую VeraPDF для проверки.)

Мой код на данный момент:

public byte[] convertirAPdfA(byte[] pdf) throws IOException, DocumentException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        // Leer el documento PDF original
        PdfReader reader = new PdfReader(pdf);
        Document document = new Document(reader.getPageSizeWithRotation(1));

        // Crear un PdfAWriter para escribir el nuevo PDF/A
        PdfAWriter writer = PdfAWriter.getInstance(document, outputStream, PdfAConformanceLevel.PDF_A_1B);

        // Abrir el documento para escribir
        document.open();

        // Crear y agregar XmpMetadata
        writer.createXmpMetadata();

        // Crear y embeder el perfil ICC
        ICC_Profile icc = ICC_Profile.getInstance(getClass().getResourceAsStream("/icc/sRGB-IEC61966-2.1.icc"));
        writer.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);

        // Crear la fuente
        BaseFont font = BaseFont.createFont("/fonts/BookAntiqua/BookAntiqua.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        writer.getDirectContent().setFontAndSize(font, 12);

        // Añadir páginas del PDF original al nuevo PDF/A
        PdfContentByte cb = writer.getDirectContent();
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            document.newPage();
            PdfImportedPage page = writer.getImportedPage(reader, i);
            cb.addTemplate(page, 0, 0);
        }

        // Crear los metadatos XMP
        XMPMeta xmpMeta = XMPMetaFactory.create();

        try {
            // Agregar metadatos DC (Dublin Core)
            xmpMeta.setProperty(XMPConst.NS_DC, "dc:format", "application/pdf");
            xmpMeta.setProperty(XMPConst.NS_DC, "dc:title", "Title of the Document");
            xmpMeta.setProperty(XMPConst.NS_DC, "dc:creator", "Your Name");
            xmpMeta.setProperty(XMPConst.NS_DC, "dc:description", "Description of the document");

            // Agregar esquema de identificación PDF/A
            XMPMetaFactory.getSchemaRegistry().registerNamespace("http://www.aiim.org/pdfa/ns/id/", "pdfaid");
            xmpMeta.setProperty("http://www.aiim.org/pdfa/ns/id/", "pdfaid:part", "1");
            xmpMeta.setProperty("http://www.aiim.org/pdfa/ns/id/", "pdfaid:conformance", "B");

            // Serializar los metadatos XMP a un byte array
            ByteArrayOutputStream xmpOutputStream = new ByteArrayOutputStream();
            XMPMetaFactory.serialize(xmpMeta, xmpOutputStream, new SerializeOptions().setUseCompactFormat(true));

            // Establecer los metadatos XMP en el documento
            writer.setXmpMetadata(xmpOutputStream.toByteArray());
        } catch (XMPException e) {
            e.printStackTrace();
        }

        // Cerrar el documento y el lector
        document.close();
        reader.close();

        // Retornar el PDF/A como byte[]
        return outputStream.toByteArray();
    }

Я использую проект Maven и имею зависимости:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-pdfa</artifactId>
    <version>5.5.13.1</version>
</dependency>

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.1</version>
</dependency>

На данный момент я тестирую код с использованием оригинального PDF/A, который проходит проверку, но, как я пишу вначале, результат не в порядке.

Ошибка валидатора:

MainXMPPackage  
Identification_size == 1    
root/document[0]/metadata[0](2 0 obj PDMetadata)/XMPPackage[0]
The document metadata stream doesn't contains PDF/A Identification Schema

Вы импортируете страницы из произвольного PDF-файла в свой новый документ. Это не делает их совместимыми с PDF/A, они импортируются такими, какие есть. И даже если они изначально были совместимы с PDF/A, необходимые метаданные не копируются. Вам следует попробовать создать PDF/A с помощью PdfAWriter, добавив текст и таблицы, используя экземпляры Paragraph и PdfPTable.

mkl 27.08.2024 17:02
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После некоторого тестирования у меня есть рабочий код, способный генерировать PDF/A-1A и PDF/A-1B. Он использует массив байтов PDF в качестве параметра и индикатора уровня соответствия.

Также я публикую код, который пришел, чтобы проверить уровень соответствия существующего PDF-файла.

public byte[] transformAPdfA(byte[] documento, PdfAConformanceLevel nivelPdfA) throws IOException, DocumentException {

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    PdfReader reader = new PdfReader(documento);
    Document document = new Document(reader.getPageSizeWithRotation(1));
    PdfAConformanceLevel conformanceLevel = (nivelPdfA == PdfAConformanceLevel.PDF_A_1A) ?
            PdfAConformanceLevel.PDF_A_1A : PdfAConformanceLevel.PDF_A_1B;
    PdfAWriter writer = PdfAWriter.getInstance(document, outputStream, conformanceLevel);

    if (nivelPdfA == PdfAConformanceLevel.PDF_A_1A) {
        writer.setTagged();
    }

    document.open();
    writer.createXmpMetadata();

    writer.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1",
            ICC_Profile.getInstance(getClass().getResourceAsStream("/icc/sRGB-IEC61966-2.1.icc")));

    writer.getDirectContent().setFontAndSize(BaseFont.createFont("/fonts/BookAntiqua/BookAntiqua.ttf",
            BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 12);

    document.close();
    reader.close();

    return outputStream.toByteArray();
}

public PdfAConformanceLevel obtainPdfaConformanceLevel(byte[] documento) throws AmapCsvPdfServiceException {
    PdfReader reader;
    byte[] metadataBytes = null;
    
    try {
        reader = new PdfReader(documento);
        metadataBytes = reader.getMetadata();
        reader.close();
    
        if (metadataBytes != null) {
            
            XMPMeta xmpMeta;
            xmpMeta = XMPMetaFactory.parseFromBuffer(metadataBytes);

            String pdfaPart = xmpMeta.getPropertyString("http://www.aiim.org/pdfa/ns/id/", "pdfaid:part");
            String pdfaConformance = xmpMeta.getPropertyString("http://www.aiim.org/pdfa/ns/id/", "pdfaid:conformance");

            if ("1".equals(pdfaPart)) {
                if ("A".equalsIgnoreCase(pdfaConformance)) {
                    return PdfAConformanceLevel.PDF_A_1A;   //PDF/A-1A
                } else if ("B".equalsIgnoreCase(pdfaConformance)) {
                    return PdfAConformanceLevel.PDF_A_1B;   //PDF/A-1B
                }
            }
        }
    } catch (XMPException | IOException e) {
        throw new AmapCsvPdfServiceException("Error al obtener la informacion de Conformidad PDF/A", e);
    }
    
    return null; // No es un PDF/A o no se pudo determinar la conformidad
}

Другие вопросы по теме

Как конвертировать несколько файлов SVG в PDF-файлы
Process.Start(...) внезапно завершается с ошибкой при вызове ASP.NET MVC 5, работающем в IIS в Windows 10 и Windows Server 2019
Выход параметризованного PDF-файла R Markdown с использованием механизма xelatex не удалось скомпилировать при включении ggplot
Использование Ghostscript для пакетного добавления номеров страниц
Строка Python: извлеките дублированную и случайно объединенную подстроку
JsPDF png и пользовательский ttf не работают при использовании вывода()
Способ конвертировать латексный файл в PDF только с помощью Python? (без необходимости что-либо устанавливать локально)
Как при использовании PyPDF2 для Python перенести данные в формате CSV в существующий PDF-файл с пустыми полями формы?
Я использую пользовательское преобразование, PNG в порядке, но PDF-файл пуст
Как создать таблицу, занимающую несколько страниц, с помощью Quarto и Typst