Angular 11 - 使用 JSZip 添加压缩文件
Angular 11 - To add files zip using JSZip
我正在尝试将几个 txt 文件添加到一个 zip 文件并在本地下载。
为此,我使用了库:JSZip 和 FileSaver。
这是下载按钮的“打字稿”代码:
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
this.selectedItems?.forEach((item.name) => {
this.downloadService
.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
});
});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
此代码成功下载了 zip 文件,其中包含一个 readme.txt 文件和一个空的 txt 文件夹。 txt 文件夹应包含从“downloadService”服务获取的 txt 文件。
当然,删除对 returns 文件的服务的调用,并放置一个硬编码的 base 64 文件,如果我们正确生成 zip 及其 txt 文件夹和其中的相应文件,则所有 TXT 文件中的内容相同,因为是硬编码的。
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
this.selectedItems?.forEach((item) => {
txtFile.file(item.name, "VGVzdCBBbGltXzEw", {base64: true});
});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
我更新问题,使用我目前正在测试的代码,这会根据处理的文件生成几个 zip,在最后一个 zip 中将文件添加到 txt 文件夹。但我需要生成一个 zip 文件。 FileSaver.saveAs,在恢复文件的循环内,将为每个文件生成一个 zip,并且在最后一个 zip 中,如果它添加了我需要的所有文件。
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
this.selectedItems?.forEach((item) => {
this.downloadService.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
});
});
selectedItems:是包含文件的对象数组,名称属性包含文件的名称。
我不知道如何调用“downloadFile”服务,以便为每个存在的文件进行相应的调用,以获取 base64 并将其添加到 zip。
根据我们 select 的文件,如果例如我们有 2 个文件,服务的响应将如下所示:
调用一个文件:
{"errorMessages":[],"output": "data:text/plain;base64,VGVzdCBJbmZyYTEw"}
调用一个文件:
{"errorMessages":[],"output": "data:text/plain;base64,VGVzdCBJbmZyYTEy"}
base64[1]变量包含txt文件的base64编码。
简而言之,当我对 base64 代码进行硬编码时,它工作正常并压缩具有相同内容的文件,但是如果我尝试通过调用我的“downloadFile”服务动态获取 base64 代码,它不会添加它们到 txt 文件夹中的 zip,并且没有给出任何错误。
谢谢,
问题是您的下载服务正在 Observable 中异步执行某些操作。您需要移动 .subscribe
块。像这样
this.downloadService
.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
});
});
我无法使用 forkjoin,但我在这种情况下可以按需工作:
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
let i = 0;
this.selectedItems?.forEach((item) => {
this.downloadService.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
i++;
if (i === this.selectedItems.length) { // I have added this condition
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
}
});
});
我正在尝试将几个 txt 文件添加到一个 zip 文件并在本地下载。
为此,我使用了库:JSZip 和 FileSaver。
这是下载按钮的“打字稿”代码:
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
this.selectedItems?.forEach((item.name) => {
this.downloadService
.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
});
});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
此代码成功下载了 zip 文件,其中包含一个 readme.txt 文件和一个空的 txt 文件夹。 txt 文件夹应包含从“downloadService”服务获取的 txt 文件。
当然,删除对 returns 文件的服务的调用,并放置一个硬编码的 base 64 文件,如果我们正确生成 zip 及其 txt 文件夹和其中的相应文件,则所有 TXT 文件中的内容相同,因为是硬编码的。
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
this.selectedItems?.forEach((item) => {
txtFile.file(item.name, "VGVzdCBBbGltXzEw", {base64: true});
});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
我更新问题,使用我目前正在测试的代码,这会根据处理的文件生成几个 zip,在最后一个 zip 中将文件添加到 txt 文件夹。但我需要生成一个 zip 文件。 FileSaver.saveAs,在恢复文件的循环内,将为每个文件生成一个 zip,并且在最后一个 zip 中,如果它添加了我需要的所有文件。
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
this.selectedItems?.forEach((item) => {
this.downloadService.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
});
});
selectedItems:是包含文件的对象数组,名称属性包含文件的名称。
我不知道如何调用“downloadFile”服务,以便为每个存在的文件进行相应的调用,以获取 base64 并将其添加到 zip。
根据我们 select 的文件,如果例如我们有 2 个文件,服务的响应将如下所示:
调用一个文件:
{"errorMessages":[],"output": "data:text/plain;base64,VGVzdCBJbmZyYTEw"}
调用一个文件:
{"errorMessages":[],"output": "data:text/plain;base64,VGVzdCBJbmZyYTEy"}
base64[1]变量包含txt文件的base64编码。
简而言之,当我对 base64 代码进行硬编码时,它工作正常并压缩具有相同内容的文件,但是如果我尝试通过调用我的“downloadFile”服务动态获取 base64 代码,它不会添加它们到 txt 文件夹中的 zip,并且没有给出任何错误。
谢谢,
问题是您的下载服务正在 Observable 中异步执行某些操作。您需要移动 .subscribe
块。像这样
this.downloadService
.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
});
});
我无法使用 forkjoin,但我在这种情况下可以按需工作:
let zip = new JSZip();
zip.file("readme.txt", "Files required");
let txtFile = zip.folder("txt");
let i = 0;
this.selectedItems?.forEach((item) => {
this.downloadService.downloadFile(item.name)
.subscribe((response) => {
let base64 = response.output.split(",");
txtFile.file(item.name, base64[1], {base64: true});
i++;
if (i === this.selectedItems.length) { // I have added this condition
zip.generateAsync({type:"blob"})
.then((content) => {
// see FileSaver.js
FileSaver.saveAs(content, this.fileZipName);
});
}
});
});