如何在pdfbox中插入另一个PDPage中的PDPage

我使用不同的工具,如处理来创buildvector图。 这些地块被写成单页或多页PDF文件。 我想用pdfbox将这些地块包含在一个单一的报告中。

我目前的工作stream程包括这些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(); 

虽然这工作,它放弃了vector文件格式的好处,特别是文件/大小与打印质量。

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

你可以推荐哪些Java库来完成这个任务?

是否有可能使用pdfbox将其他pdf页面作为embedded对象包含在页面中

这应该是可能的。 PDF格式允许使用所谓的表单xobjects作为这样的embedded对象。 虽然我没有看到明确的实现,但程序与PageExtractorPDFMergerUtility相似。

使用PDFBox 2.0.0开发版本的当前SNAPSHOT从PageExtractor派生的概念certificate:

 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(); 

此代码将源文档的第一页作为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; } 

如上所述,这只是一个概念的certificate,angular落案件还没有被考虑在内。

要更新这个问题:

org.apache.pdfbox.multipdf.LayerUtility已经有一个帮助类来执行导入。

显示将PDF页面叠加到另一个PDF上的示例: SuperimposePage

这个类是Apache PDFBox的一部分示例和@mkl所示的示例转换已添加到它。

正如mkl恰当地build议的那样, PDFClown为页面embedded提供显式支持的Java库(所谓Form XObjects(参见PDF参考1.7,第4.9节))。

为了让你领略一下PDFClown的工作方式,下面的代码代表了mkl的PDFBox解决scheme的等价物(注意:正如mkl稍后所述,他的代码样本并没有经过优化,所以这个比较可能不符合实际PDFBox的状态 – 评论欢迎澄清这一点):

 Document source = new File(SOURCE).getDocument(); Pages sourcePages = source.getPages(); Document target = new File().getDocument(); Page targetPage = new Page(target); target.getPages().add(targetPage); XObject xobject = sourcePages.get(0).toXObject(target); PrimitiveComposer composer = new PrimitiveComposer(targetPage); Dimension2D targetSize = targetPage.getSize(); Dimension2D sourceSize = xobject.getSize(); composer.showXObject(xobject, new Point2D.Double(targetSize.getWidth() * .5, targetSize.getHeight() * .35), new Dimension(sourceSize.getWidth() * .6, sourceSize.getHeight() * .6), XAlignmentEnum.Center, YAlignmentEnum.Middle, 45); composer.showXObject(xobject, new Point2D.Double(targetSize.getWidth() * .35, targetSize.getHeight()), new Dimension(sourceSize.getWidth() * .4, sourceSize.getHeight() * .4), XAlignmentEnum.Left, YAlignmentEnum.Top, 90); composer.flush(); target.getFile().save(TARGET, SerializationModeEnum.Standard); source.getFile().close(); 

比较这个代码和PDFBox的等价物,你可以注意到一些相关的差异,它们显示了PDFClown的整洁风格(如果一些PDFBox专家可以validation我的断言,这将是很好的):

  • Page-to-FormXObject转换PDFClown本身支持一个专用的方法 (Page.toXObject()),所以不需要额外的繁重工作,比如helper方法importAsXObject();
  • 资源pipe理PDFClown自动(透明地)分配页面资源 ,所以不需要显式调用,比如page.getResources()。addXObject(xobject,“X”);
  • XObject绘图PDFClown同时支持高级(显式缩放,平移和旋转锚)和低级(仿射变换)方法来将FormXObject放入页面,所以不需要处理仿射变换。

总而言之, PDFClown具有由多个抽象层构成的丰富架构 :根据您的要求,您可以select最合适的编码风格(既可以深入研究PDF的底层基础结构,也可以利用其便捷,级模型)。 PDFClown可以让你调整每一个字节,并用一个可笑的简单方法调用来解决复杂的任务。

披露:我是PDFClown的首席开发人员。