download csv file from web api in angular js
my API controller is returning a csv file as seen below:
[HttpPost]
public HttpResponseMessage GenerateCSV(FieldParameters fieldParams)
{
var output = new byte[] { };
if (fieldParams!= null)
{
using (var stream = new MemoryStream())
{
this.SerializeSetting(fieldParams, stream);
stream.Flush();
output = stream.ToArray();
}
}
var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(output) };
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "File.csv"
};
return result;
}
and my angularjs that will send and receive the csv file is shown below:
$scope.save = function () {
var csvInput= extractDetails();
// File is an angular resource. We call its save method here which
// accesses the api above which should return the content of csv
File.save(csvInput, function (content) {
var dataUrl = 'data:text/csv;utf-8,' + encodeURI(content);
var hiddenElement = document.createElement('a');
hiddenElement.setAttribute('href', dataUrl);
hiddenElement.click();
});
};
In chrome, it downloads a file which is called document
but has no file type extension.
The content of the file is [Object object]
.
In IE10, nothing is downloaded.
What could i do to fix this?
UPDATE: This might work for you guys out there with the same problem: link
Try it like :
File.save(csvInput, function (content) {
var hiddenElement = document.createElement('a');
hiddenElement.href = 'data:attachment/csv,' + encodeURI(content);
hiddenElement.target = '_blank';
hiddenElement.download = 'myFile.csv';
hiddenElement.click();
});
based on the most excellent answer in this question
I used the below solution and it worked for me.
if (window.navigator.msSaveOrOpenBlob) {
var blob = new Blob([decodeURIComponent(encodeURI(result.data))], {
type: "text/csv;charset=utf-8;"
});
navigator.msSaveBlob(blob, 'filename.csv');
} else {
var a = document.createElement('a');
a.href = 'data:attachment/csv;charset=utf-8,' + encodeURI(result.data);
a.target = '_blank';
a.download = 'filename.csv';
document.body.appendChild(a);
a.click();
}
None of those worked for me in Chrome 42...
Instead my directive now uses this link
function (base64
made it work):
link: function(scope, element, attrs) {
var downloadFile = function downloadFile() {
var filename = scope.getFilename();
var link = angular.element('<a/>');
link.attr({
href: 'data:attachment/csv;base64,' + encodeURI($window.btoa(scope.csv)),
target: '_blank',
download: filename
})[0].click();
$timeout(function(){
link.remove();
}, 50);
};
element.bind('click', function(e) {
scope.buildCSV().then(function(csv) {
downloadFile();
});
scope.$apply();
});
}
The last answer worked for me for a few months, then stopped recognizing the filename, as adeneo commented ...
@Scott's answer here is working for me:
Download file from an ASP.NET Web API method using AngularJS