SpringBoot+Vue+Element-ui 实现文件压缩(批量)下载功能

SpringBoot+Vue+Element-ui 实现文件压缩下载功能

一、vue前端模块代码

前端模块使用vue+element-ui组合,button按钮为element-ui的标签。

****考虑到数据的实时性,本方法是先取到所有选中数据的id,将其转换为字符串传给后端。后端再根据id查出文件路径。

  1. 创建一个el-button按钮用来触发下载操作
<el-button id="downloadBtn"  type="primary" @click="submit(ids)">批量下载</el-button>
  1. 在table中使用@selection-change="handleSelectionChange"来获取被选中的行的数据
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="handleSelectionChange">
      <!-- 下面这行column为table第一列的多选框-->
      <el-table-column :selectable="checkboxT" type="selection" width="55" />
 </el-table>
  1. 在vue的data中和method中定义参数和执行函数:
    **vue发送下载请求时需要定义responseType:‘blob’,(一般还要在请求头中定义’Authorization’: getToken(),getToken()为自定义方法,需要自己去写。)
//引用axios
import axios from 'axios'

data() {
   return {
     // 表格选中的数据,用数组来接收
     selectionModel: [],
     //批量下载id,用来传给后端的字符串
     ids:'',
   }
},
methods: {
    //table事件,点击复选框时触发,可以实时更新数据,携带的参数为所有选中的行的数据
    handleSelectionChange(val) {
      //用数组接收所有选中行数据
      this.selectionModel = val
      const array = this.selectionModel
      //新建一个数组接收id
      const arr = new Array()
      for (let index = 0; index < array.length; index++) {
        arr[index] = array[index].id
      }
      //将id数组转换为字符串
      this.ids = arr.join(',')
    },
    
    //复选框事件,直接复制粘贴就行
    checkboxT(row, rowIndex) {
      return row.id !== 1
    },
    
    //提交函数,点击下载按钮时触发
    submit: function(data) {
      //首先判断有没有选中数据
      if(data == null || data == ''){
        this.$message('请选择要下载的文件')
        return
      }
      //使用post请求,定义一个对象来存放id字符串。(这个地方我试过其他方式来直接传ids,但是都有问题,可能是我用的方法不对,用这种方法虽然麻烦,但是可行)
      let param = {
        ids:data
      }
      //这里是vue的请求
      axios({
          method:"post",
          responseType:'blob',
          url:"这里写请求地址",
          headers: {
          // "Content-Type": "multipart/form-data",
          //'Authorization': getToken()
          },
          withCredentials:true,
          data:param
      }).then((res)=>{
        // res就是接口返回的文件流了
        let blob = new Blob([res.data], {type: "application/zip"});  
        //这里返回的为压缩流,type:类型为"application/zip",
        //也可以是其他文件类型。 application/pdf  ,application/x-ppt,application/vnd.ms-powerpoint,audio/vnd.rn-realaudio 音频 ,'application/vnd.ms-excel'
        let objectUrl = URL.createObjectURL(blob);
        window.location.href = objectUrl;

		//以下为另一种处理文件流的方法(注意返回的res.data)
		//const url = window.URL.createObjectURL(new Blob([res.data]))
        // const link = document.createElement('a')
        // link.style.display = 'none'
        // link.href = url
        // const fileName = "zipfile" + '.' + 'zip'
        // link.setAttribute('download', fileName)
        // document.body.appendChild(link)
        // link.click()
        // document.body.removeChild(link)
      });
    }

  }
}

Java后端模块代码

