1

以下是不熟悉的 Pizzip 的文档:https ://github.com/open-xml-templating/pizzip/tree/master/documentation

另外,我正在使用 VueJS (2)、ES6、TS

我正在尝试使用 Axios 下载单个文件,然后使用 Pizzip 将它们放入一个 zip 文件中。

async getFile(mat: Material): Promise<any> {
    try {
      const file = await axios.get(mat.url, { responseType: 'arraybuffer' })
      return file.data
    } catch (error) {
      console.log(error)
      return {}
    }
}

这是给我ArrayBuffer正确的。然后我有以下内容:

async getZip() {
    let zip = new pizzip()
    this.materials.forEach(async mat => {
        const record = await PortalService.getFile(mat)
        console.log(record) // logs the ArrayBuffer
        zip.file(mat.name, record)
    })
    let files = zip.generate({ type: 'blob' })
    return saveAs(files, `${this.request.id}-files.zip`)
}

Pizzip 文档说的data参数zip.file()可以是 type ArrayBuffer,但是当我下载 zip 时它只是一个空存档。我尝试使用可选options参数 for zip.file(),但没有任何效果。先感谢您。

4

1 回答 1

1

问题可能与异步 for 循环有关。该forEach方法不支持异步循环功能;它只会执行每次迭代,而无需等待前一次完成。所以基本上你是在任何文件被添加到它之前生成 zip 文件。

有两种方法可以处理此问题:

  1. 同时触发所有请求并等待它们全部完成。这会更快,因为它同时发送请求,但请注意不要一次发送数百个请求!
await Promise.all(this.materials.map(async mat => {
  const record = await PortalService.getFile(mat)
  zip.file(mat.name, record)
}))
  1. 依次触发每个请求,一次一个。速度较慢,但​​不会发送垃圾邮件请求。
for (const mat of this.materials) {
  const record = await PortalService.getFile(mat)
  zip.file(mat.name, record)
}
于 2020-04-02T23:00:02.247 回答