Home » excel » java – How to construct the response body for InputStream which has an Excel sheet file?

java – How to construct the response body for InputStream which has an Excel sheet file?

Posted by: admin May 14, 2020 Leave a comment

Questions:

I am writing a get API for getting excel sheet file stored in src/main/resources.

The InputStream has the content of excel file (xlsm format). But the response is having corrupted data.

@GetMapping("/downloadTemplate")
public ResponseEntity<?> downloadTemplate() throws IOException {
    String fn = "filename";

    try {
        File file = new File(getClass().getClassLoader().getResource(fn).getFile());
        InputStreamSource iss = new FileSystemResource(file);

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename= SimpleStandardTemplate.xlsm")
                .body(IOUtils.toByteArray(iss.getInputStream()));
    } catch (Exception e) {
        log.error("An error occurred while trying to downloadTemplate: {}", e);
        throw new ApiException(ApiErrorCode.DEFAULT_410, "Error while downloading");
    }
}

Seems like this line has a problem “body(IOUtils.toByteArray(iss.getInputStream()));” . If yet any alternate way? Else what could be the issue?

Edit: I think the issue is with content length.

How to&Answers:

Try this, tested with spring-boot 1.5.6

@GetMapping("/export")
  public ResponseEntity<Resource> download() throws IOException {
    String fileName ="<file-path>";
    Resource resource = new FileSystemResource(fileName);
    return ResponseEntity.ok()
        .contentType(MediaType.parseMediaType(MediaType.APPLICATION_OCTET_STREAM_VALUE))
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
        .body(resource);
  }

Answer:

One potential problem is that your original file is not xlsm file. For example, Excel doesn’t allow you to open a normal xlsx file under macro enabled mode. Please double check.

Answer:

I think your MIME type is wrong, Refer this for excel Mime types, I have change the way you send the file using Spring's FileSystemResource

@GetMapping(value = "/downloadTemplate", produces = "application/vnd.ms-excel.sheet.macroEnabled.12")
public FileSystemResource downloadTemplate(HttpServletResponse response) throws IOException {
    String fn = "filename";
    File file = new File(getClass().getClassLoader().getResource(fn).getFile()); 
    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename= SimpleStandardTemplate.xlsm");
    return new FileSystemResource(file); // You could directly pass the absolute path of the file
}