【发布时间】:2017-03-21 08:45:36
【问题描述】:
我的应用程序创建了一个电子表格,它可能相当大(最多 500,000 行,每行分布在六张纸上,每张大约有 20 列)。
我使用 Apache Poi 并转而使用 SXSSFWorkBook 将数据写入临时文件,这样使用的内存与最终电子表格的大小不成比例,这很有效。
但电子表格表示元数据已更改,并且当元数据已更改时,我想向显示旧值的单元格添加注释。我让这个适用于小型电子表格,但在尝试处理大文件时它总是会因堆内存错误而失败。
我不确定问题是由于 Poi 将所有 cmets 存储在内存中的限制,还是我做错了。 Worksheet 是我自己的包装类,我只为每张纸创建一个 DrawingPatriach 类,但看起来我必须为我需要的每条评论创建一个锚。
private void addCellComment(Row r, Cell c, Worksheet sheet, String value)
{
String formattedValue = value.replace('\u0000', '\n');
int rowCount = value.split("\\\\u000").length;
ClientAnchor anchor = factory.createClientAnchor();
anchor.setCol1(c.getColumnIndex());
anchor.setCol2(c.getColumnIndex()+2);
anchor.setRow1(r.getRowNum());
anchor.setRow2(r.getRowNum()+rowCount);
Drawing drawing = sheet.getDrawing();
Comment comment = drawing.createCellComment(anchor);
RichTextString str = factory.createRichTextString(formattedValue);
comment.setString(str);
c.setCellComment(comment);
}
【问题讨论】:
-
我不知道我们可以如何帮助解决这个问题。在这种情况下,您可能不得不求助于一个非常好的分析器,并且profile您的应用程序以准确了解消耗内存的位置、方式和原因。
-
需要多少内存?你的java内存设置是什么?你用的是哪个java?您的工作站有多少内存?
-
我正在寻找具有 Poi 专业知识而不是内存分析专业知识的人。我分配了 1GB 的内存,如果我删除了创建注释部分,我可以创建一个包含 20,000 行的电子表格,并且内存永远不会达到 300mb,但是重新添加 cmets 并且它总是在堆内存上失败。我在 Windows 10 上使用 jre1.8.0_111
-
请您添加更多代码我想知道您如何初始化 SXSSFWorkbook 窗口大小是多少?您是否关闭了自动刷新并使用手动控制如何将行刷新到磁盘?
-
@SauliusNext 我只是做 workbook = new SXSSFWorkbook(1000) - 我没有关闭刷新,如果我不添加评论单元,那么它使用的内存比我只使用 HSSFWorkbook 少得多。问题特定于评论单元
标签: java apache-poi