2012-08-23 64 views
0

堆棧:JSF + PrimeFaces的JBoss ASJasperReports的JasperReports PdfServlet將報告保存爲PDF - 如何設置瀏覽器的文件名以提示用戶?

我已經使用利用JasperReports的具有三個步驟過程中PDF格式導出的圖案:

[1]從戰爭中獲取編譯後的Jasper報告

[2]將放在JasperPri上的會話NT對象

[3]重定向到的PDFServlet中

的URL所以,當從GUI用戶點擊一個號碼:的commandButton背襯-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; 
} 

我有兩個問題:

[我]你看不到任何明顯的代碼異味或限制這種做法?

[ii]以上面的示例代碼都可以保存報告,但是它們向用戶保存文件的默認文件名只是「pdf」。我如何將其配置爲一個有意義的名稱(例如「report-2012-08-23c.pdf」)?

+0

我與JSF和JasperReports的工作壓力太大。就我而言,我們不會在會話中保存任何內容,我們從JasperReport生成PDF(或Excel或其他格式),然後將內容下載到用戶客戶端(通過在響應中寫入文件內容)。這種方法適合我們。 –

回答

1

對於「另存爲」文件名的具體問題,默認爲請求URL中的最後一個路徑(/servlets/pdf實際上只是pdf),除非在Content-Disposition標頭中另有規定。

這個問題並不是由你的JSF代碼直接引起的(儘管它本身是奇怪的,但這是一個不同的問題/問題),但更多的是在被映射到/servlets/pdf上的servlet中。設置所需的「另存爲」文件名,你需要寫任何字節到響應之前添加以下行:

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

必要時,可以通過inline更換attachment如果你想用默認的內聯顯示它。

但是,Internet Explorer瀏覽器會忽略此值並堅持使用請求URL中的最後一個路徑。因此,爲了覆蓋該瀏覽器,您需要自己在請求URL中包含所需的文件名,並更改servlet映射。

E.g.

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

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

有了這個網址格式,文件名是可用的Servlet中通過

String filename = request.getPathInfo().substring(1); 
相關問題