Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

jsf 2 - Action link and download link in one

I need to show a link to download a file on a page in a JSF 2 application. Now, the issue is that the file contains data that depends on fresh looks into the database at the time of creation. But what I want to do is create it AND give the user a link to download it in one action.

This would be very simple to do in two actions: have a button to generate the file, and replace it with a link to download the file once it's generated.

So the question again is can this be done in one click on a commandLink?

EDIT, following BalusC's comment below. Here's the specifics of what I am trying to do, and have done so far. I have this in the 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> 

This works. The button creates an excel file, saves it to a location, and updates the file name in the database. Then the link serves the file. But it's a two step process for the user. What I'd like it to be is just one step. So that one link, for example:

<a href="#{bean.findBidsListFileName()}">Download Your Bids</a>

or, most likely, a jsf commandLink will create the excel file on the back end, save it to the /resources/ location, and seamlessly open a "save" dialog on the user's machine.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can just let JSF immediately write the report to the OutputStream of the HTTP response instead of to the OutputStream of the local disk file system.

Here's a basic example, assuming that you're using Apache POI to create the Excel report:

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

This way you can end up with just a single command link (or button).

<h:form>
    <h:commandLink value="Create and download bids report" action="#{bean.createAndDownloadBidsReport}" />
</h:form>

Note that this doesn't save it to disk file system. If you really need to have a copy then you'd need to add another bidsReport.write() line which writes to the desired disk file system location.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...