使用JsZip创建zip文件programaticaly

时间:2016-12-30 22:25:41

标签: javascript jszip

我想在zip循环中插入文件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");
});

1 个答案:

答案 0 :(得分:0)

从我在评论中发布的视频中看到的内容,您的代码可归纳为:

var zip = new JSZip();
docs.forEach(function () {                    // 1
  requestComments().end(function () {
    requestCommentFile().end(function () {
      zip.folder(...).folder(...).file(...);  // 2
    })
  });
  triggerDownload(zip);                       // 3
});

HTTP请求是异步的:requestCommentsrequestCommentFile需要一段时间才能完成,您需要在调用triggerDownload之前等待它们。这里,执行顺序为1,3,2:您准备HTTP请求,触发下载(使用空的zip文件),然后 HTTP请求结束并填写zip对象

要解决此问题,您必须在调用saveAs之前等待所有请求的完成。

JSZip接受promises作为内容,但是这里每个请求都会导致多个zip条目,因此您无法使用它。相反,请使用promises和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,它允许内部promises链接)。最后,在调用视频中的triggerDownloadbaixarZip)之前,请等待顶级承诺。