有没有一种方法可以保存和API流为.csv,而无需使用FileSaver或createObjectURL()

时间:2019-11-18 16:25:08

标签: angular typescript file download

这些似乎是仅有的两种现有方法。

createObjectURL()的问题在于它已被弃用,我当前的浏览器chrome甚至无法再调用此方法。

FileSaver的问题在于,实际上将整个库添加到项目中实在是太过分了,而实际上只需要花费几行就可以自然地以角度完成它。

我在这里:

const params = {'params' : p};
const httpOptions = this.authenticationService.getRequestOptions();
httpOptions['responseType'] = 'text/csv';

this.http.post(
  this.url + this.currentId,
  params,
  httpOptions
).subscribe((response: any) => {
  console.log(response);
  const blob = new Blob([response], {type: 'text/csv'});

  const link = document.createElement('a');
  link.setAttribute('style', 'display: none');
  link.href = response; // should be a URI but document.URL.createObjectURL() is deprecated
  const date = new Date();
  link.download = 'file.csv';
  link.click();
  link.remove();
}, error => {
  console.log('I failed :(', error);
}); 

这确实会触发文件下载。但是我需要将Blob转换为URI,而我没有那个部分。

编辑:

为清楚起见:

自今天19/11/2019起,自2017年1月1日起,不推荐使用window.URL.createObjectURL,并且将返回错误:https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject

更新:

我发现了:

https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject

https://code-examples.net/en/docs/dom/htmlmediaelement/srcobject

Deprecation of createObjectURL and replace with the new HTMLMediaElement.srcObject doesn't work for Webcam stream

它应该是createObjectURL的替代品,但仅适用于视频元素

1 个答案:

答案 0 :(得分:1)

我通过一些挖掘和反复试验找到了解决方案。我认为这将是一个令人惊喜的惊喜,因为它可以这么容易地下载文件,并且弃用createObjectURL()仍然可行:

this.http.post(
  this.url + this.currentId,
  params,
  httpOptions
).subscribe((response: any) => {
  const link = document.createElement('a');
  link.setAttribute('style', 'display: none');
  link.href = 'data:attachment/csv,' + encodeURI(response); // <- it was as simple as this.
  const date = new Date();
  link.download = this.currentChoice + '-' + date.getDate() + '-' + (1 + date.getMonth()) + '-' + date.getFullYear() + '.csv';
  link.click();
  link.remove();
}, error => {
  console.log('File download failed : ', error);
});

我的api的返回值已经是文件的原始内容,我不需要调用.text()或任何其他子项。

希望这会有所帮助:)