0

スタック: JasperReportsを使用したJBoss AS上のJSF + PrimeFaces

JasperReports を使用して、次の 3 つの手順で PDF 形式にエクスポートするパターンを使用しています。

[1]戦争中の道から編集されたジャスパーレポートを入手する

[2]セッションにJasperPrintオブジェクトを配置する

[3] PdfServletのURLにリダイレクト

したがって、ユーザーが GUI からp:commandButtonをクリックすると、次のコード例のように [1]、[2]、および [3] を通過するバッキング Bean のメソッドが呼び出されます。

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;
}

2 つの質問があります。

[i] このアプローチで明らかなコードの臭いや制限はありますか?

[ii] 上記のコード例では、Chrome と Conkeror の両方がレポートを保存できますが、ファイルを保存するためにユーザーに提示するデフォルトのファイル名は単に「pdf」です。それを意味のある名前 (例: "report-2012-08-23c.pdf") に設定するにはどうすればよいですか?

4

1 に答える 1

1

「名前を付けて保存」ファイル名に関する具体的な問題については、ヘッダーで特に指定されていない限り、デフォルトでリクエスト URL の最後のパスになります (これは/servlets/pdf実際には単にの場合です)。pdfContent-Disposition

この問題は、JSF コードが直接原因ではありません (それ自体が奇妙ですが、それは別の問題/質問です) /servlets/pdf。目的の「名前を付けて保存」ファイル名を設定するには、応答にバイトを書き込む前に次の行を追加する必要があります。

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

デフォルトでインラインで表示したい場合は、必要に応じて置き換えることができattachmentます。inline

ただし、Internet Explorer ブラウザーはこの値を無視し、要求 URL の最後のパスを使用し続けます。したがって、そのブラウザーもカバーするには、要求 URL に目的のファイル名を自分で含めて、サーブレットのマッピングを変更する必要があります。

例えば

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

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

この URL パターンでは、ファイル名は、

String filename = request.getPathInfo().substring(1);
于 2012-08-24T11:23:16.383 に答える