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
相关产品推荐
相关产品推荐

