0

I have a web application in which I want to download a xls file. The controller in spring-boot will return a HttpServletResponse via a get request:

@RequestMapping(method = RequestMethod.GET, value = "/export/{id}", produces = { "multipart/mixed", "multipart/form-data" })
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public void export(@PathVariable String id, HttpServletResponse response) {
    XSSFWorkbook wb = service.export(assessmentId);
    String filename="test.xlsx";
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-Disposition", "attachment; filename=test.xlsx");

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    try {
        wb.write(bos);
        byte[] barray = bos.toByteArray();
        InputStream is = new ByteArrayInputStream(barray);
        IOUtils.copy(is, response.getOutputStream());

    } catch (IOException e) {    
        e.printStackTrace();
    }
}

In the client I want to export the file to a xls and this is the code:

var blob = new Blob([data], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
var objectUrl = URL.createObjectURL(blob);
var a = document.createElement("a");
a.style = "display: none";
a.href = objectUrl;
a.download = "test.xlsx";
document.body.appendChild(a);
a.click();

I am getting file corrupt when trying to open the xlsx file.

gohil90
  • 517
  • 5
  • 16
georgiana_e
  • 1,809
  • 10
  • 35
  • 54
  • 1
    Is there a reason why you can't just [send the file as a download from the controller](https://stackoverflow.com/questions/5673260/downloading-a-file-from-spring-controllers)? In HTML use something like `` – DJDaveMark Feb 07 '18 at 12:41
  • your solution worked, thanks. – georgiana_e Feb 07 '18 at 13:25

2 Answers2

2

Is there a reason why you can't just send the file as a download from the controller? In HTML use something like

<a href="/export/124875"><i class="fa fa-download"></i></a>
DJDaveMark
  • 2,669
  • 23
  • 35
0

I had a problem similar to this one. I solved it using another workaround: Instead of using ajax, use form to submit. You can surround only the download button like this:

<form class="myform" name="myform" enctype="application/x-www-form-urlencoded" method="POST">    
                                            <button type="button" class="btn btn-default btn-sm"
                                                id="download-btn" onclick="submitDl()">Download</button>
                                        </form>

submit:

function submitDl() {
   window.document.myform.action= your_api_url;
   window.document.myform.encoding='application/x-www-form-urlencoded';
   window.document.myform.submit();
}

In controller:

byte[] barray = bos.toByteArray();
        response.setHeader("Content-Disposition", "attachment; filename=" + name_of_your_excel + ".xls");
        response.getOutputStream().write(barray);
        response.flushBuffer();

for ppl that has path already do this instead, convert the path to byte[]:

byte[] bytes = Files.readAllBytes(Paths.get("path_of_excel_you_created")); 

response.setHeader("Content-Disposition", "attachment; filename=" + name_of_your_excel + ".xls"); response.getOutputStream().write(bytes); response.flushBuffer();

You can just put void for the return no need to return byte or something...