4

I want to download a file from Web Api, using Angular as a client side. My file is unfortunately broken when I downloading it at my browser. I think it is a fault of type discrepancy.

Web Api controller returns "byte[]"

Angular service:

    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers, responseType: ResponseContentType.Blob });
    return this.http.post(this.baseUrl + '/MyAction', ac, options)
        .map(res => res.blob())
        .catch(this.handleError);

Angular component ts

  this.service.downloadXls(items).subscribe(
            data => this.downloadFile(data)),
             error => console.log("Error downloading the file."),
             () => console.info("OK");
  }
  downloadFile(data: Blob) {
    let blob = new Blob([data], { type: 'application/vnd.ms-excel' });
    let url= window.URL.createObjectURL(blob);
    window.open(url);
  }

As I understand I need to receive byte[] and convert it to blob on the client side. Or convert and send blob on the server side. I don't know how to do either.

8
  • Why is this marked as duplicate? To OP: You need to use this: github.com/eligrey/FileSaver.js Commented Mar 21, 2018 at 14:49
  • Had problems with File saver. The method I used works fine. Problem is that my file is broken Commented Mar 21, 2018 at 14:55
  • 1
    The method you use only 'seems' to work. The problem is it isn't decoding it correctly, that's why you get a broken file. Commented Mar 21, 2018 at 15:00
  • Post another question detailing the problem you are having with FileSaver, I will try to help. Commented Mar 21, 2018 at 15:01
  • 2
    I'm only speaking from a Java standpoint more than anything else, but I'm not fully convinced that this question is a dupe. What is the MIME type that you want to send across? Commented Mar 21, 2018 at 15:13

1 Answer 1

2

Fetching a binary stream is not that straightforward, I suggest you use FileSaver.js to do the heavy lifting.

I don't have Angular experience, but here is a code snippet I used on a project not too long ago. It is plain JavaScript but should be reusable on Angular with minor modification:

<html>
  <head>
  <script src="FileSaver.min.js"></script>
  <script>        
    function download() {            
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "http://your.url", true);
        xhr.setRequestHeader("Content-type","application/json");
        xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
        xhr.setRequestHeader("Accept", "application/octet-stream");
        //xhr.setRequestHeader("Authorization", "Bearer ......");
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                var blob = new Blob([xhr.response], {type: "octet/stream"});
                var fileName = "my_excel_file.xlsx";
                saveAs(blob, fileName);
            }
        }
        xhr.responseType = "arraybuffer";
        xhr.send();
    }        
  </script>
</head>
<body>
  <button onclick="javascript:download()">Download Excel File</button>
</body>
</html>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.