Преобразование в 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/
Готово, вы великолепны