当前位置: 首页 > 知识库问答 >
问题:

PDF文件合并:删除页面末尾的空白。我正在使用PDFBox v2.0.13来实现这一点

单于皓轩
2023-03-14

我正在使用PDFBox(v2.0.13)合并PDF文件
这些文件是

合并后的文件是

我可以去掉使第2页成为第1页的空白吗?
关于合并代码,我使用pdfbox github示例代码:https://github.com/apache/pdfbox/blob/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/PDFMergerExample.java

html中的表及其父元素的边距和填充为0。代码如下

<div class="table-wrap">
<table id="arOpenItemDetail_save" border="0" cellspacing="1" cellpadding="1"  class="table-Y" name="detail">
    <THEAD style="display:table-header-group;font-weight:bold" name="detailHeader">
    <tr>
        <th>Cust#</th>
        <th width="20">Order Type</th>
        <th>Order No</th>
        <th>Doc Terms</th>
        <th>Doc Date</th>
        <th>Due Date</th>
        <th>Days PastDue</th>
        <th>Doc Amount</th>
        <th>Current</th>
        <th>1~30</th>
        <th>30+</th>
        <th>Ref</th>
        <th>Ref2</th>
        <th>Reason Code</th></tr>
    </THEAD>
    <span th:each="detail:${list}">
        <tr class="odd">
            <td align="right" width="20" th:text="${detail.custNo}">1</td>
            <td align="center" width="20" th:text="${detail.custNo}">1</td>
            <td align="right"    th:text="${detail.custNo}">1</td>
            <td align="center" th:text="${detail.custNo}">1</td>
            <td align="right"   th:text="${detail.custNo}">1</td>
            <td align="right"   th:text="${detail.custNo}">1</td>
            <td align="right"   th:text="${detail.custNo}"></td>
            <td align="right"   th:text="${detail.custNo}"></td>

            <td align="right"   th:text="${detail.custNo}"></td>
            <td align="right"   th:text="${detail.custNo}"></td>
            <td align="right"   th:text="${detail.custNo}"></td>
            <td align="left"   th:text="${detail.custNo}"></td>
            <td align="left"   th:text="${detail.custNo}"></td>
            <td align="left" th:text="${detail.custNo}"></td>
        </tr>
    </span>
</table>
</div> 

共有1个答案

姬安志
2023-03-14

这个问题本质上是关于一个或多个PDF中的多个PDF页面的密集合并。

通常pdf的合并方法仅在页面基础上进行合并,即它们从文档中提取页面进行合并并使用所有这些页面创建一个新文档。通常,更密集的合并(将多个页面的内容放在单个结果页面上)是不可行的,因为在这种情况下必须识别和忽略页眉、页脚、背景图形和其他工件。对于像您这样的页面,密集合并是可行的,只是还没有作为单一实用程序方法提供。

可以实现这样的实用程序类:

public class PdfDenseMergeTool {
    public PdfDenseMergeTool(PDRectangle size, float top, float bottom, float gap)
    {
        this.pageSize = size;
        this.topMargin = top;
        this.bottomMargin = bottom;
        this.gap = gap;
    }

    html" target="_blank">public void merge(OutputStream outputStream, Iterable<PDDocument> inputs) throws IOException
    {
        try
        {
            openDocument();
            for (PDDocument input: inputs)
            {
                merge(input);
            }
            if (currentContents != null) {
                currentContents.close();
                currentContents = null;
            }
            document.save(outputStream);
        }
        finally
        {
            closeDocument();
        }

    }

    void openDocument() throws IOException
    {
        document = new PDDocument();
        newPage();
    }

    void closeDocument() throws IOException
    {
        try
        {
            if (currentContents != null) {
                currentContents.close();
                currentContents = null;
            }
            document.close();
        }
        finally
        {
            this.document = null;
            this.yPosition = 0;
        }
    }

    void newPage() throws IOException
    {
        if (currentContents != null) {
            currentContents.close();
            currentContents = null;
        }
        currentPage = new PDPage(pageSize);
        document.addPage(currentPage);
        yPosition = pageSize.getUpperRightY() - topMargin + gap;
        currentContents = new PDPageContentStream(document, currentPage);
    }

    void merge(PDDocument input) throws IOException
    {
        for (PDPage page : input.getPages())
        {
            merge(input, page);
        }
    }

