Return Excel downloadable file from Spring

32,254

You need to set the Content-Disposition header.

response.setHeader("Content-disposition","attachment; filename=" + yourFileName);

and write your bytes directly to the response OutputStream.

File xls = new File("exported.xls"); // or whatever your file is
FileInputStream in = new FileInputStream(xls);
OutputStream out = response.getOutputStream();

byte[] buffer= new byte[8192]; // use bigger if you want
int length = 0;

while ((length = in.read(buffer)) > 0){
     out.write(buffer, 0, length);
}
in.close();
out.close();

The above is relatively old. You can construct a ResponseEntity with FileSystemResource now. A ResourceHttpMessageConverter will then copy the bytes, as I have suggested above, for you. Spring MVC makes it simpler for you rather than having you interact with interfaces from the Servlet specification.

Share:
32,254
praks5432
Author by

praks5432

Updated on July 28, 2022

Comments

  • praks5432
    praks5432 almost 2 years

    So I have a Spring controller, and I'd like to create an Excel file and return it so that it is downloaded by the browser.

    I'm using JEXcelApi.

    This is my controller code

    @RequestMapping(value="/excel/cols/{colString}/rows/{rowString}/", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<String> exportExcel(HttpServletResponse response,
        @PathVariable List<String> colString,
        @PathVariable List<String> rowString) throws JSONException, IOException, WriteException {
        WritableWorkbook workbook = Workbook.createWorkbook(new File("exported.xls"));
        WritableSheet sheet = workbook.createSheet("Exported",0);
        String[] cols = colString.get(0).split(",");
        String[] rows = rowString.get(0).split(","); 
        for(int i = 0; i < cols.length;i++){
            Label label = new Label(i,0, cols[i]);
            sheet.addCell(label);
        }
        int excelCol = 0;
        int excelRow = 1;
        for(int i = 0; i < rows.length;i++){
            Label label = new Label(excelCol,excelRow, rows[i]);
            sheet.addCell(label);
            excelCol++;
            if((i+1) % cols.length == 0){
                excelCol = 0;
                excelRow++;
            }
        }
        workbook.write();
        workbook.close();
        return null;
    }
    

    How do I do that? I suspect there's some content header I can set. I know one method is to use Spring's Abstract Excel view class, but is there a simpler method?

  • praks5432
    praks5432 almost 11 years
    ah so what then gets returned?
  • praks5432
    praks5432 almost 11 years
    ah, is there any chance you could write the writing to stream code?
  • praks5432
    praks5432 almost 11 years
    so I tried that - but nothing is downloading, instead what's happening is something is console logging out - this is coming from the success function from my client
  • praks5432
    praks5432 almost 11 years
    oh one more question - is there a way to dynamically alter the buffer array - because if the file is very big, this method won't work right?