easyExcel导出功能+图片压缩打包成ZIP,实现浏览器自动下载

依赖自己导,先说一下最后实现的效果:前端用户批量选中数据点击导出,后端拿到数据创建并写入到excel表中,并且把图片压缩成ZIP包,成功后浏览器自动下载。

后端代码:
(1) excel代码

    @PostMapping("/exportExcel")
    public void exportExcel(@RequestBody Map<String,Object> params ,HttpServletResponse response){
        try {
            //获取需要导出的数据id
            List<Integer> xlhs = (List<Integer>) params.get("xlhs");
            List<Screenshot> dataList = screenShotService.listByIds(xlhs);
            response.setContentType("application/vnd.openxmlformats-officedocument.speadsheetml.sheet");
            response.setCharacterEncoding("UTF-8");
            // 这里URLEncoder.encode可以防止中文乱码, 与EasyExcel无关
            String fileName = URLEncoder.encode("这里是Excel文件名", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            //不写入Excel中的表字段
            Set<String> excludeColumns = new HashSet<>();
            excludeColumns.add("id");
            excludeColumns.add("src");
            EasyExcel.write(response.getOutputStream(), ScreenshotVo.class).excludeColumnFiledNames(excludeColumns).sheet("巡课截图信息").doWrite(dataList);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
     }

(2) 压缩包代码

    @PostMapping("/exportZip")
    public void exportZip(@RequestBody Map<String,Object> params ,HttpServletResponse response){
        //准备需要导出的数据
        List<Integer> xlhs = (List<Integer>) params.get("xlhs");
        List<Screenshot> dataList = screenShotService.listByIds(xlhs);
        //图片链接的前缀
        String urlPrefix = String.valueOf(params.get("urlPrefix"));

        byte[] buf = new byte[1024];
        BufferedOutputStream bos = null;
        ZipOutputStream out = null;
        try {
            // 重置
            response.reset();
            // 允许http://127.0.0.1:8080进行跨域访问
            response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8099");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); // 允许的访问方法
            response.setHeader("Access-Control-Max-Age", "3600"); // 缓存该结果的时间,单位为秒
            response.setHeader("Access-Control-Allow-Headers",
                    "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers"); // 允许的自定义请求头
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition","attachment;filename=" + URLEncoder.encode("巡课截图.zip",
                    "UTF-8"));

            bos = new BufferedOutputStream(response.getOutputStream());
            out = new ZipOutputStream(bos);
            for (Screenshot screenshot:dataList){
                String imgUrl = urlPrefix + screenshot.getSrc(); //拼接图片完整路径
                //图片重命名
                String imgName = screenshot.getJsmc()+"_"+screenshot.getSkbj()+"_"+screenshot.getJtdate()+
                        imgUrl.substring(imgUrl.lastIndexOf("."));

                URL url = new URL(imgUrl);
                URLConnection conn = url.openConnection();
                InputStream in = conn.getInputStream();
                out.putNextEntry(new ZipEntry(imgName));
                int len = -1;
                while ((len=in.read(buf))!=-1){
                    out.write(buf,0,len);
                }
                in.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (out!=null)
                    out.close();
                if (bos!=null)
                    bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

前端有两种请求方式都可以实现:
(1) ajax请求下载Excel:

    //导出数据
    exportData(){
      //this.checkList是存放前端选中数据的数组
      if (this.checkList.length == 0) {
        this.$message.info("请勾选要导出的数据");
        return false;
      }
      var ids = [];
      //将每条数据的id取出来封装成数组
      for(var i=0;i<this.checkList.length;i++){
        ids.push(this.checkList[i].id)
      }
      var jsonData = {
        "ids ": ids 
      }
      
      var url = "请求路径";
	  var xhr = new XMLHttpRequest();
	  xhr.open('POST', url, true);  
      xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); //必须暴露请求头 不设置后端拿不到数据
	  xhr.responseType = "blob";   //响应类型必须设为二进制文件流
	  xhr.onload = function () {
		// 请求完成
		if (this.status === 200) {
			// 返回200
			var blob = this.response;
        // 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx") 设置的文件名;
        var contentDispositionHeader = xhr.getResponseHeader('Content-Disposition');
        var filename = decodeURIComponent(contentDispositionHeader.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1]);
        // 下载
		var reader = new FileReader();
		reader.readAsDataURL(blob);     
		reader.onload = function (e) {
			var a = document.createElement('a');  //创建a标签
			a.download = filename;
			a.href = e.target.result;
			document.body.appendChild(a); // 将a标签挂载上去
			a.click();
			document.body.removeChild(a); // 移除a标签 
		}
	}
	};
	// 发送ajax请求
	xhr.send(JSON.stringify(jsonData))
  },

(2) vue方法请求下载Excel:

    //导出数据
    exportData(){
      //this.checkList是存放前端选中数据的数组
      if (this.checkList.length == 0) {
        this.$message.info("请勾选要导出的数据");
        return false;
      }
      var ids = [];
      //将每条数据的id取出来封装成数组
      for(var i=0;i<this.checkList.length;i++){
        ids.push(this.checkList[i].id)
      }
      var jsonData = {
        "ids ": ids 
      }
      exportExcel(jsonData).then(res=>{
          // 将文件流转成blob形式
          const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
          // 创建一个超链接,将文件流赋进去,然后实现这个超链接的单击事件
          const eLink = document.createElement('a')
          console.log(res.headers);
          var contentDispositionHeader = res.headers['content-disposition']
          eLink.download = decodeURIComponent(contentDispositionHeader.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1]);
          eLink.style.display = 'none'
          eLink.href = URL.createObjectURL(blob)
          document.body.appendChild(eLink)
          eLink.click()
          URL.revokeObjectURL(eLink.href) // 释放URL 对象
          document.body.removeChild(eLink)
          this.$message.success("导出成功")
      })     
  },

(3) ajax请求下载zip压缩包:

    /*************************** 下载zip ********************************************/
      var zipurl = config.apiUrl+'/ScreenShot/exportZip';
			var zipxhr = new XMLHttpRequest();
			zipxhr.open('POST', zipurl, true);  
      zipxhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); //必须暴露请求头 不设置后端拿不到前端传的参数
			zipxhr.responseType = "blob";   //响应类型必须设为二进制文件流
			zipxhr.onload = function () {
				// 请求完成
			if (this.status === 200) {
				// 返回200
				var zipblob = this.response;
        // 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode("巡课截图.zip", "UTF-8")) 设置的文件名;
        // var contentDispositionHeader = zipxhr.getResponseHeader('Content-Disposition');
        // console.log(contentDispositionHeader);
        // var zipfilename = decodeURIComponent(contentDispositionHeader.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1]);
        var zipfilename = "巡课截图.zip";
        // 下载
				var zipreader = new FileReader();
				zipreader.readAsDataURL(zipblob);     
				zipreader.onload = function (e) {
					var zipa = document.createElement('a');  //创建a标签
					zipa.download = zipfilename;
					zipa.href = e.target.result;
					document.body.appendChild(zipa); // 将a标签挂载上去
					zipa.click();
					document.body.removeChild(zipa); // 移除a标签 
				}
			}
			};
			// 发送ajax请求
			zipxhr.send(JSON.stringify(jsonData));
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值