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

lowagie PdfWriter调用writeData时覆盖数据,如何实现数据追加?

如何用iText(lowagie)实现PDF数据追加?

你的代码之所以会覆盖原有内容,是因为PDF是结构化的二进制文档,不能像纯文本那样直接用FileOutputStream的追加模式写入。iText的PdfWriter是从头创建新文档的工具,即便你打开了追加模式,它依然会生成全新的PDF结构,覆盖原有文件。

要实现PDF数据追加,必须先读取已有的PDF文档,再通过PdfStamper在原有文档的基础上添加内容,具体实现如下:

修正后的代码示例

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;

void writeData(List<org.bson.Document> item) {
    boolean isExistingFile = Files.exists(Paths.get(filePath));
    File file = new File(filePath);
    Document doc = null;
    PdfReader reader = null;
    PdfStamper stamper = null;
    PdfPTable table = null;

    try {
        if (!isExistingFile) {
            // 首次创建PDF:初始化文档并添加表头
            doc = new Document();
            PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(file));
            writer.setPageEvent(reportPdfWriter); // 保留原有的页面事件
            doc.open();
            
            table = new PdfPTable(headerLength);
            // 循环添加表头单元格(替换为你的表头数据逻辑)
            for (String header : yourHeaderList) {
                table.addCell(header);
            }
        } else {
            // 追加模式:读取现有PDF,通过PdfStamper修改
            reader = new PdfReader(filePath);
            stamper = new PdfStamper(reader, new FileOutputStream(file));
            doc = stamper.getWriter().getDocument();
            table = new PdfPTable(headerLength);
            // 追加时不需要重复添加表头
        }

        // 添加新的数据行
        for (org.bson.Document d : item) {
            Iterator<Object> itr = d.values().iterator();
            while (itr.hasNext()) {
                Object obj = itr.next();
                table.addCell(String.valueOf(obj));
            }
        }

        // 将表格添加到文档
        if (!doc.isOpen()) {
            doc.open();
        }
        doc.add(table);

    } catch (DocumentException | IOException e) {
        e.printStackTrace();
    } finally {
        // 确保所有资源正确关闭,避免文件损坏
        if (doc != null && doc.isOpen()) {
            doc.close();
        }
        if (stamper != null) {
            try {
                stamper.close();
            } catch (IOException | DocumentException e) {
                e.printStackTrace();
            }
        }
        if (reader != null) {
            reader.close();
        }
    }
}

关键说明

  • 核心逻辑:用PdfReader加载现有PDF,PdfStamper负责在原有文档上追加内容,而不是重新创建新文档。
  • 表头控制:仅在首次创建PDF时添加表头,后续追加只添加数据行,避免重复表头。
  • 资源管理:在finally块中关闭所有IO资源(PdfReader、PdfStamper、Document),这是保证PDF文件不损坏的关键。
  • 格式一致性:追加的内容会继承原有PDF的页面设置(页边距、字体等),保持整体格式统一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:17:23