télécharger le fichier csv de l'api web en angle js

mon contrôleur API retourne un fichier csv comme vu ci-dessous:

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

et mon angularjs qui enverra et recevra le fichier csv est montré ci-dessous:

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

dans chrome, il télécharge un fichier qui s'appelle document mais n'a pas d'extension de type de fichier. Le contenu du fichier est [Object object] .

Dans IE10, rien n'est téléchargé.

que pouvais-je faire pour arranger ça?

mise à jour: Cela pourrait fonctionner pour vous les gars là-bas avec le même problème: lien

46
demandé sur Community 2013-11-30 16:58:57

9 réponses

Essayer comme :

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

basé sur la réponse la plus excellente dans cette question

60
répondu adeneo 2017-05-23 12:34:08

j'ai utilisé la solution ci-dessous et cela a fonctionné pour moi.

 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();
 }
8
répondu Manu Sharma 2014-12-30 02:54:42

aucun de ceux qui ont travaillé pour moi dans Chrome 42...

à la place, ma directive utilise maintenant cette fonction link ( 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();
    });
  }
4
répondu malix 2015-04-08 04:29:43

la dernière réponse a fonctionné pour moi pendant quelques mois, puis a cessé de reconnaître le nom de fichier, comme adeneo a commenté ...

la réponse de @Scott fonctionne pour moi:

télécharger le fichier d'un ASP.NET méthode de L'API Web utilisant AngularJS

4
répondu prsnca 2017-05-23 12:17:51

j'ai dû mettre en oeuvre ceci récemment.

pour le faire fonctionner en Safari, j'ai dû fixer l'objectif: '_self',. Ne vous inquiétez pas pour le nom de fichier dans Safari. On dirait qu'il n'est pas supporté comme mentionné ici; https://github.com/konklone/json/issues/56 ( http://caniuse.com/#search=download )

le code ci-dessous fonctionne très bien pour moi dans 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();
2
répondu Ricky Boy 2016-09-13 00:58:19

The A. le téléchargement n'est pas supporté par IE. Au moins sur les pages "supportées" par HTML5. : (

1
répondu Nick Jacobs 2015-06-30 17:58:20

plutôt que D'utiliser Ajax / XMLHttpRequest / $http pour invoquer votre méthode WebApi, utilisez un formulaire html. De cette façon, le navigateur enregistre le fichier en utilisant le nom du fichier et les informations de type de contenu dans les en-têtes de réponse, et vous n'avez pas besoin de travailler autour des limites de javascript sur le traitement de fichier. Vous pouvez également utiliser une méthode GET plutôt qu'un POST car la méthode retourne des données. Voici un exemple de formulaire:

<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>
1
répondu Paul Taylor 2015-11-18 11:44:19

dans L'angle 1.5, utilisez le service $window pour télécharger un fichier.

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

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

function csvService($window) {
    function downloadCSV(urlToCSV) {
        $window.location = urlToCSV;
    }
}
1
répondu user2601995 2017-02-28 18:54:06

je pense que la meilleure façon de télécharger un fichier généré par REST call est d'utiliser window.emplacement exemple:

    $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"));
    });
0
répondu Fadi Nouh 2017-07-12 08:12:42