vue 前端需将用户所选的素材(图片)压缩到zip包中形成单个文件提供下载(附加单张图片/素材直接下载)

80 阅读1分钟

第一步

npm i JSZip FileSaver

第二步

import JSZip from 'jszip'
import FileSaver from 'file-saver'

第三步

function downloadZip (files) {
  let zip = new JSZip();
  let folder = zip.folder('files');
  let filename='素材'+new Date()+'.zip'
  Promise.resolve().then(() => {
    return files.reduce((accumulator, item) => {
		let num = item.url.lastIndexOf("/") + 1;
		let fileName = item.url.substring(num).split("?")[0];
		let imgSrc = '/upload/' + fileName;//设计跨域需配置代理或者让后端解决下(我这里/upload 是自己做了代理 
		let name = fileName+'.'+item.suffix//(item.suffix要设置 不然文件打开不了 这里就是设置文件名+后缀 例如aa.jpg)
      return accumulator.then(() => fetch(imgSrc)
                        .then(resp => resp.blob())
                        .then(blob => folder.file(name, blob)))
    }, Promise.resolve())
  }).then(() => {
    folder.generateAsync({type: "blob"}).then(content => FileSaver.saveAs(content, filename));
  })
}

第四步

执行 downloadZip(selectedImgData)//selectedImgData是一个数组 例如

[
  {
    "id": "1537010891991674882",
    "createTime": "2022-06-15 09:55:28",
    "updateTime": null,
    "suffix": "jpeg",
    "size": "18847",
    "url": "https://img1.baidu.com/it/u=3883901410,74560379&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=667",
    "thumbUrl": "https://img1.baidu.com/it/u=3883901410,74560379&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=667",
    "delFlag": false
  },
]

补充:关于前端代理配置

再vue.config.js配置 devServer: {

  proxy: {
	 '/upload': {
	 	//代理图片下载的接口
	 	target: 'https://img1.baidu.com',
	 	changeOrigin: true,
	 	secure: false, // 设置支持https协议的代理
	 	pathRewrite: {
	 	    '^/upload': ''
	     }
	 } 
  }
  

}

再次补充 图片出现跨域 我发现加上时间戳也可以,难道之前是因为浏览器缓存?

export function downloadZip (files) {
  let zip = new JSZip();
  let folder = zip.folder('files');
  let filename='素材'+new Date()+'.zip'
  Promise.resolve().then(() => {
    return files.reduce((accumulator, item) => {
		let num = item.url.lastIndexOf("/") + 1;
		let fileName = item.url.substring(num).split("?")[0];
		let imgSrc = '/upload/' + fileName;
		let name = fileName+'.'+item.suffix
      return accumulator.then(() => fetch(item.url+'?time='+(new Date().valueOf()))/这里加上时间戳就可以
      // return accumulator.then(() => fetch(imgSrc)
                        .then(resp => resp.blob())
                        .then(blob => folder.file(name, blob)))
    }, Promise.resolve())
  }).then(() => {
    folder.generateAsync({type: "blob"}).then(content => FileSaver.saveAs(content, filename));
  })
}

附加:单张图片/素材直接下载 这种方法可以直接下载不会在浏览器重新打开一个网页)

export function downLoadSigleFile (file) {
  let num = file.url.lastIndexOf("/") + 1;
  let fileName = file.url.substring(num).split("?")[0];
  let fileSrc = '/upload/' + fileName;
  let name = fileName+'.'+file.suffix
  Promise.resolve().then(() => {
    return fetch(file.url+'?time='+(new Date().valueOf())).then(resp => resp.blob())
    // return fetch(fileSrc).then(resp => resp.blob())
  }).then((blob) => {
	  const url = URL.createObjectURL(blob);
	  const a = document.createElement("a");
	  a.download = name ;
	  a.href = url;
	  a.click();
	  a.remove();
	  URL.revokeObjectURL(url);
  })
}