1

I have an application that is a Springboot backend and a reactJs frontend. I am able to successfully download an excel workbook on my localhost through the application as well as in postman without any errors, but when I test the app on the server I get an error that the file format or extension is not valid.

Also when I test the apps actual url using postman I get a 200 response but nothing is actually returned.

I am using axios and read over this post.

On the backend, the excel workbook is being put together using Apache POI XSSFworkbook.

The backend response entity looks like this

return ResponseEntity
                .ok()
                .contentType(MediaType.valueOf("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + params.getDeqId() + "Data.xlsx").body(workbook::write);

On the react side, I've tried a few different things. Currently I have:

return axios
      .post(`/api/excelexport/watersystemexcel`, submittedData, { responseType: "arraybuffer" })
      .then((response) => {
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement("a");
        link.href = url;
        link.setAttribute("download", submittedData.deqId + "Data.xlsx");
        document.body.appendChild(link);
        link.click();
        this.setState(() => ({ downloading: false }));
      });

I have also tried formating the axios request like:

axios.post(`/api/excelexport/watersystemexcel`, submittedData, {
      responseType: "arraybuffer",
      headers: { "Content-Type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }
    })

but this results in a 415 error, saying that that specified content-type isn't acceptable.

Lastly, I have also tried changing the file extension to .xls rather then .xlsx on both the front and backend. When I do this the workbook does download but when the file is opened there is an error that file extensions don't match, and that the file may be corrupt.

  • The content type "openxmlformats-officedocument" is for files with extensions .ods and eventually support .xls which is the legacy Microsoft Excel while the .xlsx is the newer Microsoft Excel format , you cannot simply rename an xlsx to xls because they are different formats. The content type for xlsx should be "application/vnd.ms-excel" eventually to doublechekc that is a file format issue you can convert the current file xlsx to xls using Microsoft Office or even the web version of it, which is available for free in case you upload your file on a Onedrive free account and give it a try. – A. Lion Dec 08 '21 at 21:05

1 Answers1

0
return ResponseEntity
                .ok()
                .contentType(MediaType.valueOf("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + params.getDeqId() + "Data.xlsx")
                .body(workbook::write);

When you build your own ResponseEntity object, you have not specified the Content Length, so it could be problematic, and maybe that's why you get a corrupted file at the end. That's how I do when I need to display images or videos :

return ResponseEntity.status(HttpStatus.OK).contentLength(cr.contentLength()).body(cr);

where cr is a FileSystemResource or a ClasspathResource or whatever Resource you need to send as a HTTP Response Entity. It seems to be identical, but not, look at the end of my code with the contentLength part before the body part.

BendaThierry.com
  • 2,080
  • 1
  • 15
  • 17