2013-11-30 4 views
42

мой контроллер API возвращает файл CSV, как показано ниже:загрузить CSV-файл с веб-АФИ в угловых JS

[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; 
    } 

и мои angularjs, которые будут отправлять и получать файл 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: Это может работать для вас, ребята там с той же проблемой: link

+4

манипуляция DOM не должно быть сделано в контроллерах –

ответ

57

Постарайся это нравится:

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(); 
}); 

на основе самого превосходного ответа в this question

+0

загружает файл с расширением .csv, но содержимое внутри - это не тексты, а слово: [object Object] –

+1

Тогда 'content' - это объект, а не строка csv. console.log 'content' и посмотреть, что вы получаете. – adeneo

+2

это был массив символов –

4

Последние ответ работал для меня в течение нескольких месяцев, а затем прекратил распознавать имя файла, как прокомментировал adeneo ...

@ ответ Скотта здесь работает для меня:

Download file from an ASP.NET Web API method using AngularJS

8

Я использовал решение ниже, и он работал на меня.

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(); 
 
}

+0

не работает. :( – mirage

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(); 
    }); 
    } 
+0

Спасибо большое спасло меня hrs. –

+0

Вот для чего это! :) – malix

1

Не поддерживается IE. По крайней мере, на поддерживаемых HTML5 страницах. :(

1

Вместо использования 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> 
2

Я должен был осуществить это в последнее время мысль о делясь Я выяснил:

Чтобы заставить его работать в Safari, мне нужно было установить цель: «_self». Не беспокойтесь о filenam e в 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(); 
1

В угловых 1.5, используйте $window сервис для загрузки файла.

angular.module('app.csv').factory('csvService', csvService); 

csvService.$inject = ['$window']; 

function csvService($window) { 
    function downloadCSV(urlToCSV) { 
     $window.location = urlToCSV; 
    } 
} 
0

Я думаю, что лучший способ, чтобы загрузить любой файл, созданный с помощью 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")); 
 
    });

Смежные вопросы