Использование JsZip для создания zip-файла программно

Я хочу вставить файлы PDF внутри цикла Zip On и после загрузки файла 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 ответ

Решение

Из того, что я вижу в видео, которое вы разместили в комментариях, ваш код может быть обобщен как:

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, вы можете преобразовать свой код:

// 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 в вашем видео).

Другие вопросы по тегам