我编写了一个用于管理和运行Jasper报告的Web应用程序。最近,我一直在处理一些报告,这些报告会生成非常大的(1500+页)输出,并试图解决由此产生的内存问题。我发现了JRFileVirtualizer
,这让我能够以非常有限的内存占用情况成功运行报告。但是,我的应用程序的一个特点是它存储以前运行的报告的输出文件,并允许将它们导出为各种格式(PDF,CSV等)。因此,我发现自己处于拥有500 + MB .jrprint文件并希望将其导出为例如CSV的需求的情况。下面是一些简单的例子代码:Jasper在导出时报告OutOfMemoryError
JRCsvExporter exporter = new JRCsvExporter();
exporter.setParameter(JRExporterParameter.INPUT_FILE_NAME, jrprintPath);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, outputStream);
exporter.exportReport();
不幸的是,当我尝试这对我提到的大文件,我得到一个OutOfMemoryError
:
Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.io.ObjectInputStream$HandleTable.grow(ObjectInputStream.java:3421)
at java.io.ObjectInputStream$HandleTable.assign(ObjectInputStream.java:3227)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1744)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at java.util.ArrayList.readObject(ArrayList.java:593)
at sun.reflect.GeneratedMethodAccessor184.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1849)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at net.sf.jasperreports.engine.base.JRVirtualPrintPage.readObject(JRVirtualPrintPage.java:423)
...
从浏览一些碧玉内部的,它看起来像无论我如何尝试设置此导出(我也尝试直接加载并设置JASPER_PRINT
参数),最终都会调用JRLoader.loadObject(...)
,这会尝试将我的整个500MB报告加载到内存中(请参阅net.sf.jasperreports.engine.JRAbstractExporter.setInput()
)。
我的问题是,有没有办法解决这个问题? 500MB是可行的,但它并没有离开我的应用程序非常面向未来的,并报告执行JRVirtualizer
溶液离开我希望有将用于出口类似的东西。我愿意让自己的手变脏,并扩展一些Jasper内部类,但理想的解决方案将由Jasper自己提供,理由很明显。
1500+页的报告,这是如此之大,它是无用的。也许考虑打破这些报告。 –
不幸的是,这是一个使用通用工具出于许多不同目的的情况。此报告(CSV格式)通过脚本导入到另一个数据库中,而不是由人类浏览。 – Eric
我已经用JasperSoft提交了一个功能请求,因为它看起来像项目预算约束会阻止我寻求像下面这样建议的更复杂的解决方案。 http://jasperforge.org/projects/jasperreports/tracker/view.php?id=5478 – Eric