【问题标题】:PDFBox merge 2 pdf files side by side with javaPDFBox与java并排合并2个pdf文件
【发布时间】:2018-10-06 06:53:52
【问题描述】:

我比较了 2 个 pdf 文件并在它们上标记高亮。 当我使用 pdfbox 合并它进行比较时。它有错误缺少突出显示。

我使用这个功能: 将 2 个文件 pdf 与它们的所有页面并排合并的功能。

function void generateSideBySidePDF() {
    File pdf1File = new File(FILE1_PATH);
    File pdf2File = new File(FILE2_PATH);
    File outPdfFile = new File(OUTFILE_PATH);
    PDDocument pdf1 = null;
    PDDocument pdf2 = null;
    PDDocument outPdf = null;
    try {

        pdf1 = PDDocument.load(pdf1File);
        pdf2 = PDDocument.load(pdf2File);

        outPdf = new PDDocument();
        for(int pageNum = 0; pageNum < pdf1.getNumberOfPages(); pageNum++) {
            // Create output PDF frame
            PDRectangle pdf1Frame = pdf1.getPage(pageNum).getCropBox();
            PDRectangle pdf2Frame = pdf2.getPage(pageNum).getCropBox();
            PDRectangle outPdfFrame = new PDRectangle(pdf1Frame.getWidth()+pdf2Frame.getWidth(), Math.max(pdf1Frame.getHeight(), pdf2Frame.getHeight()));

            // Create output page with calculated frame and add it to the document
            COSDictionary dict = new COSDictionary();
            dict.setItem(COSName.TYPE, COSName.PAGE);
            dict.setItem(COSName.MEDIA_BOX, outPdfFrame);
            dict.setItem(COSName.CROP_BOX, outPdfFrame);
            dict.setItem(COSName.ART_BOX, outPdfFrame);
            PDPage outPdfPage = new PDPage(dict);
            outPdf.addPage(outPdfPage);

            // Source PDF pages has to be imported as form XObjects to be able to insert them at a specific point in the output page
            LayerUtility layerUtility = new LayerUtility(outPdf);
            PDFormXObject formPdf1 = layerUtility.importPageAsForm(pdf1, pageNum);
            PDFormXObject formPdf2 = layerUtility.importPageAsForm(pdf2, pageNum);

            // Add form objects to output page
            AffineTransform afLeft = new AffineTransform();
            layerUtility.appendFormAsLayer(outPdfPage, formPdf1, afLeft, "left" + pageNum);
            AffineTransform afRight = AffineTransform.getTranslateInstance(pdf1Frame.getWidth(), 0.0);
            layerUtility.appendFormAsLayer(outPdfPage, formPdf2, afRight, "right" + pageNum);
        }
        outPdf.save(outPdfFile);
        outPdf.close();

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (pdf1 != null) pdf1.close();
            if (pdf2 != null) pdf2.close();
            if (outPdf != null) outPdf.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 亮点可能是注释。这些被忽略 IIRC。恕我直言,保留这些没有多大意义。
  • @TilmanHausherr 我正在使用 PDFBox 2.0.8。你知道如何解决这个问题吗?
  • @TilmanHausherr 这是一个文件样本。它具有突出显示,但在合并 2 个文件 pdf 后。它不见了。 drive.google.com/file/d/1rJ6iql8oRrFo0gsha41ZwNuwcykmWzlk/…
  • 我只是使用该单个文件作为两者的源来运行它,并且亮点在那里。但是我使用了开发主干。我用 2.0.11 重新测试,它也有效。我尝试使用 2.0.8 并且它也有效,绿色的东西被突出显示。这是结果文件:filedropper.com/new-result
  • 确实,那个——正如我在第一条评论中所怀疑的——有注释。您发送的文件没有。您向我发送的文件与您正在测试的文件不同,这有点奇怪。我怀疑您将页面“打印”成新的 PDF,这样,注释就变成了正常内容。因此,一个快速的解决方案是在运行工具之前对整个文件执行此操作。一个更困难的解决方案是复制所有注释并从右侧页面重新定位这些注释(通过修改注释矩形)。

标签: java pdf pdf-generation pdfbox


【解决方案1】:

在“必须导入源 PDF 页面”部分之后将其插入到您的代码中以复制注释。正确的 PDF 必须移动其矩形。

// copy annotations
PDPage src1Page = pdf1.getPage(pageNum);
PDPage src2Page = pdf2.getPage(pageNum);
for (PDAnnotation ann : src1Page.getAnnotations())
{
    outPdfPage.getAnnotations().add(ann);                
}
for (PDAnnotation ann : src2Page.getAnnotations())
{
    PDRectangle rect = ann.getRectangle();
    ann.setRectangle(new PDRectangle(rect.getLowerLeftX() + pdf1Frame.getWidth(), rect.getLowerLeftY(), rect.getWidth(), rect.getHeight()));
    outPdfPage.getAnnotations().add(ann);                
}

请注意,此代码有一个缺陷 - 它仅适用于带有外观流的注释(大多数都有)。对于那些不这样做的人来说,它会产生奇怪的效果,在这种情况下,必须根据注释类型调整坐标。对于高光,它将是四点,对于线,它将是线坐标等。

【讨论】:

  • 如果源页面的媒体框坐标系原点不在左下角,复制的注释将被错误定位。
猜你喜欢
  • 2012-11-28
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
相关资源
最近更新 更多