共计 1490 个字符,预计需要花费 4 分钟才能阅读完成。
需求
管理后台需要批量导出二维码图片
实现难点
选择相应的图片批量导出或直接批量导出并压缩在一个文件夹里
思路分析
1. 先将选中二维码的地址存在一个数组中 2. 依次请求图片并将其下载 3. 后用 jszip 压缩文件 4. 最后用 file-saver 生成文件
实现
实现的代码如下
import axios from ‘axios’
import JSZip from ‘jszip’
import FileSaver from ‘file-saver’
getFile = (url) => {
return new Promise((resolve, reject) => {
axios({
method: ‘get’,
url,
responseType: ‘arraybuffer’
}).then(data => {
resolve(data.data)
}).catch(error => {
reject(error.toString())
})
})
};
}
// 批量下载
handleBatchDownload = async(selectImgList) => {
const data = selectImgList;
const zip = new JSZip()
const cache = {}
const promises = []
await data.forEach(item => {
const promise = this.getFile(item).then(data => { // 下载文件, 并存成 ArrayBuffer 对象
const arr_name = item.split(“/”);
let file_name = arr_name[arr_name.length – 1] // 获取文件名
// if (file_name.indexOf(‘.png’) == -1) {
// file_name = file_name + ‘.png’
// }
zip.file(file_name, data, {
binary: true
}) // 逐个添加文件
cache[file_name] = data
})
promises.push(promise)
})
Promise.all(promises).then(() => {
zip.generateAsync({
type: “blob”
}).then(content => { // 生成二进制流
FileSaver.saveAs(content, “photo.zip”) // 利用 file-saver 保存文件
})
})
};
知识点总结
1. 插件 file-saver 的使用
a 标签 download 属性下载不了跨域图片直接在浏览器预览,利用 file-saver 将跨域访问的图片下载
可以 file-saver 下载其他文件,详情可去参考其 API
如果你需要保存较大的文件,不受 blob 的大小限制或内存限制,可以看一下更高级的 StreamSaver.js
2. 插件 jszip 的使用
点击批量下载所有图片都在浏览器下载文件多表现不友好,需将批量下载的图片打包进压缩包里,故引进了 JSZip 进行打包
JSZip 是一个用于创建,阅读和编辑.zip 文件的 JavaScript 库,具有友好而简单的 API, 详细用法可以参照其 API
备注:
注意的是 responseType, 如果下载文件是文本类型的 (如: .txt, .js 之类的), 那么用 responseType: ‘text’ 也可以, 但是如果下载的文件是图片, 视频之类的, 就得用 arraybuffer
如果下载的文件过大, 打包的时间将会很长, 甚至可能会导致浏览器奔溃
还需要注意的一点是请求图片资源时因其是异步请求,需要等所有图片请求完再进行打包这一步,在请求资源时需要 await
参考文档
file-saver 地址 JSZip 参考文档地址