前言
有些时候,项目上需要前端在浏览器下载压缩包,压缩包里可能是多个视频、图片、excel,也可能是带嵌套层级的文件夹。此时,用JSZip 可轻松解决这些需求,具体api文档 大家可自行查阅,文档还是比较全面的。我下面主要介绍两种实际应用场景,这两种场景的思路都是一致的。
思路
- 利用
JSZip
对象的file
、folder
方法往对象里插入文件、文件夹 - 使用
generateAsync
方法拿到文件流,通常是blob
格式 - 创建
a
标签,下载
场景一
下载目录文件夹
点击【下载目录】,需要把【2】处的树结构以文件夹的形式下载成压缩包
代码
import JSZip from 'jszip'
const treeData = [
{
packageName: '10月',
childList: [
{
packageName: '10月1日'
},
{
packageName: '10月2日'
}
]
},
{
packageName: '11月',
childList: [
{
packageName: '11月11日'
}
]
}
]
// 比较通用的下载方法
function downloadBlob(blob, name = '') {
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob) // 创建下载的链接
downloadElement.href = `${href}`
downloadElement.style.display = 'none'
if (name) {
downloadElement.download = `${name}` // 下载后文件名
}
document.body.appendChild(downloadElement)
downloadElement.click() // 点击下载
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
}
// 生成压缩包的主要方法
const handleDownload = treeData => {
const name = '文件夹压缩包'
const zip = new JSZip()
const first = zip.folder(name)
// 插入空文件夹
treeData.forEach(({ packageName, childList }) => {
let sec = first.folder(packageName)
childList.forEach(({ packageName }) => {
sec.folder(packageName)
})
})
zip.generateAsync({ type: 'blob' }).then(function (content) {
const filename = `${name}.zip`
downloadBlob(content, filename)
})
}
handleDownload(treeData)
场景二
已有多个http的视频链接,批量下载视频压缩包
此场景下需要多增加一步操作,即通过视频链接(http远程链接)拿到blob文件
代码
以下方法为根据视频链接(http远程链接)拿到blob文件,请求用的是xhr,也可用fetch
function getVideoBlob(url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.responseType = 'blob' // 设置返回类型blob
xhr.onload = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
let blob = this.response
blob = new Blob([blob], {
type: 'video/mp4'
})
resolve(blob)
}
}
xhr.send()
})
}
以下为主方法
import JSZip from 'jszip'
async function downLoadVideoZip(url) {
let blob = await getVideoBlob(url)
const name = '视频包'
var zip = new JSZip()
var first = zip.folder(name)
first.file('file.mp4', blob)
zip.generateAsync({ type: 'blob' }).then(function (content) {
var filename = `${name}.zip`
downloadBlob(content, filename)
})
}