如何使用 pdfbox 将 PDPage 插入另一个 PDPage

And*_*eas 6 java pdf pdfbox

我使用不同的工具(例如处理)来创建矢量图。这些图被写成单页或多页 pdf。我想使用 pdfbox 将这些图包含在一个类似报告的 pdf 中。

我当前的工作流程包括这些 pdf 文件作为图像,并具有以下伪代码

PDDocument inFile = PDDocument.load(file);
PDPage firstPage = (PDPage) inFile.getDocumentCatalog().getAllPages().get(0);
BufferedImage image = firstPage.convertToImage(BufferedImage.TYPE_INT_RGB, 300);
PDXObjectImage ximage = new PDPixelMap(document, image);

PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.drawXObject(ximage, 0, 0, ximage.getWidth(), ximage.getHeight());
contentStream.close();
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但它失去了矢量文件格式的优点,特别是文件/大小与打印质量。

是否可以使用 pdfbox 将其他 pdf 页面作为嵌入对象包含在页面中(不添加为单独的页面)?例如,我可以使用 PDStream 吗?我更喜欢像 pdflatex 这样的解决方案能够将 pdf 数字嵌入到新的 pdf 文档中。

您可以推荐哪些其他 Java 库来完成该任务?

mkl*_*mkl 8

是否可以使用 pdfbox 将其他 pdf 页面作为嵌入对象包含在页面中

这应该是可能的。PDF 格式允许使用所谓的表单 xobjects 来充当此类嵌入对象。不过,我没有看到明确的实现,但该过程与“what”PageExtractorPDFMergerUtility“do”足够相似。

PageExtractor使用 PDFBox 2.0.0 开发版本的当前快照得出的概念证明:

PDDocument source = PDDocument.loadNonSeq(SOURCE, null);
List<PDPage> pages = source.getDocumentCatalog().getAllPages();

PDDocument target = new PDDocument();
PDPage page = new PDPage();
PDRectangle cropBox = page.findCropBox();
page.setResources(new PDResources());
target.addPage(page);

PDFormXObject xobject = importAsXObject(target, pages.get(0));
page.getResources().addXObject(xobject, "X");

PDPageContentStream content = new PDPageContentStream(target, page);
AffineTransform transform = new AffineTransform(0, 0.5, -0.5, 0, cropBox.getWidth(), 0);
content.drawXObject(xobject, transform);
transform = new AffineTransform(0.5, 0.5, -0.5, 0.5, 0.5 * cropBox.getWidth(), 0.2 * cropBox.getHeight());
content.drawXObject(xobject, transform);
content.close();

target.save(TARGET);
target.close();
source.close();
Run Code Online (Sandbox Code Playgroud)

此代码将源文档的第一页作为 XObject 导入到目标文档,并使用不同的缩放和旋转变换将其两次放置到页面上,例如对于此源

源 PDF,第 1 页

它创造了这个

目标 PDF

实际执行导入的辅助方法importAsXObject定义如下:

PDFormXObject importAsXObject(PDDocument target, PDPage page) throws IOException
{
    final PDStream src = page.getContents();
    if (src != null)
    {
        final PDFormXObject xobject = new PDFormXObject(target);

        OutputStream os = xobject.getPDStream().createOutputStream();
        InputStream is = src.createInputStream();
        try
        {
            IOUtils.copy(is, os);
        }
        finally
        {
            IOUtils.closeQuietly(is);
            IOUtils.closeQuietly(os);
        }

        xobject.setResources(page.findResources());
        xobject.setBBox(page.findCropBox());

        return xobject;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

如上所述,这只是概念证明,尚未考虑极端情况。