@RequestMapping("/download")
public void download(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<Object,String> map){
//        String filePath = request.getParameter("fileName").replace("\\", "/");
        String ids = map.get("ids");
        if("".equals(ids) || null == ids){
            return;
        }
        String[] labelArrs = ids.split(",");
        
        /**
        这里需要自定义方法取后端数据,得到文件名和文件地址,
        List<Map<String,String>> list = new ArrayList<>();作为事例
		**/
		List<Map<String,String>> list = new ArrayList<>();

        //响应头的设置
//      response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
//        response.setContentType("application/octet-stream;charset=utf-8");// 设置response内容的类型

        //设置压缩包的名字
        //解决不同浏览器压缩包名字含有中文时乱码的问题
        String downloadName = "压缩包的名字.zip";
        String agent = request.getHeader("USER-AGENT");
        try {
            if (agent.contains("MSIE")||agent.contains("Trident")) {
                downloadName = URLEncoder.encode(downloadName, "UTF-8");
            } else {
                downloadName = new String(downloadName.getBytes("UTF-8"),"ISO-8859-1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");

        //设置压缩流:直接写入response,实现边压缩边下载
        ZipOutputStream zipos = null;
        try {
            zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
            zipos.setMethod(ZipOutputStream.DEFLATED); //设置压缩方法
        } catch (Exception e) {
            e.printStackTrace();
        }

        //循环将文件写入压缩流
        DataOutputStream os = null;
        InputStream is = null;
        for(int i = 0; i < 数组或集合的长度; i++ ){
            
            //获取文件路径,事例map
            String filePath = map.get("fileUrl");
            //获取文件后缀
            String suffix = filePath.substring(filePath.lastIndexOf("."));
            //这里,加上i是防止要下载的文件有重名的导致下载失败,事例map
            String fileName = map.get("fileName") + i + suffix;

            try {
                //添加ZipEntry,并ZipEntry中写入文件流
                zipos.putNextEntry(new ZipEntry(fileName));
                os = new DataOutputStream(zipos);
                if(-1 == filePath.indexOf("https://") && -1 == filePath.indexOf("http://")){
                    //获取本地文件,url不能带有http
                    File file = new File(filePath);
                    is = new FileInputStream(file);
                }else {
                    //is = fileService.download(filePath);此方法为获取ftp中的文件,需要自定义连接ftp服务器的方法,然后获取流文件
                    
                    //获取服务器端的文件,url带有http
					URL url = new URL(filePath);
					URLConnection connection = url.openConnection();
                    is = connection.getInputStream();
                 // BufferedReader br = new BufferedReader(new InputStreamReader(is,"gb2312"));
                }

                //输入流转换为输出流
                IOUtils.copy(is, os);
                zipos.closeEntry();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //关闭流
        try {
            is.close();
            os.flush();
            os.close();
            zipos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
实现头像上传,可以结合Spring Boot后端框架,Vue前端框架以及Element UI组件库进行实现。 首先,在Vue前端页面中,可以使用Element UI中的Upload组件实现文件上传功能。可以在页面中定义一个Upload组件,设置action属性为上传接口的URL,设置headers属性为请求头部信息,设置on-success属性为上传成功后的回调函数。具体代码如下: ``` <template> <div> <el-upload class="avatar-uploader" action="/api/uploadAvatar" :headers="{ Authorization: 'Bearer ' + token }" :show-file-list="false" :on-success="handleSuccess"> <img v-if="imageUrl" :src="imageUrl" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </div> </template> <script> import { getToken } from '@/utils/auth' export default { data() { return { imageUrl: '', token: getToken() } }, methods: { handleSuccess(response) { this.imageUrl = response.data.url } } } </script> ``` 其中,token是用于认证的令牌,可以通过getToken函数获取。handleSuccess函数是上传成功后的回调函数,其中response.data.url表示上传成功后的图片URL。 然后,在Spring Boot后端接口中,可以使用Spring MVC的注解@RequestParam来接收上传的文件。具体代码如下: ``` @RestController @RequestMapping("/api") public class UploadController { @PostMapping("/uploadAvatar") public JsonResult uploadAvatar(@RequestParam("file") MultipartFile file) throws IOException { // 处理上传的文件 return JsonResult.ok("url", "http://www.example.com/avatar.jpg"); } } ``` 其中,@PostMapping注解表示接收POST请求,@RequestParam("file")注解表示接收名为file的文件参数。处理上传的文件后,可以返回一个JsonResult对象,其中包含上传成功后的图片URL。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值