Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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

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

1 Answer

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...