我需要显示一个链接,以便在JSF 2应用程序的页面上下载文件。现在,问题是该文件包含的数据取决于创建时对数据库的全新外观。但我想要做的是创建它并给用户一个链接,以便在一个动作中下载它。
在两个操作中执行此操作非常简单:使用按钮生成文件,并将其替换为生成后下载文件的链接。
所以再问题是,只需点击一下commandLink就可以了吗?
编辑,遵循BalusC的评论如下。这是我要做的事情的具体细节,到目前为止已经完成了。我在xhtml中有这个:
<h:panelGroup rendered="#{!bean.showLinkToExcelFile()}">
<h:form>
<td><h:commandButton value="Generate list of your Bids for download" action="#{bean.createBidsList()}"/></td>
</h:form>
</h:panelGroup>
<h:panelGroup rendered="#{bean.showLinkToExcelFile()}">
<td><a href="#{bean.findBidsListFileName()}">Download Your Bids</a></td>
</h:panelGroup>
这很有效。该按钮创建一个excel文件,将其保存到某个位置,并更新数据库中的文件名。然后链接提供文件。但这对用户来说是一个两步过程。我希望它只是一步。所以一个链接,例如:
<a href="#{bean.findBidsListFileName()}">Download Your Bids</a>
或者,最有可能的是,jsf commandLink将在后端创建excel文件,将其保存到/ resources /位置,并在用户的计算机上无缝打开“保存”对话框。
答案 0 :(得分:5)
您可以让JSF立即将报告写入HTTP响应的OutputStream
,而不是本地磁盘文件系统的OutputStream
。
以下是一个基本示例,假设您使用Apache POI创建Excel报告:
public void createAndDownloadBidsReport() throws IOException {
// Prepare Excel report to be downloaded.
HSSFWorkbook bidsReport = createBidsReportSomehow();
String filename = "bids.xls";
// Prepare response to show a Save As dialogue with Excel report.
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
externalContext.setResponseContentType("application/vnd.ms-excel");
externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
// Write Excel report to response body.
bidsReport.write(externalContext.getResponseOutputStream());
// Inform JSF that response is completed and it thus doesn't have to navigate.
facesContext.responseComplete();
}
这样,您最终只能使用一个命令链接(或按钮)。
<h:form>
<h:commandLink value="Create and download bids report" action="#{bean.createAndDownloadBidsReport}" />
</h:form>
请注意,这不会将其保存到磁盘文件系统。如果确实需要有副本,那么您需要添加另一条bidsReport.write()
行,该行会写入所需的磁盘文件系统位置。
答案 1 :(得分:0)
我会使用正常的下载链接并将URL映射到动态生成文档的servlet。