java jasper 报告导出到流空白页

java jasper report export to stream blank page

我使用 jasper 报告版本 6.2.1,配置如下:

HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
 JREmptyDataSource jasper = new JREmptyDataSource();
 JasperPrint jasperPrint = jasperFillManager.fillReport(this.getClass().getClassLoader().getResource("/reports/tn2.jasper").getPath(), null, jasper);

response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment" + "; filename=hehe.pdf");

ByteArrayOutputStream finalReport = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,finalReport);
PrintWriter ouputStream = response.getWriter();
ouputStream.write(new String(finalReport.toByteArray()));
ouputStream.flush();
FacesContext.getCurrentInstance().responseComplete();

我从我的 JSF 2.x 支持 bean 中完成。

但是当我尝试导出到流时,我总是得到一个空白页面。但如果我这样做:

JasperExportManager.exportReportToPdfFile(jasperPrint,
                                "d://hehe.pdf");

它工作正常,我在生成的文件中看到了内容。如何强制它与流一起工作?我尝试 close/flush 不同配置的流,使用 ARM 等。到目前为止运气不佳

这部分是错误的。

ByteArrayOutputStream finalReport = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,finalReport);
PrintWriter ouputStream = response.getWriter();
ouputStream.write(new String(finalReport.toByteArray()));

您正在内存中分配一个字节数组。然后您将报告导出到它。然后将字节数组转换为字符串(基本上是字符数组)。然后你把它写给一个基于角色的作家。基本上,您通过以相当低效且依赖于平台的方式将所有字节转换为字符来破坏 PDF 文件的二进制内容。就好像您在记事本等文本编辑器中打开 PDF 文件,然后将其另存为 TXT 文件一样。 PDF 无法再读取此类文件 reader.

您应该将未修改的字节流式传输到基于字节的输出流。用下面的一行替换上面的所有内容。

JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());

与具体问题无关,因为 JSF 2.x、ExternalContext 提供了多种委托方法,无需转换为 HttpServletResponse .有关具体示例,另请参阅 How to provide a file download from a JSF backing bean?

解决方案很简单:

 FacesContext.getCurrentInstance().getExternalContext().responseReset();

就是这样!!

感谢您的帮助。

我通过添加下一行解决了这个问题:

JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, new JREmptyDataSource());