Скачать текстовый контент/CSV как файлы с сервера в угловой


Я пытаюсь передать a csv файл с узла.сервер JS. Серверная часть очень проста:

server.get('/orders' function(req, res) {
  res.setHeader('content-type', 'text/csv');
  res.setHeader('content-disposition', 'attachment; filename='orders.csv');
  return orders.pipe(res); // assuming orders is a csv file readable stream (doesn't have to be a stream, can be a normal response)
}

в моем угловом контроллере я пытаюсь сделать что-то вроде этого

$scope.csv = function() {
    $http({method: 'GET', url: '/orders'});
};

эта функция вызывается при нажатии на кнопку с ng-click на мой взгляд :

<button ng-click="csv()">.csv</button>

Я посмотрел на другие ответы о загрузке файлов с сервера в Angular, но не нашел ничего, что работало для меня. Есть ли общий способ сделать это ? Кажется, что-то, что должно быть простым.

5 52

5 ответов:

$http сервис возвращает a promise, который имеет два метода обратного вызова, как показано ниже.

$http({method: 'GET', url: '/someUrl'}).
  success(function(data, status, headers, config) {
     var anchor = angular.element('<a/>');
     anchor.attr({
         href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data),
         target: '_blank',
         download: 'filename.csv'
     })[0].click();

  }).
  error(function(data, status, headers, config) {
    // handle error
  });

большинство ссылки в интернете об этой проблеме указывают на то, что вы не можете загружать файлы с помощью ajax вызова "из коробки". Я видел (хакерские) решения, которые включают iframes а также такие решения, как @dcodesmith, которые работают и совершенно жизнеспособны.

вот еще одно решение, которое я нашел, которое работает в угловом и очень прямолинейно.

на view, оберните скачать с <a> тег следующим образом :

<a target="_self" ng-href="{{csv_link}}">
  <button>download csv</button>
</a>

(уведомление target="_self там, важно отключить маршрутизацию Angular внутри ng-приложения подробнее об этом здесь)

внутри вы контроллер вы можете определить csv_link следующим образом :

$scope.csv_link = '/orders' + $window.location.search;

(the $window.location.search является необязательным и onlt, если вы хотите передать дополнительный поисковый запрос на ваш сервер)

теперь каждый раз, когда вы нажимаете кнопку, он должен начать загрузку.

var anchor = angular.element('<a/>');
anchor.css({display: 'none'}); // Make sure it's not visible
angular.element(document.body).append(anchor); // Attach to document

anchor.attr({
    href: 'data:attachment/csv;charset=utf-8,' + encodeURI(data),
    target: '_blank',
    download: 'filename.csv'
})[0].click();

anchor.remove(); // Clean it up afterwards

этот код работает как Mozilla, так и chrome

Это то, что работало для меня для IE 11+, Firefox и Chrome. В safari он загружает файл, но как неизвестный и имя файла не установлено.

if (window.navigator.msSaveOrOpenBlob) {
    var blob = new Blob([csvDataString]);  //csv data string as an array.
    // IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
    window.navigator.msSaveBlob(blob, fileName);
} else {
    var anchor = angular.element('<a/>');
    anchor.css({display: 'none'}); // Make sure it's not visible
    angular.element(document.body).append(anchor); // Attach to document for FireFox

    anchor.attr({
        href: 'data:attachment/csv;charset=utf-8,' + encodeURI(csvDataString),
        target: '_blank',
        download: fileName
})[0].click();
anchor.remove();
}

С помощью угловой 1.5.9

Я сделал это работает так, установив окно.расположение к url-адресу загрузки файла csv. Протестировано и его работа с последней версией Chrome и IE11.

Угловое

   $scope.downloadStats = function downloadStats{
        var csvFileRoute = '/stats/download';
        $window.location = url;
    }

html

<a target="_self" ng-click="downloadStats()"><i class="fa fa-download"></i> CSV</a>

на php установите следующие заголовки для ответа:

$headers = [
    'content-type'              => 'text/csv',
    'Content-Disposition'       => 'attachment; filename="export.csv"',
    'Cache-control'             => 'private, must-revalidate, post-check=0, pre-check=0',
    'Content-transfer-encoding' => 'binary',
    'Expires' => '0',
    'Pragma' => 'public',
];