Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return Excel downloadable file from Spring

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?

like image 200
praks5432 Avatar asked Sep 06 '13 02:09

praks5432


1 Answers

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.

like image 133
Sotirios Delimanolis Avatar answered Oct 19 '22 17:10

Sotirios Delimanolis