axios下载excel踩坑记录(导出Excel总是报格式错误而且乱码)

项目中使用axios下载Excel时,遇到文件打开报错且显示乱码的问题。通过检查发现,虽然后端生成并返回了文件流,前端接收到的数据类型为字符串而非预期的blob。问题根源在于MockJS导致请求被封装,即使未配置拦截下载请求,也会对所有请求进行处理。解决方案是禁用MockJS,避免其影响下载请求。这样便能成功导出Excel文件。

项目需要,有一个功能是后端生成Excel文件并且写入文件流,前台接收并提示用户导出文件。

看起来是个很简单的功能,网上关于这个功能的解决办法也有很多,基本都差不多,大致如下:

  • 后端:
@RequestMapping(value = "/exportGatherXls", method = RequestMethod.POST)
  public void exportGatherXls(HttpServletResponse response) {
    //导出Excel
    response.setContentType("application/vnd.ms-excel;charset=utf-8");
    String codedFileName = "test";
    OutputStream fOut = null;
    try {
      String newtitle = new String(codedFileName.getBytes("UTF-8"), "ISO8859-1");
      response.setHeader("content-disposition", "attachment;filename=" + newtitle + ".xls");
      Workbook workbook = new HSSFWorkbook();
      //2.创建工作簿
      Sheet sheet = workbook.createSheet();
      //3.创建标题行,测试数据
      Row titlerRow = sheet.createRow(0);
      titlerRow.createCell(0).setCellValue("省");
      titlerRow.createCell(1).setCellValue("市");
      titlerRow.createCell(2).setCellValue("区");
      titlerRow.createCell(3).setCellValue("邮编");
      titlerRow.createCell(4).setCellValue("简码");
       titlerRow.createCell(5).setCellValue("城市编码");
      fOut = response.getOutputStream();
      workbook.write(fOut);
      workbook.close();
    } catch (Exception e) {

    }finally {
      try {
        if (fOut != null) {
          fOut.flush();
          fOut.close();
        }
      } catch (IOException e) {
      }
    }
  }
  • 前端:
axios({
    method: 'post',
    url: url,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
    data: qs.stringify(params, {arrayFormat: 'brackets'}),
    // 这个非常重要!!
    responseType: 'blob'
  }).then(response => {
    let blob = new Blob([response.data], {type: 'application/vnd.ms-excel;charset=utf-8'});
    let downloadElement = document.createElement('a');
    let href = window.URL.createObjectURL(blob); //创建下载的链接
    downloadElement.href = href;
    downloadElement.download = '导出文件.xls'; //下载后文件名
    document.body.appendChild(downloadElement);
    downloadElement.click(); //点击下载
    document.body.removeChild(downloadElement); //下载完成移除元素
    window.URL.revokeObjectURL(href); //释放掉blob对象
  });

基本上就可以实现导出功能了。

但是!我尝试了无数次都遇到了导出的文件打开提示错误并且乱码的问题:

强行打开是这个鬼样子:

我对照网上的下载文件的代码检查和尝试了很多次都是这个错误,直到查看response的结构发现了这个:

这里的request类型不是原生的XMLHttpRequest,data是字符串类型,按照我们的设置应该是blob类型才对。

字面意思看起来应该是我使用了mockjs所以导致了Request类型被封装,去掉mock引入,正解!

结论:下载文件不要使用mockjs,尽管并没有配置拦截下载的后端地址,但是mock会拦截所有的请求,匹配规则的就使用模拟数据,不匹配的也会使用封装后的request请求后台。

真是一个不容易发现原因的问题,前后花了大半天时间才解决。希望可以帮助到和我遇到一样问题的小伙伴们~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值