itsource

angular js의 web api에서 csv 파일 다운로드

mycopycode 2023. 2. 26. 09:44
반응형

angular js의 web api에서 csv 파일 다운로드

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 파일을 송수신하는 my angularjs는 다음과 같습니다.

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

크롬에서는, 라고 불리는 파일을 다운로드합니다.document파일 형식 확장자가 없습니다.파일의 내용은[Object object].

IE10에서는 아무것도 다운로드되지 않습니다.

이걸 고치려면 어떻게 해야 하죠?

업데이트: 이 방법은 같은 문제를 안고 있는 고객님께 도움이 될 수 있습니다.link

다음과 같이 시험해 보십시오.

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

이 질문의 가장 훌륭한 답변에 근거하여

아래 솔루션을 사용했는데 효과가 있었습니다.

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

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

마지막 답변은 몇 달 동안 효과가 있었지만, 아데노 코멘트처럼 파일 이름을 인식하지 못했습니다.

@Scott의 답변은 다음과 같습니다.

ASP에서 파일을 다운로드합니다.Angular를 사용하는 NET Web API 메서드JS

저는 최근에 이것을 구현해야 했습니다.내가 알아낸 걸 공유하려고 했어

Safari에서 작동시키기 위해 타겟을 설정해야 했습니다. '_self'...Safari에서는 파일명에 대해 걱정할 필요가 없습니다.여기에 기재된 바와 같이 지원되지 않는 것 같습니다.https://github.com/konklone/json/issues/56 (http://caniuse.com/ #search=http://http://caniuse.com/

아래 코드는 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();

Ajax / XMLHttpRequest / $http를 사용하여 WebApi 메서드를 호출하는 대신 html 형식을 사용합니다.이렇게 하면 브라우저는 응답 헤더에 파일 이름과 콘텐츠 유형 정보를 사용하여 파일을 저장할 수 있으며, 파일 처리에 대한 javascript의 제한을 회피할 필요가 없습니다.이 메서드는 데이터를 반환하므로 POST가 아닌 GET 메서드를 사용할 수도 있습니다.다음은 예를 제시하겠습니다.

<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>

Angular 1.5에서는$window파일을 다운로드하는 서비스입니다.

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

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

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

a.download는 IE에서 지원되지 않습니다.적어도 HTML5의 "지원 대상" 페이지.:(

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

실행 가능한 솔루션:

downloadCSV(data){   
 const newBlob = new Blob([decodeURIComponent(encodeURI(data))], { type: 'text/csv;charset=utf-8;' });

        // IE doesn't allow using a blob object directly as link href
        // instead it is necessary to use msSaveOrOpenBlob
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
          window.navigator.msSaveOrOpenBlob(newBlob);
          return;
        }

        // For other browsers:
        // Create a link pointing to the ObjectURL containing the blob.
        const fileData = window.URL.createObjectURL(newBlob);

        const link = document.createElement('a');
        link.href = fileData;
        link.download = `Usecase-Unprocessed.csv`;
        // this is necessary as link.click() does not work on the latest firefox
        link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));

        setTimeout(function () {
          // For Firefox it is necessary to delay revoking the ObjectURL
          window.URL.revokeObjectURL(fileData);
          link.remove();
        }, 5000);
  }

언급URL : https://stackoverflow.com/questions/20300547/download-csv-file-from-web-api-in-angular-js

반응형