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

iText7生成PDF/A大表格时无法自动刷新致堆溢出求助

解决iText PdfADocument生成大表格时内存溢出问题

使用iText的PdfDocument生成超大型表格时,系统会自动刷新页面,将临时数据写入文件,堆内存保持稳定。但切换到PdfADocument生成PDF/A文件时,无法自动触发页面刷新,所有内容在内存中构建,最终导致堆内存溢出。日志明确提示:

com.itextpdf.pdfa.PdfADocument : Page flushing was not performed. Pages flushing in PDF/A mode works only with explicit calls to PdfPage#flush(boolean) with flushResourcesContentStreams argument set to true

解决方案

PDF/A模式下,iText要求显式调用页面刷新方法才能释放内存。核心操作是在生成表格的过程中,主动调用PdfPage#flush(true),将页面资源写入临时文件,避免内存堆积。

具体实现步骤

  1. 正常初始化PdfADocument和Document实例。
  2. 批量添加表格数据,每完成一批内容或一页数据后,获取当前页面并调用flush(true)。
  3. 文档生成完成后,遍历所有页面执行最终刷新,确保资源全部写入文件。

修改后的代码示例

// 初始化PdfADocument
PdfADocument pdf = new PdfADocument(new PdfWriter(tempfile), PdfAConformanceLevel.PDF_A_1B,
        new PdfOutputIntent("Custom", "", null, "sRGB IEC61966-2.1",
                resourceLoader.getResource("classpath:sRGB2014.icc").getInputStream()));
pdf.getCatalog().setLang(new PdfString("it-it"));
Document document = new Document(pdf, PageSize.A4, true);

// 创建4列表格
Table table = new Table(4);
// 添加表头
table.addHeaderCell("列1");
table.addHeaderCell("列2");
table.addHeaderCell("列3");
table.addHeaderCell("列4");

// 模拟生成10万行数据
for (int i = 0; i < 100000; i++) {
    table.addCell("数据行" + i);
    table.addCell("数据行" + i);
    table.addCell("数据行" + i);
    table.addCell("数据行" + i);

    // 每添加1000行刷新一次页面,平衡性能与内存占用
    if (i % 1000 == 0) {
        document.add(table);
        // 获取当前页面并显式刷新,参数true表示刷新资源流释放内存
        PdfPage currentPage = pdf.getCurrentPage();
        if (currentPage != null) {
            currentPage.flush(true);
        }
        // 重置表格,重新添加表头以支持跨页显示
        table = new Table(4);
        table.addHeaderCell("列1");
        table.addHeaderCell("列2");
        table.addHeaderCell("列3");
        table.addHeaderCell("列4");
    }
}

// 添加剩余的表格内容
document.add(table);

// 遍历所有页面,确保全部资源完成写入
for (int pageNum = 1; pageNum <= pdf.getNumberOfPages(); pageNum++) {
    pdf.getPage(pageNum).flush(true);
}

// 关闭文档
document.close();
pdf.close();

关键注意事项

  • 刷新频率:避免过于频繁刷新(如每一行都刷新),会降低生成效率;建议按批量行或分页节点触发。
  • 表头处理:如果需要跨页保留表头,每次重置表格时需重新添加表头,或通过Table#setHeaderRows(1)配置固定表头(需结合刷新逻辑适配)。
  • 最终校验:遍历所有页面执行刷新,确保最后一页的资源也被写入文件,避免内存残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:45:14