0

I'm trying to send a xls file from my java spring server to react client.

Using default Apache POI constructors creates xlsx file, that's not good. In order to override it I have to create the file using FileOutputStream.

FileOutputStream outputStream = new FileOutputStream("file.xls");

But I cannot sent the file over the web. I've tried using the following answer: https://stackoverflow.com/a/54765335/10319765 I quote: "While downloading a file , your code needs to stream a file chunk by chunk - thats what Java streams are for."

return ResponseEntity.ok().contentLength(inputStreamWrapper.getByteCount())
        .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
        .cacheControl(CacheControl.noCache())
        .header("Content-Disposition", "attachment; filename=" + "file.xls")
        .body(new InputStreamResource(inputStreamWrapper.getByteArrayInputStream()));

so my controller is sending InputStreamResource.

How can I construct InputStreamResource using my FileOutputStream?

P.S this is my React client:

 axios.get('/issues/export', { responseType: 'arraybuffer' }).then(response => {
        if (response && !response.error) {
            const blob = new Blob([response.payload.data], {type: 'application/vnd.ms-excel'});
            saveAs(blob);
        }
    });

Source: https://stackoverflow.com/a/46331201/10319765

Edit:

I've managed to do that with a trick, right after I've written to the FileOutputStream I've opened a FileInputStream and returned the value.

    FileOutputStream outputStream = new FileOutputStream("file.xls");
    workbook.write(outputStream);
    workbook.close();
    final InputStream fileInputStream = new FileInputStream("file.xls");
    return fileInputStream;

but now, the xls file returned as response to the client is corrupted and has weird characters inside: enter image description here

enter image description here

The excel file should look the following (taken from my java server after sending it): enter image description here

Yahav
  • 146
  • 11

1 Answers1

0

Issue solved. Eventually what I did in order to solve the corrupted xls file is to work with byte arrays. the controller looks exactly the same but now the return type is ResponseEntity<byte[]>. To convert the InputStream to byte array I've used IOUtils.toByteArray() method.

Client side code has also changed a bit because now the type is no longer responseType: 'arraybuffer' but 'blob'.

 axios.get('/issues/export', { responseType: 'blob' }).then(response => {
    if (response && !response.error) {
        const blob = new Blob([response.payload.data]);
        saveAs(blob);
    }
});

That's all.

Yahav
  • 146
  • 11