【vue】vue项目中批量下载文件并打压缩包

前言

一开始用的是循环单个文件下载,即从后台获取到文件url列表,循环对每个url单独进行下载,这样的问题是每调用一次下载,浏览器都会进行"另存为"的弹框,很麻烦!!!

关闭"下载前询问每个文件的保存位置",又不是我想要的,这样就不提示保存位置,直接下载到浏览器的默认位置。而且按网上的方法,在程序代码里不让它弹"另存为"的弹框,也不起作用(具体方法放到了参考文章中)。

所以就产生了批量下载并打压缩包的想法。

解决方法

1、下载插件

javascript 复制代码
npm install jszip
npm install file-saver

注: install完成后,会自动在package-lock.json和package.json中,添加上所需依赖。

2、在vue文件中使用

javascript 复制代码
import JSZip from 'jszip'
import FileSaver from 'file-saver'

3、下载文件以及打包方法

javascript 复制代码
    /**文件打包* arrImages:文件list:[{fileUrl:文件url,renameFileName:文件名}]* filename 压缩包名* */
    filesToRar(arrImages, filename) {
      let _this = this;
      let zip = new JSZip();
      let cache = {};
      let promises = [];
      _this.title = '正在加载压缩文件';
      const loading = this.$loading({lock: true,text: '正在加载压缩文件',spinner: 'el-icon-loading',background: 'rgba(0, 0, 0, 0.7)'});
      console.log("aaaa",arrImages);
      for (let item of arrImages) {
        console.log("item",item)
        // 下载文件, 并存成ArrayBuffer对象
        const promise = this.getImgArrayBuffer(item.fileStaticUrl).then(data => { 
          // 获取文件名
          const file_name = encodeURIComponent(item.fileId) 
          // 逐个添加文件
          zip.file(file_name, data, { binary: true })           
          cache[file_name] = data})
          promises.push(promise);
        }
        Promise.all(promises)
        // 生成二进制流
        .then(() => {zip.generateAsync({ type: "blob" })
          .then(content => {_this.title = '正在压缩';
            // 利用file-saver保存文件  自定义文件名
            FileSaver.saveAs(content, filename);             
            _this.title = '压缩完成';}
          );
          loading.close();
        }).catch(res=>{
          _this.$message.error('文件压缩失败');
          loading.close();
        });
    },
javascript 复制代码
   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) {
            resolve(this.response);
          } else {
            reject(this.status);
          }};
          xmlhttp.send();
      });
    },

4.获取文件url列表

javascript 复制代码
    getFileUrls() {     
      this.$http({
        url: this.$http.adornUrl("/fileSystemApi/fileInfo/batch/download"),
        method: "post",
        data: {
          fileInfoList: this.dataListSelections,
          updateBy: this.$cookie.get('username')
        },
      }).then(({ data }) => {
        console.log("getFileUrls",data)
        this.fileInfoList = data.data.fileInfoList;
        console.log("sd",this.fileInfoList) 
        this.filesToRar(this.fileInfoList, this.getTimestamp());
      });
    },

获取的fileInfoList即第3步中的arrImages,时间戳当做压缩包的文件名

5.在data中定义变量

javascript 复制代码
data() {
    return {
      dataForm: {
        id: "",
        bucketId: "",
        fileId: "",
        fileType: "",
        syscode: "",
        fileCustno: "",
        createTime: "",
      },
      dataList: [],
      dataListSelections: [], // 选中数据
      dataIdListSelections: [], // 选中id
      dataListLoading: false,
      currPage: 1,
      pageSize: 10,
      totalCount: 0,
      url: "",
      fileInfoList: "",
      dialogVisible: false,
    };
  },

6.点击按钮

html 复制代码
<template>
  <div>
    <!-- 省略其他... -->
    <el-form
      :inline="true"
      :model="dataForm"
      @keyup.enter.native="getDataList()"
    >
      <el-form-item>
        <el-button type="primary" @click="getFileUrls()">批量下载</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

参考文章

https://blog.csdn.net/qq_47498423/article/details/131191964

http://www.taodudu.cc/news/show-5240586.html?action=onClick

https://code84.com/821872.html

http://www.taodudu.cc/news/show-4791614.html?action=onClick

循环单个文件下载的方式

https://blog.csdn.net/qq_41131745/article/details/128861548

https://blog.csdn.net/qq_42840904/article/details/131582093

https://ask.csdn.net/questions/7733361

https://blog.csdn.net/weixin_52268321/article/details/130465839

https://www.5axxw.com/questions/simple/qq469i

https://blog.csdn.net/weixin_43227235/article/details/130227361

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang2 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄5 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、5 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser7 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la7 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui7 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui