VUE及后台实现流下载Excel文件

后台: 设置头
public void orderDownload(@RequestBody OrderProductsReq req,
                    HttpServletResponse response) {
   String orderToStr = dateToStr(req.getOrderTo() == null ? null : req.getOrderTo());
   String orderFromStr = dateToStr(req.getOrderFrom() == null ? null : req.getOrderFrom());
   //----------------处理文件名--------------------
   String fromTempStr = orderFromStr == null ? "最开始" : orderFromStr;
   String toTempStr = orderToStr == null ? "现在" : orderToStr;
   String fileName = fromTempStr+"-"+toTempStr+"意向记录:" + System.currentTimeMillis();
   //-------------------------------------------------
   try {
      response.setHeader("Content-type", "application/vnd.ms-excel");
      // 解决导出文件名中文乱码
      response.setCharacterEncoding("UTF-8");
      response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1") + ".xlsx");
      orderProductsService.orderDownload(req,response.getOutputStream());
   } catch (Exception e) {
      e.printStackTrace();
   }
}

//数据写入流部分代码

List<OrderProductsQueryRes> rowList = result.getResult();
// 1.创建Excel工作薄对象
Workbook wb = new XSSFWorkbook();
// 2.创建Excel工作表对象
Sheet sheet = wb.createSheet("意向患者");
//3.将数据写入sheet
bulidFirstSheet(sheet, rowList);
try {
    //4.将Excel写入到输出流里面
    wb.write(outputStream);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    try {
        wb.close();
        outputStream.close();
        outputStream.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

前台: 文件名可以通过response.headers获取设置或者在前端处理

downloadGridData: function () {
  var _this = this
  this.$http.post(_this.$host + 'admin_product_order_manage/orderListDownload', _this.search, {responseType: 'arraybuffer'}
  ).then(response => {
    let blob = new Blob([response.data], {type: 'application/vnd.ms-excel'})
    let dateTime = new Date()
    let dateTimeStr = dateTime.getFullYear() + '-' + dateTime.getMonth() + '-' + dateTime.getDay()
    let filename = '意向患者-' + dateTimeStr + '_' + new Date().getTime() + '.xls'
    if (typeof window.navigator.msSaveBlob !== 'undefined') {
      window.navigator.msSaveBlob(blob, filename)
    } else {
      var blobURL = window.URL.createObjectURL(blob)// 将blob对象转为一个URL
      var tempLink = document.createElement('a')// 创建一个a标签
      tempLink.style.display = 'none'
      tempLink.href = blobURL
      tempLink.setAttribute('download', filename)// 给a标签添加下载属性
      if (typeof tempLink.download === 'undefined') {
        tempLink.setAttribute('target', '_blank')
      }
      document.body.appendChild(tempLink)// 将a标签添加到body当中
      tempLink.click()// 启动下载
      document.body.removeChild(tempLink)// 下载完毕删除a标签
      window.URL.revokeObjectURL(blobURL)
    }
  }).catch((error) => {
    //
    console.log(error)
  })
}

上方为下载Excel文件的一个核心逻辑,需要你自己构建一个函数,将上方代码放入,下面是原理:

1、获取后端传递来的二进制数据流

2、传递到封装的函数当中,需要传递二进制数据和文件名

3、将二进制数据流包裹成一个new Blob对象

4、将Blob对象转化为一个URL资源地址,这个地址时一个本地地址

5、创建一个a标签,设置隐藏,添加下载属性,添加到body当中,启动下载

6、下载完毕之后,删除a标签

注意事项:

在vue框架当中,数据请求是借助axios的,为此,在发送请求的时候,需要修改responseType,改为arraybuffer,axios默认情况下responseType为json,若是不修改,很可能下载时候会是乱码,或者为null。
 

猜你喜欢

转载自blog.csdn.net/feng271374203/article/details/88656055