You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用iText 5实现无额外分页的PDF连续合并

解决iText5合并PDF时内容续接至前一页剩余空间的问题

问题原因

你当前用PdfCopy直接导入整页PDF的方式,本质是把每个导入页面作为独立新页添加,它不会检测前一页的剩余空间,所以哪怕第一份PDF最后一页有大量空白,第二份PDF也会从新页面开始。

解决方案

要实现内容续接,得改用PdfWriter手动控制内容写入位置,而非直接导入整页。核心逻辑是:先写入第一份PDF的所有页面,再在最后一页的剩余空间里写入第二份PDF的内容,空间不够时再新建页面。

实现代码

import com.itextpdf.text.Document;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import java.io.FileOutputStream;
import java.io.IOException;

public class MergePDFsWithContentContinuation {
    public static void main(String[] args) {
        try {
            // 读取第一份PDF
            PdfReader reader1 = new PdfReader("First.pdf");
            int totalPages1 = reader1.getNumberOfPages();
            Rectangle pageSize = reader1.getPageSize(1);

            // 创建合并后的新文档,沿用第一份PDF的页面尺寸
            Document document = new Document(pageSize);
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("Merged.pdf"));
            document.open();

            PdfContentByte contentByte = writer.getDirectContent();

            // 写入第一份PDF的前n-1页
            for (int i = 1; i < totalPages1; i++) {
                document.newPage();
                PdfImportedPage page = writer.getImportedPage(reader1, i);
                contentByte.addTemplate(page, 0, 0);
            }

            // 处理第一份PDF的最后一页
            document.newPage();
            PdfImportedPage lastFirstPage = writer.getImportedPage(reader1, totalPages1);
            contentByte.addTemplate(lastFirstPage, 0, 0);

            // 获取最后一页的可写入起始Y坐标(示例用CropBox底部加边距,实际需根据第一PDF内容调整)
            Rectangle cropBox = reader1.getCropBox(totalPages1);
            float currentY = cropBox.getBottom() + 20;

            // 读取第二份PDF
            PdfReader reader2 = new PdfReader("Second.pdf");
            int totalPages2 = reader2.getNumberOfPages();

            // 逐页写入第二份PDF内容
            for (int i = 1; i <= totalPages2; i++) {
                byte[] pageContent = reader2.getPageContent(i);
                if (pageContent == null) continue;

                // 计算当前内容高度(示例简化处理,实际需解析内容真实高度)
                float contentHeight = pageSize.getHeight() - 40;

                // 检查当前页面剩余空间是否足够
                if (currentY - contentHeight < cropBox.getBottom()) {
                    // 空间不足,新建页面
                    document.newPage();
                    currentY = cropBox.getTop() - 20;
                }

                // 将内容写入当前页面指定位置
                contentByte.saveState();
                contentByte.concatCTM(1, 0, 0, 1, cropBox.getLeft(), currentY);
                contentByte.addContent(pageContent);
                contentByte.restoreState();

                // 更新可写入起始Y坐标
                currentY -= contentHeight;
            }

            // 关闭资源
            document.close();
            reader1.close();
            reader2.close();
        } catch (IOException | com.itextpdf.text.DocumentException e) {
            e.printStackTrace();
        }
    }
}

关键说明

  1. 替换PdfCopy为PdfWriter:PdfWriter允许直接操作PDF内容流,能精准控制内容的写入位置。
  2. 剩余空间计算:示例中用页面CropBox底部加边距作为起始位置,实际项目里建议解析第一PDF最后一页的内容边界,获取更准确的剩余空间起始坐标。
  3. 内容分页处理:写入第二PDF内容前先检查剩余空间,不足则新建页面,确保内容完整显示。

内容的提问来源于stack exchange,提问作者Usama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 21:56:14