我有点晚了,但这段代码将使用您的图像数组并创建GET请求。之后,它将执行所有请求,并将响应添加到zip文件中,然后下载。
如果您不喜欢使用filesaver,我提供了两种下载文件的方法。选择你喜欢的。
编辑:
如果您使用的是旧版本的RXJS,则必须导入
forkJoin
以不同的方式,请参考RXJS文档。
还要确保后端允许下载文件,否则会出现CORS错误。
forkJoin Documentation
应用组件.ts
import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from 'jszip';
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = [
'http://yoururl/file.png',
'http://yoururl/file2.png'
];
getRequests = [];
constructor(private _http: HttpClient) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests)
.subscribe((res) => {
const zip = new JSZip();
res.forEach((f, i) => {
zip.file(`image${i}.png`, f);
});
/* With file saver */
// zip
// .generateAsync({ type: 'blob' })
// .then(blob => saveAs(blob, 'image.zip'));
/* Without file saver */
zip
.generateAsync({ type: 'blob' })
.then(blob => {
const a: any = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
const url = window.URL.createObjectURL(blob);
a.href = url;
a.download = 'image.zip';
a.click();
window.URL.revokeObjectURL(url);
});
});
}
private createGetRequets(data: string[]) {
data.forEach(url => this.getRequests.push(this._http.get(url, { responseType: 'blob' })));
}
}
app.component.html(应用程序组件.html)
<div style="text-align:center">
<button (click)="download()">Download</button>
</div>
我还必须在tsconfig.json中包含jszip的路径。根据角度的不同,你不需要这样做。里面
"compilerOptions"
添加以下内容:
TSOCONT.JSON
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
]
}
更新:
这里有一个旧的httpmodule的解决方案,我试过了,它工作了。如果可能的话,我建议更换新的httpclientmodule。
更新2:
正如我在评论中所说,在保存文件以处理不同的文件类型时,可以更改文件扩展名。这是一个例子,您可以轻松地扩展这个解决方案。
应用组件.ts
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http"; // Different Import
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
/*
UPDATE 2
Create a Type map to handle differnet file types
*/
readonly MIME_TYPE_MAP = {
"image/png": "png",
"image/jpeg": "jpg",
"image/jpg": "jpg",
"image/gif": "gif"
};
data = [
"http://url/file.png",
"http://url/file.jpeg",
"http://url/file.gif"
];
getRequests = [];
constructor(private _http: Http) {} // Different Constructor
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
console.log(res);
/*
The return value is different when using the HttpModule.
Now you need do access the body of the response with ._body,
as you can see inside the forEach loop => f._body
*/
let fileExt: String; // UPDATE 2
res.forEach((f, i) => {
fileExt = this.MIME_TYPE_MAP[f._body.type]; // UPDATE 2, retrieve type from the response.
zip.file(`image${i}.${fileExt}`, f._body); // UPDATE 2, append the file extension when saving
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string[]) {
/*
Change your responseType to ResponseContentType.Blob
*/
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}
更新3:
从URL提取文件名的解决方案,这样就不需要文件类型:
import { Component } from "@angular/core";
import { Http, ResponseContentType } from "@angular/http";
import { forkJoin } from "rxjs";
import { saveAs } from "file-saver";
import * as JSZip from "jszip";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
data = ["http://url/file.png", "http://url/file.jpg", "http://url/file.gif"];
getRequests = [];
constructor(private _http: Http) {}
download() {
this.createGetRequets(this.data);
forkJoin(...this.getRequests).subscribe(res => {
const zip = new JSZip();
let fileName: String;
res.forEach((f, i) => {
fileName = f.url.substring(f.url.lastIndexOf("/") + 1); // extract filename from the response
zip.file(`${fileName}`, f._body); // use it as name, this way we don't need the file type anymore
});
zip
.generateAsync({ type: "blob" })
.then(blob => saveAs(blob, "image.zip"));
});
}
private createGetRequets(data: string[]) {
data.forEach(url =>
this.getRequests.push(
this._http.get(url, { responseType: ResponseContentType.Blob })
)
);
}
}