简体   繁体   English

使用 JsZip 以编程方式创建 zip 文件

[英]Using JsZip to create zip file programmatically

I wanna insert files pdf inside of the zip on loop and after download the file zip.我想在循环中和下载文件 zip 后在 zip 中插入文件 pdf。

The problem is when I try to download the file thats came empty.问题是当我尝试下载空文件时。 If I printer on console a variable zip, it's have my files..如果我在控制台上打印一个可变的 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"); });

From what I can see in the video you posted in the comments, your code can be summarized as:从我在评论中发布的视频中可以看到,您的代码可以总结为:

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

HTTP requests are asynchronous: requestComments and requestCommentFile will take time to complete and you need to wait for them before calling triggerDownload . HTTP 请求是异步的: requestCommentsrequestCommentFile需要一些时间才能完成,您需要在调用triggerDownload之前等待它们。 Here, the execution order is 1, 3, 2: you prepare the HTTP requests, trigger the download (with an empty zip file) and then HTTP requests end and fill in the zip object.在这里,执行顺序是 1、3、2:您准备 HTTP 请求,触发下载(带有一个空的 zip 文件),然后HTTP 请求结束并填充zip对象。

To fix that, you must wait for the completion of all requests before calling saveAs .要解决这个问题,您必须在调用saveAs之前等待所有请求完成。

JSZip accepts promises as content but here each request can lead to multiple zip entries so you can't use it. JSZip 接受 promise 作为内容,但这里的每个请求都可能导致多个 zip 条目,因此您无法使用它。 Instead, use promises and Promise.all .相反,使用 promises 和Promise.all

Which ajax library do you use ?您使用哪个 ajax 库? If the result is compatible with ES6 Promises, you can convert your code:如果结果与 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);

In this example, commentsP is a list of promises and Promise.all will transform it into a promise of the list of results.在这个例子中, commentsP是一个承诺列表, Promise.all将把它转换成一个结果列表的承诺。 That means once it resolves, all included promises have resolved.这意味着一旦它解决,所有包含的承诺都已解决。

Do that for all ajax requests (don't forget any return , it allow inner promises to be chained).对所有 ajax 请求执行此操作(不要忘记任何return ,它允许链接内部承诺)。 In the end, wait for the top level promise before calling triggerDownload ( baixarZip in your video).最后,在调用triggerDownload (视频中的baixarZip )之前等待顶级承诺。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM