使用 JsZip 以编程方式创建 zip 文件
Using JsZip to create zip file programmatically
我想在 zip on 循环中插入文件 pdf,并在下载文件 zip 之后。
问题是当我尝试下载空文件时。
如果我在控制台上打印可变 zip,它有我的文件..
var zip = new JSZip();
var nomeCliente = "";
this.state.docs.forEach(function(itemDoc, index) {
var file = new File([this.dataURItoBlob(response.data)], itemComment.comment_file_name, {type: response.mime+"charset=utf-8"});
zip.folder(itemDoc.person_firstname).folder(itemDoc.category_description).file(itemComment.comment_file_name, file);
}
zip.generateAsync({type:"blob"})
.then(function(content) {
FileSaver.saveAs(content, nomeCliente+".zip");
});
从您在评论中发布的视频中我可以看到,您的代码可以概括为:
var zip = new JSZip();
docs.forEach(function () { // 1
requestComments().end(function () {
requestCommentFile().end(function () {
zip.folder(...).folder(...).file(...); // 2
})
});
triggerDownload(zip); // 3
});
HTTP 请求是异步的:requestComments
和 requestCommentFile
需要时间才能完成,您需要在调用 triggerDownload
之前等待它们。此处,执行顺序为 1、3、2:准备 HTTP 请求,触发下载(使用空 zip 文件),然后 然后 HTTP 请求结束并填写 zip
对象。
要解决此问题,您必须等待所有请求完成后再调用 saveAs
。
JSZip 接受承诺作为内容,但这里每个请求都可能导致多个 zip 条目,因此您不能使用它。相反,使用承诺和 Promise.all
.
您使用哪个 ajax 库?如果结果兼容 ES6 Promises,你可以转换你的代码:
// from
comments.forEach(function () {
request.post(...)
.send(...)
.end(function() {
zip.file(...);
});
});
// to
var commentsP = comments.map(function () { // forEach to map
return request.post(...) // return here
.send(...)
.then(function() { // each time you see a then
return zip.file(...); // ends with a return
});
});
return Promise.all(commentsP);
在此示例中,commentsP
是一个承诺列表,Promise.all
会将其转换为结果列表的承诺。这意味着一旦它解决,所有包含的承诺都已解决。
对所有 ajax 请求执行此操作(不要忘记任何 return
,它允许链接内部承诺)。最后,在调用 triggerDownload
(视频中的 baixarZip
)之前等待顶级承诺。
我想在 zip on 循环中插入文件 pdf,并在下载文件 zip 之后。
问题是当我尝试下载空文件时。 如果我在控制台上打印可变 zip,它有我的文件..
var zip = new JSZip();
var nomeCliente = "";
this.state.docs.forEach(function(itemDoc, index) {
var file = new File([this.dataURItoBlob(response.data)], itemComment.comment_file_name, {type: response.mime+"charset=utf-8"});
zip.folder(itemDoc.person_firstname).folder(itemDoc.category_description).file(itemComment.comment_file_name, file);
}
zip.generateAsync({type:"blob"})
.then(function(content) {
FileSaver.saveAs(content, nomeCliente+".zip");
});
从您在评论中发布的视频中我可以看到,您的代码可以概括为:
var zip = new JSZip();
docs.forEach(function () { // 1
requestComments().end(function () {
requestCommentFile().end(function () {
zip.folder(...).folder(...).file(...); // 2
})
});
triggerDownload(zip); // 3
});
HTTP 请求是异步的:requestComments
和 requestCommentFile
需要时间才能完成,您需要在调用 triggerDownload
之前等待它们。此处,执行顺序为 1、3、2:准备 HTTP 请求,触发下载(使用空 zip 文件),然后 然后 HTTP 请求结束并填写 zip
对象。
要解决此问题,您必须等待所有请求完成后再调用 saveAs
。
JSZip 接受承诺作为内容,但这里每个请求都可能导致多个 zip 条目,因此您不能使用它。相反,使用承诺和 Promise.all
.
您使用哪个 ajax 库?如果结果兼容 ES6 Promises,你可以转换你的代码:
// from
comments.forEach(function () {
request.post(...)
.send(...)
.end(function() {
zip.file(...);
});
});
// to
var commentsP = comments.map(function () { // forEach to map
return request.post(...) // return here
.send(...)
.then(function() { // each time you see a then
return zip.file(...); // ends with a return
});
});
return Promise.all(commentsP);
在此示例中,commentsP
是一个承诺列表,Promise.all
会将其转换为结果列表的承诺。这意味着一旦它解决,所有包含的承诺都已解决。
对所有 ajax 请求执行此操作(不要忘记任何 return
,它允许链接内部承诺)。最后,在调用 triggerDownload
(视频中的 baixarZip
)之前等待顶级承诺。