Jasper报告导出为文本会导致java.lang.OutOfMemoryError:Java堆空间

huangapple go评论82阅读模式
英文:

Jasper report exporting to text results in java.lang.OutOfMemoryError: Java heap space

问题

目前我正在使用jasper v `3.7.4`

从相同的`数据集`导出到任何其他格式(`csv`、`xls`、`pdf`)时,我没有任何问题。

导出到`text`会抛出:

> java.lang.OutOfMemoryError: Java heap space 	at
> java.util.Arrays.copyOf(Arrays.java:3236) 	at
> java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)

以下是我的代码:

```java
byte[] bytes = null;
JRTextExporter exporter = new JRTextExporter();
ByteArrayOutputStream txtReport = new ByteArrayOutputStream();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, txtReport);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "mytxt.txt");
exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");
exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, 2.0F);
exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, 100.0F);
exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, 4.0F);
exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, 50.0F);

exporter.exportReport();
bytes = txtReport.toByteArray();

FileOutputStream fos = new FileOutputStream("c:\\myfile.txt");
System.out.println(bytes.length/1024 + " Kbytes");
fos.write(bytes, 0, bytes.length);
fos.flush();
fos.close();

我还将jasperPrint参数设置为了一个virtualizer

JRFileVirtualizer virtualizer = new JRFileVirtualizer(150);
virtualizer.setReadOnly(false);
params.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);

但是这并没有起作用,并且还会显示以下警告:

> WARNING: Parameter "REPORT_VIRTUALIZER" already registered, skipping
> this one.

鉴于csv也是一个“text”文件,并且可以正常生成,导出到text失败有点奇怪。

也许我为导出器提供的参数有问题?

谢谢。


<details>
<summary>英文:</summary>

Currently I am using jasper v `3.7.4`
 
While exporting to any other format (`csv`,`xls`,`pdf`) from the same `dataset` - I have has no issues. 

Exporting to `text` throws:  

&gt; java.lang.OutOfMemoryError: Java heap space 	at
&gt; java.util.Arrays.copyOf(Arrays.java:3236) 	at
&gt; java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)

Here is my code: 
            
        byte[] bytes = null;
        JRTextExporter  exporter = new JRTextExporter();
        ByteArrayOutputStream txtReport = new ByteArrayOutputStream();
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, txtReport);
        exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, &quot;mytxt.txt&quot;);
        exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, &quot;UTF-8&quot;);
        exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, 2.0F);
        exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, 100.0F);
        exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, 4.0F);
        exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, 50.0F);
        
        exporter.exportReport();
        bytes = txtReport.toByteArray();

        FileOutputStream fos = new FileOutputStream(&quot;c:\\myfile.txt&quot;)
        System.out.println(bytes.length/1024+&quot; Kbytes&quot;);
        fos.write(bytes, 0, bytes.length);
        fos.flush();
        fos.close();


I am also using a `virtualizer` as `jasperPrint` parameter 

     JRFileVirtualizer virtualizer = new JRFileVirtualizer(150);
     virtualizer.setReadOnly(false);
     params.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);

But it does not help, and also the following warning is shown: 

&gt; WARNING: Parameter &quot;REPORT_VIRTUALIZER&quot; already registered, skipping
&gt; this one.

Given that `csv` is also a &quot;`text`&quot; file and is generated without any problem, it is kind of strange that 
exporting to `text` fails.

May be something is wrong with the parameters I provide for the exporter?   

Thanks.

</details>


# 答案1
**得分**: 2

虽然 `text` 和 `csv` 都可能是基于*文本*的格式,但它们并不是*相同*的格式,因此不会占用相同的空间。

将*任何内容*(通常是报告)生成到内存中是危险的,因为虽然在测试中可能有效,但在生产中,生成一个大型报告可能导致 OOME(内存耗尽错误),从而造成严重混乱。

在生成内容时,请使用真实的流。例如,`FileOutputStream`、网络流,或者任何不会将内容存储在内存中的适当流。如果你在进行“真实工作”时使用 `ByteArrayOutputStream`,很可能出现了错误操作。

<details>
<summary>英文:</summary>

While `text` and `csv` may both be *text based* formats, they&#39;re not the *same* format and therefore do not take the same amount of space.

Generating *anything* (usually reports) to memory is hazardous since while it may work in testing, a large report in production causing an OOME will wreak havoc.

Use a real stream when generating things. A `FileOutputStream`, network stream, any proper stream that doesn&#39;t store things in memory. If you&#39;re using a `ByteArrayOutputStream` for &quot;real work&quot;, you&#39;re most likely doing something wrong.

</details>



# 答案2
**得分**: 0

立即将报告输出到文件,而不是先收集报告。

```java
try (FileOutputStream fos = new FileOutputStream("c:\\myfile.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos)) {
    JRTextExporter exporter = new JRTextExporter();
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, bos);
    exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "mytxt.txt");
    exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");
    exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, 2.0F);
    exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, 100.0F);
    exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, 4.0F);
    exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, 50.0F);

    exporter.exportReport();
}
英文:

Immediately output the report to the file, instead of first collecting it.

try (FileOutputStream fos = new FileOutputStream(&quot;c:\\myfile.txt&quot;);
        BufferedOutputStream bos = new BufferedOutputStream(fos)) {
	JRTextExporter  exporter = new JRTextExporter();
	exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
	exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, bos);
	exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, &quot;mytxt.txt&quot;);
	exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, &quot;UTF-8&quot;);
	exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, 2.0F);
	exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, 100.0F);
	exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, 4.0F);
	exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, 50.0F);

	exporter.exportReport();
}

huangapple
  • 本文由 发表于 2020年9月15日 14:23:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/63896243.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定