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