1

I've been banging my head against the wall on this problem for a while now, and I've done my fair share of looking through existing StackOverflow questions that are similar to my predicament, but haven't found a solution that works for me yet.

I've got existing code that takes an HttpServletResponse and exports it as an .xls attachment for the user to download. This code is presented here:

import java.io.IOException;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;

/**
 * Action class to export data as a excel sheet.
 *
 */
public class ForecastReportExcel extends PageCodeBase {

public String exportExcel() throws IOException {
    HttpServletResponse response = (HttpServletResponse) FacesContext
            .getCurrentInstance().getExternalContext().getResponse();
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-Disposition",
            "attachment; filename=forecastReports.xls");
    return "success";
 }
}

My requirements for this project are simply to change the exported file from an .xls file to an .xlsx file. Which seemed like a pretty simple undertaking.

My first attempt was to simply change the MimeType to application/vnd.openxmlformats-officedocument.spreadsheetml.sheetand the filename to forecastReports.xlsx. AFter downloading the exported file from the webapp, I get the error - Excel cannot open the file '[file].xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file.

So, I went to searching and came across some threads where people suggested using the Apache POI libraries, specifically the XSSF Library for .xlsx files, and writing to the OutputStream. So, I gave this a whirl:

import java.io.IOException;
import java.io.OutputStream;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * Action class to export data as a excel sheet.
 *
 */
public class ForecastReportExcel extends PageCodeBase {


public String exportExcel() throws IOException {
    XSSFWorkbook workbook = new XSSFWorkbook();
    HttpServletResponse response = (HttpServletResponse) FacesContext
            .getCurrentInstance().getExternalContext().getResponse();
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setHeader("Content-Disposition",
            "attachment; filename=forecastReports.xlsx");

    OutputStream outStream = response.getOutputStream();
    workbook.write(outStream);
    outStream.flush();
    outStream.close();
    return "success";
 }
}

When I download the exported file and run it in Excel, I get the message We found a problem with some content in '[file].xlsx'. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes. Upon clicking 'Yes', I get The workbook cannot be opened or repaired by Microsoft Excel because it is corrupt.

Also, when I take a look at my developer console, I'm seeing an error printing out that says java.lang.IllegalStateException: Cannot forward. Response already committed.

I've done some searching on what that means, but I'm not finding how it relates to this. Now, I'm super confused. Does anyone see anything I'm not seeing? Can someone give me some direction on what I'm doing wrong?

Thank you all so much for any help or ideas thrown my way!

Cole Carver
  • 11
  • 1
  • 2
  • 2
    You are rendering a response in the form of HTML while trying to download a file which is incorrect. See [here](http://stackoverflow.com/a/9394237/1391249). The other message is a warning against a malformed file which is likely not written properly while generating using Java code (Apache POI). – Tiny Sep 28 '15 at 15:42
  • I've continued to play with it, and I've found separating out the facesContext and the response, then adding `facesContext.responseComplete();` line before the return removes the IllegalStateException error, however, I'm still getting the corrupt file message. – Cole Carver Sep 28 '15 at 15:53
  • Can you return 'valid' textfiles? I doubt it works, try it. @Tiny: it is a combination. Most likely as I state, returning a text file, or pdf or whatever also returns in 'invalid' files. This question is not java, excel or xlsx related at all (poi maybe, but not excel or xlsx) – Kukeltje Sep 28 '15 at 19:17
  • When I have it output as a text/plain, it's a valid file, and it returns HTML in [file].txt. Still, when trying to do .xlsx, I get a corruption message. I've also updated the Tags to try to match my question better. Sorry about that. – Cole Carver Sep 29 '15 at 15:00
  • 1
    "it returns HTML" doesn't sound good. Did you mean to say that the output of the view as identified by "success" is also included in the file? In any case, you should also not return a navigation case at all, but just void or null and mark the response complete in faces context. Is this acceptable as dupe? http://stackoverflow.com/questions/9391838/how-to-provide-a-file-download-from-a-jsf-backing-bean – BalusC Sep 29 '15 at 16:02
  • 1
    What I mean is - when I open the downloaded file in a text editor after changing the mimeType to "plain/text", or even as the .xlsx sheet, it shows as HTML and CSS Markup. However, if I leave the filename as '[file].xls', when I open it in excel, it opens as a workbook properly, not as HTML. This is the most confusing part. -- When following the link provided, I'm doing exactly what is provided in the JSF 1.x example - with the addition of writing the outputStream to an XSSFWorkbook - and I'm still getting filetype mismatch errors. – Cole Carver Sep 29 '15 at 18:27
  • Me too getting the same shit .Did you got the solution. – goku Oct 14 '15 at 14:21

0 Answers0