如何使用 Angular2 或更高版本下载文件

IT技术 javascript angular typescript download fileapi
2021-02-08 05:13:39

我有一个 WebApi/MVC 应用程序,我正在为其开发 angular2 客户端(以替换 MVC)。我在理解 Angular 如何保存文件时遇到了一些麻烦。

请求成功(正常工作与MVC,我们可以登录接收到的数据),但我无法弄清楚如何保存下载的数据(我主要是遵循同样的逻辑这篇文章)。我相信它非常简单,但到目前为止我根本没有掌握它。

组件函数的代码如下。我尝试过不同的方案,则斑的方法应该是,据我了解的路要走,但没有作用createObjectURLURL我什至找不到URLin window的定义,但显然它存在。如果我使用该FileSaver.jsmodule,则会出现相同的错误。所以我想这是最近发生变化或尚未实施的事情。如何触发文件保存在 A2 中?

downloadfile(type: string){

    let thefile = {};
    this.pservice.downloadfile(this.rundata.name, type)
        .subscribe(data => thefile = new Blob([data], { type: "application/octet-stream" }), //console.log(data),
                    error => console.log("Error downloading the file."),
                    () => console.log('Completed file download.'));

    let url = window.URL.createObjectURL(thefile);
    window.open(url);
}

为了完整起见,获取数据的服务如下,但它唯一做的就是发出请求并在成功时不映射地传递数据:

downloadfile(runname: string, type: string){
   return this.authHttp.get( this.files_api + this.title +"/"+ runname + "/?file="+ type)
            .catch(this.logAndPassOn);
}
6个回答

问题是 observable 在另一个上下文中运行,因此当您尝试创建 URL var 时,您有一个空对象,而不是您想要的 blob。

解决此问题的众多方法之一如下:

this._reportService.getReport().subscribe(data => this.downloadFile(data)),//console.log(data),
                 error => console.log('Error downloading the file.'),
                 () => console.info('OK');

当请求准备好时,它将调用定义如下的函数“downloadFile”:

downloadFile(data: Response) {
  const blob = new Blob([data], { type: 'text/csv' });
  const url= window.URL.createObjectURL(blob);
  window.open(url);
}

blob 已完美创建,因此 URL var,如果未打开新窗口,请检查您是否已导入 'rxjs/Rx' ;

  import 'rxjs/Rx' ;

我希望这可以帮助你。

我遇到的问题是窗口立即打开和关闭,而不是下载文件
2021-03-13 05:13:39
我已经使用上面的代码从 API 响应下载文件,但在创建 Blob 部分时出现一些错误“类型响应不能分配给类型 Blobpart”。如果有人知道这个问题,请帮忙
2021-03-18 05:13:39
@BurjuagetReport()返回一个this.http.get(PriceConf.download.url)
2021-03-27 05:13:39
我们如何在这里设置文件名?默认情况下,它选择一个数值作为名称
2021-03-27 05:13:39
什么是this._reportService.getReport()什么,它返回什么?
2021-04-07 05:13:39

试试这个

1 - 安装依赖项以显示保存/打开文件弹出窗口

npm install file-saver --save
npm install -D @types/file-saver

2-使用此功能创建服务以接收数据

downloadFile(id): Observable<Blob> {
    let options = new RequestOptions({responseType: ResponseContentType.Blob });
    return this.http.get(this._baseUrl + '/' + id, options)
        .map(res => res.blob())
        .catch(this.handleError)
}

3- 在组件中使用“文件保护程序”解析 blob

import {saveAs as importedSaveAs} from "file-saver";

  this.myService.downloadFile(this.id).subscribe(blob => {
            importedSaveAs(blob, this.fileName);
        }
    )

这对我有用!

'RequestOptions' 类型的错误 Av5 参数不可分配给类型 '{ headers?: HttpHeaders | 的参数 { [标题:字符串]:字符串 | string[]; };
2021-03-14 05:13:39
我将步骤 2 与@Alejandro 的答案结合使用,它无需安装文件保护程序即可工作...
2021-03-26 05:13:39
谢谢!它完美地工作!我想知道我们是否可以获得在响应头中定义的文件名。那可能吗?
2021-04-06 05:13:39
@jfajunior 如果您不想从响应中获取文件名,则需要访问响应头:添加observe: 'response'到请求选项并返回Observable<HttpResponse<Blob>>而不是Observable<Blob>- 现在您可以访问响应头并读取文件名,例如res.headers.get('File-Name')
2021-04-06 05:13:39
然而,这个不适合大文件下载。
2021-04-10 05:13:39

如果您不需要在请求中添加标头,要在 Angular2 中下载文件,您可以执行一个简单的操作KISS PRINCIPLE):

window.location.href='http://example.com/myuri/report?param=x';

在您的组件中。

有人可以告诉为什么这个答案被否决了吗?主题是使用angular2下载文件。如果此方法适用于进行简单下载,则还应将其标记为有效答案。
2021-03-24 05:13:39
我确实理解反对票,不过这个答案解决了我的问题。
2021-03-24 05:13:39
@SaurabhShetty,如果您想发送自定义标头,这将无济于事,例如,如果您想发送身份验证令牌怎么办?如果您查看 OP 问题,您可以看到他使用authHttp!
2021-03-26 05:13:39
如果您让服务器在某些上下文中返回 url,则服务器可以准备 url。例如:对象:MyRecord.Cover。封面可以是服务器中图像的 url。调用 get(Myrecord) 时,您让服务器返回准备好的 url (Cover),并设置了安全令牌和其他标头。
2021-03-26 05:13:39
这是一个有效的答案。只是因为它没有 <在此处插入有用的功能> 使其不是答案。
2021-04-01 05:13:39

这是为那些正在寻找如何使用 HttpClient 和文件保护程序的人准备的:

  1. 安装文件保护程序

npm install file-saver --save

npm install @types/file-saver --save

API服务类:

export() {
    return this.http.get(this.download_endpoint, 
        {responseType: 'blob'});
}

零件:

import { saveAs } from 'file-saver';
exportPdf() {
    this.api_service.export().subscribe(data => saveAs(data, `pdf report.pdf`));
}
下载开始时如何在浏览器中显示文件大小?我将文件大小作为 http 标头中的内容长度发送。
2021-03-30 05:13:39

这个怎么样?

this.http.get(targetUrl,{responseType:ResponseContentType.Blob})
        .catch((err)=>{return [do yourself]})
        .subscribe((res:Response)=>{
          var a = document.createElement("a");
          a.href = URL.createObjectURL(res.blob());
          a.download = fileName;
          // start download
          a.click();
        })

我可以做到。
不需要额外的包裹。

使用responseType: "blob"我没有使用res.blob()并且它已经工作了!
2021-03-25 05:13:39
如此简单,但却是完美无瑕的工作。它不会弄乱 DOM,也不会创建任何元素。我将此解决方案与上述一些解决方案相结合,它就像一个魅力。
2021-04-09 05:13:39