【问题标题】:java jasper report export to stream blank pagejava jasper 报告导出到流空白页
【发布时间】:2016-09-08 09:53:15
【问题描述】:

我使用具有以下配置的 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 等。到目前为止没有运气

【问题讨论】:

    标签: java jsf-2 jasper-reports


    【解决方案1】:

    这部分是错误的。

    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?

    【讨论】:

    • 谢谢,但 response.getOutputStream() 是我尝试的第一个选项,但得到'getWriter() 已被调用以获取此响应'。然后发现应该调用getWriter()方法,但是writer不支持写字节数组等
    • 只需修复该异常,您就可以继续使用getOutputStream()xyproblem.info
    • 只是修复?如何? Stackoverflow 一直告诉我,我应该在所有情况下都使用 getWriter。
    • 确定负责呼叫getWriter()的人并使其停止。
    • 这是 JSF 2 部分,我想我不能让它停下来,因为这是内部结构。在这段代码之前,我从不隐式调用任何这些方法
    【解决方案2】:

    解决方法很简单:

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

    就是这样!!

    感谢您的帮助。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多