11

I am using Apache POI to generate .xlsx file.

I would like to return that file from Spring controller. Here's what I've done so far:

Controller:

@RequestMapping(method = RequestMethod.GET)
    public HttpEntity<byte[]> createExcelWithTaskConfigurations(HttpServletResponse response) throws IOException {
        byte[] excelContent = excelService.createExcel();

        HttpHeaders header = new HttpHeaders();
        header.setContentType(new MediaType("application", "vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        header.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=my_file.xls");
        header.setContentLength(excelContent.length);

        return new HttpEntity<>(excelContent, header);
    }

Is it possible to return actual excel file from rest controller so user can download it to his computer ? As for now controller returning byte[] but I would like to return it actual file. How can I achieve that ?

Martin Čuka
  • 10,400
  • 4
  • 20
  • 45
  • You can use standart apache commons utils to download file. [Similar question.](https://stackoverflow.com/questions/5673260/downloading-a-file-from-spring-controllers) – Igor Konyaev Aug 04 '18 at 10:21
  • Yes, I've already read it. I've tried to return InpurtStream from Service creating excel then used IOUtils.copy(targetStream, response.getOutputStream()); in controller but it only "print" response in unreadable characters. I would like to actually download the file from controller. No luck so far – Martin Čuka Aug 04 '18 at 10:33
  • How about like [that](https://stackoverflow.com/questions/43261106/convert-bytearray-to-xssfworkbook-using-apache-poi)? This question is also very close to yours. – Igor Konyaev Aug 04 '18 at 10:41
  • Have a look at https://stackoverflow.com/a/35683261/4516887 – fateddy Aug 04 '18 at 12:18

3 Answers3

19

You can use ByteArrayResource to download as a file. Below is the modified code snippet of yours

    @GetMapping(value="/downloadTemplate")
    public HttpEntity<ByteArrayResource> createExcelWithTaskConfigurations() throws IOException {
        byte[] excelContent = excelService.createExcel();

        HttpHeaders header = new HttpHeaders();
        header.setContentType(new MediaType("application", "force-download"));
        header.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=my_file.xlsx");


        return new HttpEntity<>(new ByteArrayResource(excelContent), header);
    }

If you are trying to generate excel using apache poi, please find the code snippet below

    @GetMapping(value="/downloadTemplate")
    public ResponseEntity<ByteArrayResource> downloadTemplate() throws Exception {
        try {
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            XSSFWorkbook workbook = createWorkBook(); // creates the workbook
            HttpHeaders header = new HttpHeaders();
            header.setContentType(new MediaType("application", "force-download"));
            header.set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=ProductTemplate.xlsx");
            workbook.write(stream);
            workbook.close();
            return new ResponseEntity<>(new ByteArrayResource(stream.toByteArray()),
                    header, HttpStatus.CREATED);
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
Olivier Depriester
  • 1,609
  • 1
  • 6
  • 18
vettrivel18
  • 306
  • 2
  • 4
  • Thanks for the Excel / POI example, great solution imo as it fits in nicely the with the Spring way of doing things . FYI for anyone using this, by 'fitting in with Spring' I mean it returns Spring's ResponseEntity, and the classes doing the download wok are from org.springframework.core.io and org.springframework.http packages. – MetalRules Apr 14 '20 at 00:14
  • what is XSSFWorkbook workbook = createWorkBook();?? – KevO Jul 02 '21 at 05:07
2

Thanks to @ JAR.JAR.beans. Here is the link: Downloading a file from spring controllers

@RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
@ResponseBody 
public FileSystemResource getFile(@PathVariable("file_name") String fileName) {
    return new FileSystemResource(myService.getFileFor(fileName)); 
}
Mafuj Shikder
  • 143
  • 1
  • 8
1

This is working code I have used to download txt file. Same should do for excel file as well.

@GetMapping("model")
public void getDownload(HttpServletResponse response) throws IOException {


    InputStream myStream = your logic....

    // Set the content type and attachment header.  for txt file
    response.addHeader("Content-disposition", "inline;filename=sample.txt");
    response.setContentType("txt/plain");

    // xls file
    response.addHeader("Content-disposition", "attachment;filename=sample.xls");
    response.setContentType("application/octet-stream");

    // Copy the stream to the response's output stream.
    IOUtils.copy(myStream, response.getOutputStream());
    response.flushBuffer();
}
MyTwoCents
  • 6,573
  • 3
  • 21
  • 47