在 Java 中,我希望能够读取 PDF 文件,测试它是否兼容 PDF/A(用于存档的 PDF),如果不兼容,则将文件转换为 PDF/A。
我可能更喜欢 Apache PDFBox 中的这个,因为我已经在该 API 中做了一些事情,但我也会对其他 API 开放。
测试 PDF 文件是否为 PDF/A-1b 可以使用 PDFBox 预检完成,请参见示例here 或使用预检应用程序。
创建将文件从 PDF 转换为 PDF/A 的工具是一项艰巨的任务,可能需要数月甚至数年的时间。如果您查看 PDFBox preflight 的源代码,您会发现数百条错误消息。因此,您的工具必须能够修复这些错误中的每一个。有些是:
只需使用 PDFBox 预检检查您自己的一些文件,您就会看到各种各样的问题......
如果您没有几个月或几年,请访问
Callas Software GmbH
或PDF Tools AG
的主页购买这样的转换器。
我一直在研究一种将 PDF 转换为 PDF/A 的简单方法。最后,我将原始 PDF 的每一页都转换为图像,然后仅使用图像重新创建 PDF。
这样我就不关心字体、表格或任何其他配置。
public void usingImages(File pdfFile) {
try (PDDocument docIn = PDDocument.load(pdfFile))
{
try(PDDocument docOut = new PDDocument()) {
PDFRenderer pdfRenderer = new PDFRenderer(docIn);
for (int pageIx = 0; pageIx < docIn.getNumberOfPages(); ++pageIx) {
//convert the input page to img
BufferedImage bim = pdfRenderer.renderImageWithDPI(pageIx, 300, ImageType.RGB);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bim, "png", baos);
byte[] toByteArray = baos.toByteArray();
//Create new output page
PDPage page = new PDPage();
docOut.addPage(page);
//Insert Image to new page
PDImageXObject pdImage = PDImageXObject.createFromByteArray(docOut, toByteArray, "Pagina_"+String.valueOf(page));
try (PDPageContentStream contentStream = new PDPageContentStream(docOut, page, PDPageContentStream.AppendMode.APPEND, true, true))
{
// contentStream.drawImage(ximage, 20, 20 );
// better method inspired by http://stackoverflow.com/a/22318681/535646
// reduce this value if the image is too large
float width = page.getCropBox().getWidth();
float height = page.getCropBox().getHeight();
float scale = width / pdImage.getWidth();
if (scale > (height / pdImage.getHeight()))
scale = height / pdImage.getHeight();
contentStream.drawImage(pdImage, page.getCropBox().getLowerLeftX(), page.getCropBox().getLowerLeftY(), pdImage.getWidth() * scale, pdImage.getHeight() * scale);
}
}
docOut.save(new File(pdfFile.getAbsolutePath() + ".PDFA.pdf"));
}
} catch (Exception ex) {
Logger.getLogger(PDFtoPDFA.class.getName()).log(Level.SEVERE, null, ex);
}
}