Преобразование в PDF/A с помощью Jodconverter

Преобразование в PDF/A с помощью Jodconverter

Стоит задача сделать возможность сохранения текущей страницы в PDF. Обычное такое преобразование, куча библиотек на эту тему (например: iText, PDFbox, даже микросервис pdf-bot), если бы не одно «НО»: формат должен быть PDF/A. Т.е. формат для долгосрочного хранения, содержащий в теле файла шрифты, метаинформацию, цветовой профиль и т.д. — в общем все, что нужно для корректного отображения, независимо от платформы.

Библиотека Jodconverter является прослойкой между приложением и OpenOffice (или LibreOffice), который умеет конвертировать в PDF/A.

Стандартное преобразование:

    public static void main(String[] args) throws OfficeException {
        OfficeManager officeManager = LocalOfficeManager.make();
        DocumentConverter converter = LocalConverter.make(officeManager);

        System.out.println("officeManager start");
        officeManager.start();
        try {
            System.out.println("convert start");

            File inputFile = new File("c:/jServers/1/www1.html");
            File pdfFile = new File("c:/jServers/test_W.pdf");


            DocumentFormatRegistry registry = converter.getFormatRegistry();
            DocumentFormat htmlFormat = registry.getFormatByExtension("html");
            DocumentFormat pdfFormat = registry.getFormatByExtension("pdf");

            converter.convert(inputFile).as(htmlFormat).to(pdfFile).as(pdfFormat).execute();

            System.out.println("convert end");
        } catch (OfficeException e) {
            e.printStackTrace();
        } finally {
            if (officeManager.isRunning())
                officeManager.stop();
        }
    }

В результате мы получим обычный pdf.

Для нашей задачи необходимо включить настройку при экспорте. Вот так это выглядит в самом OpenOffice:

Для этого в коде мы должны создать свой собственный формат.

    private static DocumentFormat getDocumentFormatPDFA() {
        final int PDFX1A2001 = 1;

        final Map<String, Integer> pdfOptions = new HashMap<>();
        pdfOptions.put("SelectPdfVersion", PDFX1A2001);

        return DocumentFormat.builder()
                .inputFamily(DocumentFamily.TEXT)
                .extension("pdf")
                .mediaType("pdf")
                .storeProperty(DocumentFamily.TEXT, "FilterData", pdfOptions)
                .storeProperty(DocumentFamily.TEXT, "FilterName", "writer_pdf_Export")
                .unmodifiable(false)
                .build();
    }

Соответственно формат pdfFormat будет:

 DocumentFormat pdfFormat = getDocumentFormatPDFA();

В данном примере я преобразую в самый распространенный формат PDF/X-1a. Для других, используйте один из вариантов ниже:

final int PDFXNONE = 0;
final int PDFX1A2001 = 1;
final int PDFX32002 = 2;
final int PDFA1A = 3;
final int PDFA1B = 4;

А теперь можно проверить на валидаторе https://pdfrecover.herokuapp.com/pdfaconvert/

Готово, вы великолепныsmile