使用vue+Springboot+easyExecl导出文件时,在浏览器中下载的文件总是打不开,并且显示这个错误

esayexcel 导出 项目重启_esayexcel 导出 项目重启


1.我们逐步进行排查,首先看是不是后端的问题。这里附上我后端的代码

@GetMapping("/downloadTemplate")
    public void download(HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=example.xlsx");
        List<Entry> entries = new ArrayList<Entry>();
        Entry entry = new Entry();
        entry.setQuestion("整改方案很清楚,但酒店不愿意整改,怎么办?");
        entry.setAnswer("A:升级到区域协调,及时在甲方在的微信群反馈,任何纠纷我们都不与酒店交涉。");
        entry.setQuestionType("工程师问题");
        entry.setDataSource("美团");
        entry.setKeyword("整改,方案,不整改,不愿整改");
        entry.setQuestionCategory("踏勘问题");
        entry.setEquipmentCategory("流程问题");
        entries.add(entry);
        EasyExcel.write(response.getOutputStream(), Entry.class).registerWriteHandler(CellStyleUtils.getHorizontalCellStyleStrategy()).
        sheet("sheet1").doWrite(entries);
    }

在后端的代码中,使用easyExecl将响应的数据转为了流的形式,这个代码看起来没有问题,我们使用localhost+downloadTemplate的方式进行请求接口,这里我就不演示了,最终的结果是成功下载,并且可以正常打开,这证明我们后端的代码没有问题。

2.我们看一眼返回的响应数据,在控制台打印

esayexcel 导出 项目重启_esayexcel 导出 项目重启_02

再看我们前端的代码

request(downloadTemplate, METHOD.GET,null,{responseType: 'blob'}).then(res => {
        console.log(res)
        if (res.status === 200) {
          let blob = new Blob([res.data], {type: res.data.type})
          const fileName = 'ProductTemplateCopy.xlsx';
          let downloadElement = document.createElement('a')
          let href = window.URL.createObjectURL(blob); //创建下载的链接
          downloadElement.href = href;
          downloadElement.download = fileName; //下载后文件名
          document.body.appendChild(downloadElement);
          downloadElement.click(); //点击下载
          document.body.removeChild(downloadElement); //下载完成移除元素
          window.URL.revokeObjectURL(href); //释放blob

          this.$message.info('导出成功')
        }

请求接口时,我们设置返回的应该是blob文件,再看我们第二步,可以看到在这里blob文件被硬生生转换成了json格式的代码。然后下载后的文件就损坏报错。

为什么会出现这种情况呢?

文件发生了变化,他是在哪变化的?因此我想到了是响应的时候某一个地方应该进行了处理,在此,我使用的是antd-vue-admin这个模板,其中的mockjs会对所有的前端请求进行一个拦截处理,就会对blob产生影响。所以我尝试将src/main中的mock注释

esayexcel 导出 项目重启_vue.js_03

注释之后,重新尝试请求接口,最终成功了。下载的文件也可以打开了。因此本次bug出现的原因是mock处理导致blob发生了变化。