Скачать csv файл из web api в angular js
мой API-контроллер возвращает файл csv, как показано ниже:
[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;
}
и мои угловые символы, которые будут отправлять и получать файл csv, показаны ниже:
$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();
});
};
В chrome он загружает файл, который называется document
, но не имеет расширения типа файла.
Содержимое файла [Object object]
.
В IE10 ничего не загружается.
Что я могу сделать, чтобы исправить это?
UPDATE:
Это может сработать для вас, ребята, с той же проблемой: ссылка
Ответы
Ответ 1
Попробуйте:
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();
});
на основе самого превосходного ответа в этом вопросе
Ответ 2
Я использовал решение ниже, и это сработало для меня.
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();
}
Ответ 3
Последний ответ работал на меня в течение нескольких месяцев, а затем прекратил распознавать имя файла, как прокомментировал adeneo...
@Scott ответ здесь работает для меня:
Загрузите файл из метода ASP.NET Web API с помощью метода AngularJS
Ответ 4
Ни один из них не работал у меня в Chrome 42...
Вместо этого моя директива теперь использует эту функцию link
(base64
заставила ее работать):
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();
});
}
Ответ 5
Мне пришлось реализовать это недавно. Мысль о том, чтобы поделиться тем, что я выяснил;
Чтобы заставить его работать в Safari, мне нужно было установить цель: "_self". Не беспокойтесь о имени файла в Safari. Похоже, он не поддерживается, как упоминалось здесь; https://github.com/konklone/json/issues/56 (http://caniuse.com/#search=download)
Нижеприведенный код отлично работает для меня в Mozilla, Chrome и Safari;
var anchor = angular.element('<a/>');
anchor.css({display: 'none'});
angular.element(document.body).append(anchor);
anchor.attr({
href: 'data:attachment/csv;charset=utf-8,' + encodeURIComponent(data),
target: '_self',
download: 'data.csv'
})[0].click();
anchor.remove();
Ответ 6
A.download не поддерживается IE. По крайней мере, на поддерживаемых HTML5 страницах.: (
Ответ 7
Вместо использования Ajax/XMLHttpRequest/$http для вызова вашего метода WebApi используйте форму html. Таким образом, браузер сохраняет файл, используя имя файла и информацию о типе содержимого в заголовках ответов, и вам не нужно обойти ограничения javascript при обработке файлов. Вы также можете использовать метод GET, а не POST, поскольку метод возвращает данные. Вот пример формы:
<form name="export" action="/MyController/Export" method="get" novalidate>
<input name="id" type="id" ng-model="id" placeholder="ID" />
<input name="fileName" type="text" ng-model="filename" placeholder="file name" required />
<span class="error" ng-show="export.fileName.$error.required">Filename is required!</span>
<button type="submit" ng-disabled="export.$invalid">Export</button>
</form>
Ответ 8
В Angular 1.5 используйте службу $window
для загрузки файла.
angular.module('app.csv').factory('csvService', csvService);
csvService.$inject = ['$window'];
function csvService($window) {
function downloadCSV(urlToCSV) {
$window.location = urlToCSV;
}
}
Ответ 9
Я думаю, что лучший способ загрузить любой файл, созданный вызовом REST, - это использовать window.location
Пример:
$http({
url: url,
method: 'GET'
})
.then(function scb(response) {
var dataResponse = response.data;
//if response.data for example is : localhost/export/data.csv
//the following will download the file without changing the current page location
window.location = 'http://'+ response.data
}, function(response) {
showWarningNotification($filter('translate')("global.errorGetDataServer"));
});