在带有 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,这使得我的应用程序更快。
我使用 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,这使得我的应用程序更快。