9

I'm generating an Excel file in my WebAPI. I "store" it in a memorystream and then put in the the response as follow :

var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StreamContent(ms) };

            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = projectName + ".xlsx"
            };
           // ms.Close();
            return result;

It looks like the server side is working correcty. If I'm writing that memorystream into a filestream, the file is created and can be open without any problem.

On angular side, how can I recreate the file when click on a button?

I tried something like this :

$scope.exportQuotas = function (projectName) {
    homeService.GetQuotas(projectName, $routeParams.token, $scope.selection).then(
             function (data) {
                 var dataUrl = 'data:application/octet-stream;' + data
                 var link = document.createElement('a');
                 angular.element(link)
                   .attr('href', dataUrl)
                   .attr('download', "bl.xlsx")
                   .attr('target', '_blank')
                 link.click();
             })
}

The file is created but when I tried to open it, it's corrupted... I've tried changing the data type to vnd.ms-excel in angular but it didn't work... How can I get the file to be downloaded on click?

EDIT After Jorg answer, I tried the following : What the api returns is :

Status Code: 200
Pragma: no-cache
Date: Tue, 02 Sep 2014 02:00:24 GMT
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Type: application/binary
Access-Control-Allow-Origin: *
Cache-Control: no-cache
X-SourceFiles: =?UTF-8?B?        QzpcVXNlcnNcdHJpaGFuaC5waGFtXFByb2plY3RzXFF1b3RhUXVlcnlcUXVvdGFRdWVyeUFQSVxhcGlccXVvdGFcR2V0?=
Content-Disposition: attachment; filename=O14Y0129AUG.xlsx
Content-Length: 13347
Expires: -1

From what I can see, it looks correct.

In client side :

                 var file = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' });
                 var fileURL = URL.createObjectURL(file);
                 window.open(fileURL);

A excel file is created but it's still corrupted...

Thanks

2
  • I got mine working like this: stackoverflow.com/questions/22447952/… Commented Sep 2, 2014 at 0:20
  • It didn't work for me though :( file is corrupted... also as metionned, the filename is weird... Commented Sep 2, 2014 at 2:20

2 Answers 2

17

I had the same problem. The file was OK server side, but when downloaded it became corrupt.

What solved it for me was to add responseType: "arraybuffer" to the server request.

Then when calling this line var file = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' }); The data variable should be of type ArrayBuffer, and not a string.

Sign up to request clarification or add additional context in comments.

4 Comments

Could you please provide the full code as to how you added responseType: "arraybuffer" to the server request?
@Shivam657 This is how you add response type to your request: $http.get(url, { responseType: "arraybuffer" })
working fro me with cache : false ,responseType: "arraybuffer",
savior @daniel thank you so much daniel i was facing this issue from last 2days
1

The main issue comes from the fact that by default, XMLHttpRequest uses the default response type which is an empty String. See this link. Your binary data are therefore not correctly handled.

When using javascript API, you need to take care of the response type for binary data. Otherwise, it will be interpreted as a String.

API like angular-file-upload (last version is currently 1.1.5) for example does not provide the possibility to set the response type of data received after an upload. I had to update the API to define the response type.

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.