在带有 vert.x 框架的 iText 7 中使用大 table 时出现堆 space 错误

Heap space error when using large table in iText 7 with vert.x framework

我使用 iText 和 vert.x 框架开发了一个 PDF 生成应用程序。生成的 pdf 包含 tables 并确保它可以生成具有大量原始文件的 tables,我在初始化 tables 时启用大 table(new Table(float[] {1, 1, 1, 1, 1}, true)) 并使用 table.flush() 命令刷新 table。

该应用程序在少量数据上运行良好,但当我尝试创建包含大量数据(18,000 个原始数据)的 pdf 时,出现堆 space 错误。然后我将最大堆大小设置为 2GB,但仍然发生错误。然后我获取应用程序的堆转储,发现堆 space 错误的主要原因是,com.itextpdf.kernel.pdf.PdfIndirectReference 有更大的保留堆,它包含 com.itextpdf.kernel.pdf.PdfIndirectReference。要了解更多信息,请查看下面随附的屏幕截图。

下面是table每一行的代码示例(重复执行直到所有数据执行完)

Cell cell1 = createCcCell(createCcPara(a[0]).setFontSize(6));
    Cell cell2 = createCcCell(createCcPara(a[2]).setFontSize(6));
    Cell cell3 = createCcCell(createCcPara(a[7]).setFontSize(6));
    Cell cell4 = createCcCell(createCcPara(a[6]).setFontSize(6));
    Cell cell5 = createCcCell(createCcPara(a[5].split("T")[0] +" "+a[5].split("T")[1].substring(0,8)).setFontSize(6));
    Cell cell6 = createCcCell(createCcPara(a[1]).setFontSize(6));
    Cell cell7 = createCcCell(createCcPara(a[3]).setFontSize(6));
    Cell cell8 = createCcCell(createCcPara(a[4]).setFontSize(6));
    Cell cell9 = createCcCell(createCcPara(a[8]).setFontSize(6));
    Cell cell10 = createCcCell(createCcPara(a[9]).setFontSize(6));

    table
      .addCell(cell1)
      .addCell(cell2)
      .addCell(cell3)
      .addCell(cell4)
      .addCell(cell5)
      .addCell(cell6)
      .addCell(cell7)
      .addCell(cell9)
      .addCell(cell10)
      .addCell(cell8);

createCcCell方法:

private Cell createCcCell (Paragraph content) {
    return new Cell()
      .setBorder(new SolidBorder(ColorConstants.BLACK, 0.5f))
      .setPaddingLeft(2)
      .setPaddingTop(0)
      .setPaddingBottom(0)
      .setHorizontalAlignment(HorizontalAlignment.LEFT)
      .setVerticalAlignment(VerticalAlignment.MIDDLE)
      .add(content);
  }

createCcPara方法:

private Paragraph createCcPara (String content) {
    Paragraph newPara = new Paragraph(content)
      .setFontSize(5)
      .setFontColor(new DeviceCmyk(0, 0, 0, 100));

    try {
      newPara.setFont(PdfFontFactory.createFont(StandardFonts.HELVETICA));
    } catch (IOException e){
      logger.warn("Font setting failed for cc table due to "+e.getMessage());
    }

    return newPara;
  }

任何人都可以解释这个堆问题的原因是什么,有什么办法可以解决这个问题。

我尝试通过多种方式解决这个问题。但是我找不到通过优化数据结构来减小堆大小的方法,或者没有找到解决该问题的 iText 相关解决方案。

然后我找到了该问题的架构解决方案。我不是一次创建整个 pdf,而是将数据分成几个部分并为每个数据块创建单独的 PDF。最后,使用 iText PdfMerger 合并这些 pdf。

这给了我另一个优势。因为我与 vert.x 一起工作,所以我使用 returns vert.x Future 的方法来创建 pdf 部分并使用 CompositeFuture.all() 方法并行执行所有这些 Futures,这使得我的应用程序更快。