AngularJS $http-post - convert binary to excel file and download AngularJS $http-post - convert binary to excel file and download json json

AngularJS $http-post - convert binary to excel file and download


Just noticed you can't use it because of IE8/9 but I'll push submit anyway... maybe someone finds it useful

This can actually be done through the browser, using blob. Notice the responseType and the code in the success promise.

$http({    url: 'your/webservice',    method: "POST",    data: json, //this is your json data string    headers: {       'Content-type': 'application/json'    },    responseType: 'arraybuffer'}).success(function (data, status, headers, config) {    var blob = new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});    var objectUrl = URL.createObjectURL(blob);    window.open(objectUrl);}).error(function (data, status, headers, config) {    //upload failed});

There are some problems with it though like:

  1. It doesn't support IE 8 and 9:
  2. It opens a pop up window to open the objectUrl which people might have blocked
  3. Generates weird filenames

It did work!

blobThe server side code in PHP I tested this with looks like this. I'm sure you can set similar headers in Java:

$file = "file.xlsx";header('Content-disposition: attachment; filename='.$file);header('Content-Length: ' . filesize($file));header('Content-Transfer-Encoding: binary');header('Cache-Control: must-revalidate');header('Pragma: public');echo json_encode(readfile($file));

Edit 20.04.2016

Browsers are making it harder to save data this way. One good option is to use filesaver.js. It provides a cross browser implementation for saveAs, and it should replace some of the code in the success promise above.


This is how you do it:

  1. Forget IE8/IE9, it is not worth the effort and does not pay the money back.
  2. You need to use the right HTTP header,use Accept to 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' and also you need to put responseType to 'arraybuffer'(ArrayBuffer but set with lowercase).
  3. HTML5 saveAs is used to save the actual data to your wanted format. Note it will still work without adding type in this case.
$http({    url: 'your/webservice',    method: 'POST',    responseType: 'arraybuffer',    data: json, //this is your json data string    headers: {        'Content-type': 'application/json',        'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'    }}).success(function(data){    var blob = new Blob([data], {        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'    });    saveAs(blob, 'File_Name_With_Some_Unique_Id_Time' + '.xlsx');}).error(function(){    //Some error log});

Tip! Don't mix " and ', stick to always use ', in a professional environment you will have to pass js validation for example jshint, same goes for using === and not ==, and so on, but that is another topic :)

I would put the save excel in another service, so you have clean structure and the post is in a proper service of its own. I can make a JS fiddle for you, if you don't get my example working. Then I would also need some json data from you that you use for a full example.

Happy coding.. Eduardo


Download the server response as an array buffer. Store it as a Blob using the content type from the server (which should be application/vnd.openxmlformats-officedocument.spreadsheetml.sheet):

var httpPromise = this.$http.post(server, postData, { responseType: 'arraybuffer' });httpPromise.then(response => this.save(new Blob([response.data],    { type: response.headers('Content-Type') }), fileName));

Save the blob to the user's device:

save(blob, fileName) {    if (window.navigator.msSaveOrOpenBlob) { // For IE:        navigator.msSaveBlob(blob, fileName);    } else { // For other browsers:        var link = document.createElement('a');        link.href = window.URL.createObjectURL(blob);        link.download = fileName;        link.click();        window.URL.revokeObjectURL(link.href);    }}