springboot+vue +poi excel文件导出下载

后端controller层:

@PostMapping("/listExport")
    public void maEmployeeListExport(//这里返回值必须为空,如果设返回了result结果类,返回给前端会报错
            @RequestParam(value = "belong", required = false) String belong,
            @RequestParam(value = "role", required = false) String role,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "phone", required = false) String phone,
            HttpServletResponse response){
        //第一步创建一个webbook,对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        wb = maEmployeeService.maEmployeeListExport(belong, role, name, phone);//这里调用service层相关方法,主要是为了生成一个workbook,具体service层可根据自己需求编写
        //将文件传给前端
        try {
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            String filename = "filename="
                    + URLEncoder.encode("excle文件.xlsx", "UTF-8") + ";";
            response.setHeader("Content-Disposition", filename);
            try {
                wb.write(response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

前端vue

1、使用vue-elementui,前端会接受统一格式的返回值,如以下格式:

主要代码位于:\src\utils\request.js,但是后端返回值为一个数据流,无法返回正常的结果集,所以需要修改这个文件中的代码,思路为判断为文件流格式直接将获取到的结果返回,具体如下:

service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    const res = response.data
    
    //!!!!!修改的部分就是在这里增加一个if语句,如果为判断返回值为文件流直接跳过校验
    if (res instanceof Blob) {
      return Promise.resolve(response)//这里要返回response,而不是response.data,后续需要从response中获取headers
    }
    
    // if the custom code is not 20000, it is judged as an error.
    if (res.code !== 20000) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

2、请求excel导出接口,位于src\api\目录下:

exportMaEmployeeList(searchModel) {
        return request({
            url: '/sys/maEmployee/listExport',
            method: 'post',
            params: {
                belong: searchModel.belong,
                role: searchModel.role,
                name: searchModel.name,
                phone: searchModel.phone,
            },
            responseType: 'blob'//这里需要设置成blob类型
        });
    },

3、接受后端的文件流并导出,位于src\views的vue文件:

exportMaEmployeeList() {
      maEmployeeApi.exportMaEmployeeList(this.searchModel).then(response => {
        var blob = new Blob([response.data], {
          type: "application/vnd.ms-excel;charset=utf-8",
        }); 
        //获取文件名
        var temp = response.headers["content-disposition"];//这里有个bug,后端写的是Content-Disposition,但是log打印response,变成了content-disposition。
        var fileName = decodeURIComponent(temp.split("filename=")[1]); // 中文需要转码 (前端乱码)
        var name = fileName.split(";")[0]; //切割成文件名
        
        var url = window.URL.createObjectURL(blob);
        //使用a标签拼接字符串
        var aLink = document.createElement("a");
        aLink.style.display = "none";
        aLink.download = name;
        aLink.href = url;
        document.body.appendChild(aLink);
        aLink.click();
      });

    },

总结

excel导出后端返回值需要改成void,然后需要更改前端request.js对于返回结果的校验,
强行使用结果集返回前端,会导致后端报错,因为返回结果集是json格式,httpservletresponse返回了文件流,可能相当于在返回文件流后又返回一个json导致了报错,如果你有好方法解决这个问题请告诉我

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值