从Web API中使用AngularJS下载CSV文件

14 浏览
0 Comments

从Web API中使用AngularJS下载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;
}

我使用AngularJS发送和接收CSV文件的代码如下:

$scope.save = function () {
    var csvInput = extractDetails();
    // File是一个Angular资源。我们在这里调用它的save方法,访问上面的API,该API应该返回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中,没有下载任何内容。

我该如何修复这个问题?

更新:

这个链接可能对有相同问题的人有用:[链接](https://stackoverflow.com/questions/20303988/generate-csv-from-mvc-web-api-httpresponse-and-receive-it-by-angularjs-for-downl/20917641#20917641)

0
0 Comments

问题:在AngularJS中如何从Web API下载CSV文件?

原因:在AngularJS中,由于浏览器的兼容性问题,直接从Web API下载CSV文件可能会遇到一些困难。

解决方法:以下是一种解决方法,可以通过创建一个临时链接来下载CSV文件:

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

以上解决方法可以通过判断浏览器是否支持`msSaveOrOpenBlob`方法来选择不同的下载方式。如果浏览器支持该方法,则创建一个Blob对象并通过`navigator.msSaveBlob`保存或打开该Blob对象;否则,创建一个``标签,并设置其href为CSV文件的数据,target为`_blank`,download为文件名,然后将该``标签添加到页面中并点击该链接以触发文件下载。

通过以上解决方法,我们可以在AngularJS中从Web API下载CSV文件。

0
0 Comments

问题:在Chrome 42中,无法通过AngularJS从Web API中下载CSV文件。

原因:在Chrome 42中,使用传统的下载方式无法下载CSV文件,需要使用base64编码的方式来下载文件。

解决方法:通过在AngularJS的指令中使用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();
  });
}

以上代码通过在指令的link函数中定义了一个downloadFile函数来实现文件下载。首先获取要下载的文件名,然后创建一个a标签元素,设置其href属性为base64编码的CSV文件内容,设置target属性为_blank以在新窗口中打开文件,设置download属性为要下载的文件名。接着模拟点击a标签来触发文件下载,并通过setTimeout函数在50毫秒后移除a标签。

最后,在指令的click事件中调用buildCSV函数来获取CSV文件内容,然后调用downloadFile函数来下载文件。

这样,就可以通过AngularJS从Web API中下载CSV文件了。

0
0 Comments

问题的原因是在使用上述代码下载csv文件时,下载的文件扩展名为.csv,但文件内部的内容不是文本,而是[object Object]。这是因为content是一个对象,而不是一个csv字符串。解决方法是将content转换为字符串,可以使用join('')将数组转换为字符串。

另外,还有一些附加的问题和解决方法。有用户提到在Firefox浏览器中无法正确设置文件名,这是因为设置文件名的代码应该是hiddenElement.download = 'myFile.csv',而不是hiddenElement = 'myFile.csv'。还有用户提到在Safari浏览器中无法正常工作,因为Safari不支持download属性,所以文件名也无法使用,它会下载一个名为'Unknown'的文件。

对于想要下载.xlsx文件而不是.csv文件的用户,可以尝试相同的方法创建文件,但是使用JS创建xlsx内容可能更加困难。

最后,还有用户提到使用这段代码下载大文件时遇到问题,但没有提供具体解决方法。

使用这段代码下载csv文件时,需要将content转换为字符串,并注意不同浏览器对文件名和文件类型的支持情况。对于其他问题,可能需要进一步调查和尝试其他解决方法。

0