5 Replies Latest reply on Jul 2, 2009 11:33 PM by Francois Eric

    Serializing large CSV file

    Francois Eric Novice


      I would like to serialize a large object tree to a csv without busting my memory.

      My object tree is a map that contains approximately 1,000,000 objects.  Today, I iterate through the object tree and stock everything in a StringBuffer.  I then send this buffer content to my JSF page:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
          <h:messages styleClass="message" infoClass="success" errorClass="error" warnClass="warning"/>
          <f:view contentType="text/csv">#{reportTemplateAction.reportContent}</f:view>

      Obviously this is causing me to have twice the representation of the object in memory at once and causing me memory issues.

      Is there any way I can serialize this with JSF and seam while iterating through it?


        • 1. Re: Serializing large CSV file
          Nikos Paraskevopoulos Novice


          I have done something similar: A link that generates a file, then serves its content to the client. In other words a standard download link. NOTE: my use case does not submit the form. The data is gathered in a wizard and after finishing it, the user is provided with a link to download the generated document. Your code seems to contain a messages component, so it may be different use case. Anyway, here is how:

          First you need a link that calls an action:

          <s:link value="..." action="#{generationBean.download}" />

          In the action method:

          public class GenerationBean {
               public void download() {
                    // watch out if it may run in portal!!!
                    HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
                    response.setContentType(...as appropriate...);
                    response.addHeader("Content-disposition", "attachment; filename=\"THE FILENAME HERE\"");
                    try {
                         ServletOutputStream os = response.getOutputStream();
                         os.write(...data...); // ITERATE OVER YOUR STRUCTURE AND WRITE DATA, A PIECE AT A TIME
                         // OR GIVE THE ServletOutputStream TO ANYTHING THAT WRITES TO STREAMS
                         FacesContext.getCurrentInstance().responseComplete(); // DONT FORGET THIS ONE
                    catch(IOException ioe) {

          The browser sees the content type and acts accordingly. The JSF mechanism obeys the responseComplete() command and does not execute the render response phase.

          • 2. Re: Serializing large CSV file
            Francois Eric Novice

            Awesome.  Exactly what I was looking for.


            • 3. Re: Serializing large CSV file
              Francois Eric Novice

              Works well but the only thing is that the attachment is not downloadable but inserted directly in browser.  I would like to have a popup where the user chooses to save or open the attachement.  My code is the following:

                          HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
                          response.addHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
                          if(reportTemplate.getIsDaily()) {
                              facadeLocator.getReportTemplateGeneratorDailyFacade().generateCSVReport(reportTemplate, response.getOutputStream());
                          } else {
                              facadeLocator.getReportTemplateGeneratorHourlyFacade().generateCSVReport(reportTemplate, response.getOutputStream());

              where the content is generated by my methods.

              How can I force the attachment (even though I have set it in the header)?



              • 4. Re: Serializing large CSV file
                Cody Lerum Apprentice

                It's a function of the clients browser.

                IF you want it downloaded then response.setContentType(application/octet-stream);

                Otherwise specify the correct mime type (text/csv) and if clients browser can handle the type then it will be loaded in the browser.

                • 5. Re: Serializing large CSV file
                  Francois Eric Novice

                  Thanks Cody.

                  Actually the problem was even simpler.  I was using a a4j:commandButton for my download link.  By using a h:commandButton it solved my problem and now works flawlessly.

                  Thanks again to both of you.