携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
需求:因为需要后端生成二维码然后在前端进行导出,支持单个导出和批量导出
补充:因为我请求的是在 oss 上下载图片,然后因为请求协议的问题报以下错误,一般都是因为我们的网站是HTTPS的,而对方的链接是HTTP协议的,因此在Ajax或者javascript请求时,就会报如下这种错误:
1. 单个导出的话我就简单带过了,主要是写一下批量的
// 单个有url的oss链接,直接下载的话
FileSaver.saveAs(list[0].qr_code,`${list[0].title}.jpg`) // 通过fileSaver导出下载图片
FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom })saveAs 方法支持三个参数,第一个参数表示它支持
Blob/File/Url三种类型,第二个参数表示文件名(可选),而第三个参数表示配置对象(可选)。如果你需要 FlieSaver.js 自动提供 Unicode 文本编码提示(参考:字节顺序标记),则需要设置{ autoBom: true}。
2. 批量导出
代码解释的话,主要在代码里面,方便更好的理解
//数据
imgesArr:[
{
url:'http://jingshipeihu.oss-cn-hangzhou.aliyuncs.com/patrol_code/20220630/ff02cca980ecd44887f0970f529847ca.jpg',
name:'first'
},
{
url:'http://jingshipeihu.oss-cn-hangzhou.aliyuncs.com/patrol_code/20220630/610dff0dd546a831dc11376a251580e5f.jpg',
name:'second'
}
]
// 逻辑
// 下载二维码图片并压缩
getImgArrayBuffer(url){
return new Promise((resolve,reject) => {
//通过请求获取文件blob格式
let xmlHTTP = new XMLHttpRequest()
xmlHTTP.open('GET',url,true)
xmlHTTP.responseType = "blob";
xmlHTTP.onload = function() {
if(this.status == 200 ){
// console.log(this.response)
resolve(this.response)
}else{
// console.log(this.status)
reject(this.status)
}
}
xmlHTTP.send()
})
},
// 批量下载
batchDownload(){
let zip = new JSZip() // 进行压缩
var imgObj = {} // 创建一个对象保存遍历的要下载的图片
let promises = [] // 创建一个数组,保存上面的下载图片的对象
for(let obj of this.imgesArr){
const promise = this.getImgArrayBuffer(obj.url).then(data => {
zip.file(obj.name + '.png', data , {binary:true}); // 逐个添加文件
imgObj[obj.name] = data
})
promises.push(promise)
}
this.$message('正在压缩,请稍后!')
// 使用promised.all 方法来实现,有可能会有点问题
Promise.all(promises).then(async () => {
try {
const content = await zip.generateAsync({type:'blob'}) // zip自带的方法,类型为blob,因为在要下载的时候上面转为了blob,兼容性更强
// console.log(content)
await FileSaver.saveAs(content,'压缩图片')
this.$message("压缩完成")
} catch (error) {
console.log(error)
}
// zip.generateAsync({type: 'blob'}).then(content => {
// this.$message('正在压缩,请稍后!')
// console.log(content)
// FileSaver.saveAs(content,'压缩图片') // 利用file-saver保存文件 自定义文件名
// this.$message("压缩完成")
// }).catch(res => {
// console.log(111111)
// console.log(res)
// })
})
}
}
2.1 Promise.all 方法
Promise.all() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set 都属于 ES6 的 iterable 类型)的输入,并且只返回一个
Promise实例, 那个输入的所有 promise 的 resolve 回调的结果是一个数组。
const p = Promise.all([p1, p2, p3]);
p的状态由p1、p2、p3决定,分成两种情况:
- 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
- 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
MDN解释:
完成(Fulfillment):
如果传入的可迭代对象为空,Promise.all会同步地返回一个已完成(resolved)状态的promise。
如果所有传入的promise都变为完成状态,或者传入的可迭代对象内没有promise,Promise.all返回的promise异步地变为完成。
在任何情况下,Promise.all返回的promise的完成状态的结果都是一个数组,它包含所有的传入迭代参数对象的值(也包括非promise值)。
失败/拒绝(Rejection):
如果传入的promise中有一个失败(rejected),Promise.all异步地将失败的那个结果给失败状态的回调函数,而不管其它promise是否完成。
注意 ### Promise.all 的快速返回失败行为
Promise.all在任意一个传入的promise失败时返回失败。例如,如果你传入的promise中,有四个promise在一定的时间之后调用成功函数,有一个立即调用失败函数,那么Promise.all将立即变为失败。如果作为参数的 Promise实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
3. 封装的方法😌 为了复用,
(为了方便以后忘了直接拿来用 哈哈哈才不是勒)
import FileSaver from 'file-saver'
import JSZip from 'jszip'
// 单个二维码导出
export const singleExportQRCode = (url,name ) =>{
// console.log(url)
// console.log(name)
if(!name){
FileSaver.saveAs(url) // 未传入导出图片名称
}else{
FileSaver.saveAs(url,`${name}.jpg`) // 通过fileSaver导出下载图片
}
}
// 下载二维码图片并压缩
function getImgArrayBuffer (url){
return new Promise((resolve,reject) => {
//通过请求获取文件blob格式
let xmlHTTP = new XMLHttpRequest()
xmlHTTP.open('GET',url,true)
xmlHTTP.responseType = "blob";
xmlHTTP.onload = function() {
if(this.status == 200 ){
// console.log(this.response)
resolve(this.response)
}else{
// console.log(this.status)
reject(this.status)
}
}
xmlHTTP.send()
})
}
// 批量二维码导出
export const batchExportQRCode = list => {
let zip = new JSZip()
var imgObj = {}
let promises = []
for(let obj of list){
const promise = getImgArrayBuffer(obj.qr_code).then(data => {
zip.file(obj.title + '.jpg', data , {binary:true}); // 逐个添加文件
imgObj[obj.title] = data
})
promises.push(promise)
}
// console.log(promises)
Promise.all(promises).then(async () => {
try {
const content = await zip.generateAsync({type:'blob'})
await FileSaver.saveAs(content,'压缩图片')
// const newDate = +new Date()
// console.log('new-',newDate)
} catch (error) {
console.log(error)
}
})
}