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

iText7合并HTML转PDF与带嵌入式Excel的PDF时异常求助

iText7合并PDF时出现"Trailer not found"和交叉引用表错误的解决方法

嘿,刚看完你的代码和报错信息,问题其实很明确——你生成的PDF内容不完整,导致后续读取时解析失败。

问题根源

iText7的PdfDocument对象负责处理PDF的整个写入生命周期,包括生成交叉引用表和trailer(这两个是PDF文件的核心结构)。你的代码里,生成HTML转PDF的pdf对象、生成带附件PDF的pdfLaunch对象都没有被关闭,导致ByteArrayOutputStream里只写入了PDF的部分内容,缺少关键的结尾结构。当你用PdfReader读取这些不完整的流时,自然会抛出找不到xref或者trailer的错误。

修复方案

解决方法很简单:用Java的try-with-resources语法来管理PdfDocument和相关流,确保它们在使用完成后自动关闭,这样就能保证PDF内容完整写入输出流。

下面是修改后的完整代码:

import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.kernel.pdf.annot.PdfAnnotation;
import com.itextpdf.kernel.pdf.annot.PdfFileAttachmentAnnotation;
import com.itextpdf.kernel.pdf.filespec.PdfFileSpec;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class PdfMergeFix {
    public static void main(String[] args) throws IOException {
        String htmlContent = "<html><body><h1>HTML to PDF Test</h1></body></html>";
        String excelPath = "path/to/your/test.xlsx";
        String outputDir = "path/to/output/dir";
        String dest = "path/to/final/merged.pdf";

        // 1. 将HTML转换为PDF,用try-with-resources确保PdfDocument关闭
        ByteArrayOutputStream htmlToPdfContent = new ByteArrayOutputStream();
        try (PdfWriter writer = new PdfWriter(htmlToPdfContent);
             PdfDocument pdf = new PdfDocument(writer)) {
            pdf.setTagged();
            PageSize pageSize = PageSize.A4.rotate();
            pdf.setDefaultPageSize(pageSize);
            ConverterProperties properties = new ConverterProperties();
            HtmlConverter.convertToPdf(htmlContent, pdf, properties);
            // 这里不需要手动关闭,try-with-resources会自动处理
        }

        // 清理输出目录
        FileUtils.cleanDirectory(new File(outputDir));

        // 2. 生成带Excel附件的PDF,同样用try-with-resources
        ByteArrayOutputStream pdfAttach = new ByteArrayOutputStream();
        try (PdfWriter attachWriter = new PdfWriter(pdfAttach);
             PdfDocument pdfLaunch = new PdfDocument(attachWriter)) {
            Rectangle rect = new Rectangle(36, 700, 100, 100);
            byte[] embeddedFileContentBytes = Files.readAllBytes(Paths.get(excelPath));
            PdfFileSpec fs = PdfFileSpec.createEmbeddedFileSpec(pdfLaunch, embeddedFileContentBytes, null, "test.xlsx", null, null);
            PdfAnnotation attachment = new PdfFileAttachmentAnnotation(rect, fs)
                    .setContents("Click me");
            pdfLaunch.addNewPage().addAnnotation(attachment);
        }

        // 3. 合并两个PDF到最终输出
        try (ByteArrayOutputStream pdfResult = new ByteArrayOutputStream();
             PdfWriter writerResult = new PdfWriter(pdfResult);
             PdfDocument pdfDocResult = new PdfDocument(writerResult);
             // 读取HTML转PDF的文档
             PdfReader htmlPdfReader = new PdfReader(new ByteArrayInputStream(htmlToPdfContent.toByteArray()));
             PdfDocument htmlPdfDoc = new PdfDocument(htmlPdfReader);
             // 读取带附件的PDF文档
             PdfReader attachPdfReader = new PdfReader(new ByteArrayInputStream(pdfAttach.toByteArray()));
             PdfDocument attachPdfDoc = new PdfDocument(attachPdfReader)) {

            // 复制HTML PDF的所有页面
            htmlPdfDoc.copyPagesTo(1, htmlPdfDoc.getNumberOfPages(), pdfDocResult);
            // 复制带附件的PDF页面
            attachPdfDoc.copyPagesTo(1, attachPdfDoc.getNumberOfPages(), pdfDocResult);

            // 写入最终文件
            try (OutputStream outputStream = new FileOutputStream(dest)) {
                pdfResult.writeTo(outputStream);
            }
        }
    }
}

关键修改点

  • 所有PdfDocument、PdfWriter、PdfReader实例都通过try-with-resources声明,确保资源自动关闭,避免手动遗漏
  • 将生成HTML PDF和带附件PDF的逻辑分别封装在独立的try-with-resources块中,保证每个PDF生成完成后都能完整写入流
  • 合并阶段的所有资源也统一用try-with-resources管理,进一步避免资源泄漏

这样修改后,生成的PDF都是完整的,合并时就不会再出现交叉引用表或trailer相关的错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:37:41