-1

I have tried to use restController generate file byte array but when i return it to react , react didn't get the byte array. front-end is using react , back-end is using spring restController and i use Http to communication both front and back. is it any wrong in my code? Thank you for your helping.

restController:

String fileName = DateUtility.dateToStr(new Date(), DateUtility.YYYYMMDD_HHMMSS) + " - "
            + reportNmaeByType.get(exportParam.getReportType()) + ".xls";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentDispositionFormData("attachment", fileName);
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

    return new ResponseEntity<>(excelByte, HttpStatus.OK);

react:

createExcelFile(){
    var params = {
    reportResultList: this.state.reportResult, 
    reportType: getReportSelector().state.selectedReportType,
    selectColumnMap: this.state.selectColumn,
    selectCusColumnMap: this.state.selectCusColumn
                }
    fetch("http://localhost:8080/mark-web/file/createExcel", {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(params)
    }).then(res => {
        if (res.ok) {
            console.log(res)
            console.log(this)
             console.log('create excel success!!')
        } else {
            console.log('create excel Fail!!')
        }
    })
}

response: enter image description here

Update 2018/09/16:

I have added some code in react function and it finally could download excel file but the file is broken. i have checked the blob object in response. it shows blob is json object. is it because i didn't decode to the blob object?

React:

}).then(res => {
       if(!res.ok){
        console.log("Failed To Download File")
       }else{
        return res.blob()
       }
    }).then(blob => {
        console.log(blob)
        let url = URL.createObjectURL(blob)
        console.log(url)
        var downloadAnchorNode = document.createElement('a')
        downloadAnchorNode.setAttribute("href", url)
        downloadAnchorNode.setAttribute("download", "excel" + ".xls")
        downloadAnchorNode.click()
        downloadAnchorNode.remove()
    })

response:

enter image description here

Jack
  • 3
  • 1
  • 5

1 Answers1

0

So, from your network graph, it looks like your request is completing as expected, but you are just unable to derive the ByteArray from the response.

With normal requests which return a JSON or XML for e.x. you can read them in one go, as they are part of the body. In your case however, your body contains a Stream. You will thus have to handle reading that stream on your own.

You can do that with response.blob() :

The blob() method reads the stream to completion and returns a Blob object. You can then use this blob object to embed an image or download the file. For all intent and purposes, I would recommend using this. Unless you are dealing with huge files (>500 MB), it should suffice your needs.

For example:

fetch("http://localhost:8080/mark-web/file/createExcel", {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(params)
    }).then(res => {
        if (!res.ok) { 
            throw new Error(res.statusText);
        } else {
            return res.blob()
        }
   }).then(blob => {// do your thing})
   .catch(err => console.log(error))

Or

You can use the experimental ReadableStream interface for a more granular control over what you want to do with it.

dubes
  • 5,324
  • 3
  • 34
  • 47
  • i would like to ask a question. byte array and string Base64 are same thing here? Thank you for your helping – Jack Sep 11 '18 at 06:38
  • [Base64](https://en.wikipedia.org/wiki/Base64) is an encoding scheme, where as your Byte array is the content of your file. However, Spring could be sending you the byte array encoded in Base64. Normal blob operations should take care of it (I think), let me know if you run into a specific problem – dubes Sep 11 '18 at 06:56
  • Im facing on blob problem. i have provide some information on the top. i used java.util.Base64 to encode the excel file in restController. thank you for your answer sincerely. – Jack Sep 16 '18 at 17:36
  • @Jack this could be due to a wrong content type (should be octet-stream, but seems to be read as json) in your rest controller response. Take a look at this answer on how best to send a file: https://stackoverflow.com/a/35683261/1695393 let me know if it still doesn't work – dubes Sep 18 '18 at 07:28
  • thank you for your helping. i have solved my problems – Jack Sep 28 '18 at 09:53
  • Awesome! Great to hear! – dubes Sep 28 '18 at 10:50