views:

101

answers:

4

I have an requirement of generating two excel files at once. We are using Apache POI for generating excel files and struts framework.

Within the action class, the steps are like,

OutputStream outputStream = response.getOutputStream();

and then populate data from db and created one file using POI and called,

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition",
                 "attachment; filename=ExportFile1.xls");
workbook.write(outputStream);
outputStream.flush();

and followed same steps(populate data from db, write excel content) for second file as,

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition",
                 "attachment; filename=ExportFile2.xls");
workbook.write(outputStream);
outputStream.flush();

But only one file is generated.

Is this possible in java to generate two files at once? Have anyone implemented this?

Pls note: Generating two sheets within one excel file is not required.

A: 

I'm not familiar with the Apache POI. However, you need to have two OutputStreams in order to write to two files.

With the code you've provided, it looks like all you've done is change the header of the file from thinking it's "ExportFile1.xls" to "ExportFile2.xls", and then written out the file contents (with a header claiming to get file2) to a stream. I suspect you'll need a second resonse object for the second stream, too.

Brian S
hi, i tried your suggestion but it throws exception, java.lang.IllegalStateException: getOutputStream() has already been called for this response
karthikn_jay
Note the last part. "I suspect you'll need a second resonse object for the second stream, too." (or use the other ideas provided in other answers)
MatrixFrog
@MatrixFrog. Yes, I tried that using two reference objects outputStream1 and outputStream2 both getting streams as response.getOutputStream();
karthikn_jay
Trying to get two different output streams != trying to get two different responses.
MatrixFrog
A: 

The nub of this question is how to send multiple files in an HTTP response. This won't happen by default. And if you do what you are currently doing you (naturally) end up with one downloaded file containing a concatenation of the two excel workbooks, and no easy way for the browser to separate them.

In order to do send 2 distinct excel files, you would need to encode them using some schema that the browser knows how to unpick. One way to do this is to send a response with a "multi-part" content type as described in RFC1341 section 7.2. I expect someone can chime in with an appropriate java library that will take care of creating the multi-part content stream.

Another way would be to encode the two (or more) files as a ZIP archive. The Java class library has classes for creating a ZIP archive programmatically.

Stephen C
+3  A: 

I have an requirement of generating two excel files at once.

I had similar requirements, but this wasn't to "generate with one click", because if the user would be presented with "save as" dialogs for two or more files would be very confusing to the end-user.

  1. So there was a "generate" button, that would generate the files (with a progress bar if the procedure takes more time) and than redirect to another page (or popup) that would contain individual links of those multiple files, so the user could take them one by one, or only the desired ones.

  2. If the user still needs to get "with only one click" than zipping all files is the standard procedure. For more usability, that could be combined/improved with the screen or popup from scenario #1 : e.g. to show a list with checkboxes for each file, and a link at the bottom to "get all as a zip". That way, the user could download individually files, but also select only the files is interested in, or simply just get all.

This is how most webapps do it since it's the most user friendly.

A. Ionescu
@a.lonescu for pt.1 - After clicking generate, I could show links with 2 excel icons. Clicking on each icon will generate each file. But where will I keep those files, in memory(request scope) or db(needs seperate table) or a temp folder in web server(I think, all of these are bad ideas) ? Any ideas.
karthikn_jay
@a.lonescu pt.2 looks like a good idea. But it has to generate two files dynamically everytime and then zip it. Is that possible? Seems like to do a lot of extra(zipping) work.
karthikn_jay
You can keep in memory if the files are not too big, or in temporary files: both are very simple to implement. I'm not sure if it's really needed to keep them in a database however (this is done only if the generation is very expensive - e.g. some reports might take a few hours to run - in this case a notification system is also required). The Java ZIP API is quite simple and it allows you to zip whatever content you need - from memory or from disk and anytime you want - it takes just a few lines of code.
A. Ionescu
A: 

You can only send a single file back.

In your case I would generate a zip file containg the two excel files and return that. Dó it with files initially and if needed you Can dó it All in memory.

Thorbjørn Ravn Andersen