    void merge(PDDocument sourceDoc, PDPage page) throws IOException
    {
        PDRectangle pageSizeToImport = page.getCropBox();
        BoundingBoxFinder boundingBoxFinder = new BoundingBoxFinder(page);
        boundingBoxFinder.processPage(page);
        Rectangle2D boundingBoxToImport = boundingBoxFinder.getBoundingBox();
        double heightToImport = boundingBoxToImport.getHeight();
        float maxHeight = pageSize.getHeight() - topMargin - bottomMargin;
        if (heightToImport > maxHeight)
        {
            throw new IllegalArgumentException(String.format("Page %s content too large; height: %s, limit: %s.", page, heightToImport, maxHeight));
        }

        if (gap + heightToImport > yPosition - (pageSize.getLowerLeftY() + bottomMargin))
        {
            newPage();
        }
        yPosition -= heightToImport + gap;

        LayerUtility layerUtility = new LayerUtility(document);
        PDFormXObject form = layerUtility.importPageAsForm(sourceDoc, page);

        currentContents.saveGraphicsState();
        Matrix matrix = Matrix.getTranslateInstance(0, (float)(yPosition - (boundingBoxToImport.getMinY() - pageSizeToImport.getLowerLeftY())));
        currentContents.transform(matrix);
        currentContents.drawForm(form);
        currentContents.restoreGraphicsState();
    }

    PDDocument document = null;
    PDPage currentPage = null;
    PDPageContentStream currentContents = null;
    float yPosition = 0; 

    final PDRectangle pageSize;
    final float topMargin;
    final float bottomMargin;
    final float gap;
}

(PDFDE工具实用程序类)

它使用这个答案中的BoundingBoxFinder类来回答一个旧问题。

您可以像这样使用pdfdensemerge工具

PDDocument document1 = ...;
PDDocument document2 = ...;
PDDocument document3 = ...;
PDDocument document4 = ...;
PDDocument document5 = ...;

PdfDenseMergeTool tool = new PdfDenseMergeTool(PDRectangle.A4, 30, 30, 10);
tool.merge(new FileOutputStream("Merge with Text.pdf"),
        Arrays.asList(document1, document2, document3, document4, document5,
                document1, document2, document3, document4, document5,
                document1, document2, document3, document4, document5));

连续三次合并五个源文档。

对于我的测试文档(每个源文档包含三行文本),我得到这个结果:

第1页:

第2页:

这个实用程序类本质上是这个答案中iText的PdfDenseMergeTool的一个端口。

它已经用当前的PDFBox 3.0.0开发分支快照进行了测试。

 类似资料:
  • 目前我正在测试PhpStorm IDE。它真的很棒,除了一个功能。它不会从文件末尾删除空行。现在删除不需要的空格,但末尾的空行不会删除。 这对我来说真的很烦人。我能改变这种行为吗?

  • 问题内容: 在我当前的项目中,我们总是在Java源文件的末尾插入一个空的新行。我们还使用CheckStyle(具有错误级别)来强制执行此操作。 我一直在寻找这个主题很长时间,但是不幸的是,我找不到任何令人信服的理由。似乎其他开发人员对此无动于衷,因为他们只是选中了Eclipse formatter中的一个复选框,并且它是自动完成的。但是我仍然不知道为什么需要它,为什么它很重要。所以我的问题是: 为

  • 我正在使用2018.1.5社区版的intellij编辑器来编辑纯文本文件。 我没有使用项目。我在Linux上启动它,如下所示: 其中my_file.mpl是纯文本文件。 这很有效,除了一个大问题。 我需要在一些行的末尾留一个空白。i、 在文件中某行的行字符后,我插入一些白色。通过执行“查看”,我看到空间在那里- 但一旦我保存了文件,这些空白就会从行尾删除。 这给我带来了一个问题(由于其他原因,当其

  • 我有一些代码可以接受3个不同的PDF字节数组并将它们合并。这段代码非常有效。(一些人)面临的问题是,每个PDF都被视为一个完整的页面(如果打印出来的话),即使上面只有4英寸的内容,也会在垂直方向上留下7英寸的空白。然后,中间的文档被放入其中,它的末尾可能有也可能没有垂直的空格。然后,页脚也会放在自己的页面上。 代码如下: 当我合并每个页面时,有没有办法剪辑/删除/擦除每个pdf末尾的垂直空白,使其

  • 我用iReport设计了一个报告,它有两个细节带和一个页眉和页脚。在两个细节条带之间有一个分页符,以确保两者都从新页面开始。第一细节带的内容具有比第二细节带更多的数据。 基本输出是一个带有 2 页以及页眉、页脚的 PDF。如果内容增加,页数就会增加。 问题:在某些情况下,第一个明细栏有2页数据,而第二个明细栏只有一页。在上面的场景中,我应该总共得到3页,但是我在第二个细节带的末尾得到一个空白页。如

  • 问题内容: 我正在尝试将类路径中的文件复制到另一个临时位置。 这是它的代码: readMeFile有2页,在tempFilesOutputPath文件夹中复制的文件也有2页,但没有任何内容。 如果我犯了一些错误,或者必须以其他方式进行处理,请告诉我。 干杯,马杜 问题答案: 问题完全无关。我正在使用Maven复制资源来复制src / main / resources /下的资源 这是我的行家资源: