JasperReports PdfServlet 将报告保存为 PDF - 如何设置浏览器的文件名以提示用户?

2024-01-04

Stack: JSF + PrimeFaces on JBoss AS with 贾斯珀报告

我一直在使用 JasperReports 以 PDF 格式导出的模式,过程分为三个步骤:

[1] 从以下路径获取编译好的Jasper报告war

[2] 放置碧玉印刷会话中的对象

[3] 重定向到的 URLPDFServlet

因此,当用户从 GUI 单击p:命令按钮调用支持 bean 的方法,该方法会经历 [1]、[2] 和 [3],如以下示例代码所示:

xhtml 文件:

<p:commandButton ajax="false" action="#{indexController.exportPDF}" value="Export PDF"/>

支持 bean 代码:

private void putPrintObjectInSession() throws JRException {
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    ServletContext context = (ServletContext) externalContext.getContext();
    String reportFileName = context.getRealPath("/reports/PrimeNumbersReport.jasper");
    File reportFile = new File(reportFileName);
    if (!reportFile.exists())
        throw new JRRuntimeException(".jasper file not found in the war.");
    Map parameters = new HashMap();
    parameters.put("ReportTitle", "2nd Prime Numbers Report");
    parameters.put("BaseDir", reportFile.getParentFile());
    JasperPrint jasperPrint = 
            JasperFillManager.fillReport(
                      reportFileName, 
                      parameters, 
                      getSQLConnection()
                    );
    ((HttpSession) externalContext.getSession(false)).setAttribute(BaseHttpServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);
}

public String exportPDF() throws IOException, JRException {
    putPrintObjectInSession();
    FacesContext facesContext = FacesContext.getCurrentInstance();  
    ExternalContext externalContext = facesContext.getExternalContext();  
    externalContext.redirect("servlets/pdf");
    return null;
}

我有两个问题:

[i] 您是否发现这种方法有任何明显的代码味道或限制?

[ii] 使用上面的示例代码,Chrome 和 Conkeror 都可以保存报告,但它们向用户提供的用于保存文件的默认文件名只是“pdf”。如何将其配置为有意义的名称(例如“report-2012-08-23c.pdf”)?


至于“另存为”文件名的具体问题,它默认为请求 URL 中的最后一个路径(在这种情况下)/servlets/pdf确实只是pdf),除非另有规定Content-Disposition标头。

该问题并不是直接由您的 JSF 代码引起的(尽管它有其自身的奇怪之处,但这是一个不同的问题/问题),而是更多地由映射到的 servlet 引起/servlets/pdf。要设置所需的“另存为”文件名,您需要在将任何字节写入响应之前添加以下行:

response.setHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");

如有必要,您可以更换attachment by inline如果你想默认内联显示它。

然而,Internet Explorer 浏览器会忽略该值并坚持使用请求 URL 中的最后一个路径。因此,为了覆盖该浏览器,您需要自己在请求 URL 中包含所需的文件名并更改 servlet 映射。

E.g.

String filename = "report-2012-08-23c.pdf";
externalContext.redirect("servlets/pdf/" + filename);

with

@WebServlet("/servlets/pdf/*") // instead of @WebServlet("/servlets/pdf")

使用此 URL 模式,文件名位于可用的 servlet 内

String filename = request.getPathInfo().substring(1);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JasperReports PdfServlet 将报告保存为 PDF - 如何设置浏览器的文件名以提示用户? 的相关文章

随机推荐