Angular使用HTTP POST下载流文件

Angular使用HTTP POST下载流文件

Angular / Vue HTTP POST下载流文件
HTTP POST 请求流文件转成excel

在使用Angular开发项目时,通常会有下载文件的功能项。一般是后台返回下载地址,通过<a>标题或者使用window打开下载地址新窗口,浏览器则会识别出流文件进行文件下载。

但是,有时候进行http异步请求,后台返回的并不是下载地址,而是直接返回一个文件流,这时如何使用http请求回来的文件流转换成文件下载?

其实并非Angular框架存地这样的情况,其他PWA如Vue,React甚至Jquery都通过http xhr进行请求而获取的流文件,浏览器也并不会自动识别并自动下载。

那当然,肯定有解决方案。
方案思路:

  • http请求使用blob的返回类型,
  • 获取文件流后,对数据进行Blob
  • 再提交给浏览器进行识别下载。

下面是代码示例

/**
 * 导出excel
 */
exportExcel(){
  const params = {}; // body的参数
  const queryParams = undefined; // url query的参数
  this.http.post(this.exportUrl, params, queryParams, {
    responseType: "blob",
    headers: new HttpHeaders().append("Content-Type", "application/json")
  }).subscribe(resp=>{
    // resp: 文件流
    this.downloadFile(resp);
  })
}

/**
 * 创建blob对象,并利用浏览器打开url进行下载
 * @param data 文件流数据
 */
downloadFile(data) {
  // 下载类型 xls
  const contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  // 下载类型:csv
  const contentType2 = 'text/csv';
  const blob = new Blob([data], { type: contentType });
  const url = window.URL.createObjectURL(blob);
  // 打开新窗口方式进行下载
  // window.open(url); 

  // 以动态创建a标签进行下载
  const a = document.createElement('a');
  const fileName = this.datePipe.transform(new Date(), 'yyyyMMdd');
  a.href = url;
  // a.download = fileName;
  a.download = fileName + '.xlsx';
  a.click();
  window.URL.revokeObjectURL(url);
}
Angular中请求文件通常是处理从服务器下载文件(如图片、PDF、视频等)或者上传文件到服务器。这里主要介绍如何在Angular使用HttpClient模块下载文件。 首先,确保你的Angular项目中已经导入了HttpClientModule,在你的app.module.ts文件中添加HttpClientModule: ```typescript import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ HttpClientModule, // 其他模块... ], }) export class AppModule { } ``` 接下来,创建一个服务或组件来处理HTTP请求: 1. 下载文件下载到本地) ```typescript import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class FileService { private baseUrl = 'http://example.com/api'; // 服务器API基础URL constructor(private http: HttpClient) {} downloadFile(fileId: string): Observable<Blob> { const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), responseType: 'blob' as 'json' }; return this.http.get(this.baseUrl + '/download/' + fileId, httpOptions).pipe( map(response => { const contentType = response.headers.get('content-type'); const contentDisposition = response.headers.get('content-disposition'); const blob = new Blob([response], { type: contentType }); return blob; }) ); } } ``` 在组件中调用服务方法: ```typescript import { Component, OnInit } from '@angular/core'; import { FileService } from './file.service'; import { saveAs } from 'file-saver'; @Component({ selector: 'app-download-file', templateUrl: './download-file.component.html', styleUrls: ['./download-file.component.css'] }) export class DownloadFileComponent implements OnInit { constructor(private fileService: FileService) { } ngOnInit() { this.downloadAndSaveFile('12345'); } downloadAndSaveFile(fileId: string): void { this.fileService.downloadFile(fileId).subscribe(blob => { saveAs(blob, 'downloaded-file.pdf'); // 使用file-saver库保存文件 }); } } ``` 2. 上传文件(发送到服务器) ```typescript import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class FileService { private baseUrl = 'http://example.com/api'; // 服务器API基础URL constructor(private http: HttpClient) {} uploadFile(file: File): Observable<any> { const formData: FormData = new FormData(); formData.append('file', file); const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'multipart/form-data' }) }; return this.http.post(this.baseUrl + '/upload', formData, httpOptions); } } ``` 在组件中调用服务方法: ```typescript import { Component } from '@angular/core'; import { FileService } from './file.service'; @Component({ selector: 'app-upload-file', templateUrl: './upload-file.component.html', styleUrls: ['./upload-file.component.css'] }) export class UploadFileComponent { constructor(private fileService: FileService) { } upload() { const fileInput = document.getElementById('file-input') as HTMLInputElement; const file = fileInput.files[0]; if (file) { this.fileService.uploadFile(file).subscribe(response => { console.log('File uploaded successfully', response); }, error => { console.error('File upload failed', error); }); } else { console.log('Please select a file to upload.'); } } } ``` 确保在你的HTML文件中提供一个文件输入控件: ```html <input type="file" id="file-input"> <button (click)="upload()">Upload File</button> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值