我使用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");
它工作正常,我在生成的文件中看到了内容。如何强制它与流一起工作?我尝试关闭/刷新不同配置的流,使用ARM等。到目前为止没有运气
答案 0 :(得分:2)
这部分是错误的。
ByteArrayOutputStream finalReport = new ByteArrayOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,finalReport);
PrintWriter ouputStream = response.getWriter();
ouputStream.write(new String(finalReport.toByteArray()));
您在内存中分配字节数组。然后,您将报告导出到该报告中。然后,您将字节数组转换为字符串(基本上是字符数组)。然后你将它写给一个基于角色的作家。基本上,您通过以相当低效且与平台相关的方式将所有字节转换为字符来破坏PDF文件的二进制内容。就像您在记事本等文本编辑器中打开PDF文件然后将其另存为TXT文件一样。这样的文件不再是PDF阅读器可读的。
您应该将未修改的字节流式传输到基于字节的输出流。用以下的oneliner替换以上所有内容。
JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
无关具体问题,因为JSF 2.x,ExternalContext
提供了多种委托方法,而无需转向HttpServletResponse
。另请参阅How to provide a file download from a JSF backing bean?以获取具体示例。
答案 1 :(得分:0)
解决方案很简单:
FacesContext.getCurrentInstance().getExternalContext().responseReset();
就是这样!!
感谢您的帮助。
答案 2 :(得分:0)
我通过添加下一行解决了这个问题:
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, new JREmptyDataSource());