后端创文件流前端浏览器进行下载Excel(springboot+Vue)

一.后端代码
记得引入POI依赖
后端将要下载的数据转成输出流

public void Export(HttpServletResponse response,List Listexamgrade)throws IOException {
    // 创建工作空间
        Workbook wb = new XSSFWorkbook();
        // 创建工作表
        Sheet sheet = wb.createSheet("员工成绩");
        // 创建标题行(第一行)
        Row row0 = sheet.createRow(0);

        CellStyle style = wb.createCellStyle();
        Font headerFont = wb.createFont(); // 字体
        headerFont.setFontHeightInPoints((short) 14);
        headerFont.setColor(HSSFColor.BLACK.index);
        headerFont.setFontName("宋体");
        sheet.setColumnWidth(3, 252*30);
        sheet.setColumnWidth(5, 252*30);
        sheet.setColumnWidth(6, 252*30);
        sheet.setColumnWidth(7, 252*30);
        style.setFont(headerFont);
        Cell cell1 = row0.createCell(0);// 第一个参数:列数(从0开始),第二个参数:列类型
        Cell cell2 = row0.createCell(1);// 第一个参数:列数(从0开始),第二个参数:列类型
        Cell cell3 = row0.createCell(2);
        Cell cell4 = row0.createCell(3);
        Cell cell5 = row0.createCell(4);
        Cell cell6 = row0.createCell(5);
        Cell cell7 = row0.createCell(6);
        Cell cell8 = row0.createCell(7);
        Cell cell9 = row0.createCell(8);
        cell1.setCellStyle(style);
        cell2.setCellStyle(style);
        cell3.setCellStyle(style);
        cell4.setCellStyle(style);
        cell5.setCellStyle(style);
        cell6.setCellStyle(style);
        cell7.setCellStyle(style);
        cell8.setCellStyle(style);
        cell9.setCellStyle(style);

        cell1.setCellValue("名次");
        cell2.setCellValue("姓名");
        cell3.setCellValue("工号");
        cell4.setCellValue("考试名称");
        cell5.setCellValue("分数");
        cell6.setCellValue("是否及格");
        cell7.setCellValue("考试开始时间");
        cell8.setCellValue("考试结束时间");
        cell9.setCellValue("试卷总分");

        for (int j = 1;j< Listexamgrade.size()+1;j++) {
            Row row = sheet.createRow(j);
            for(int i = 0;i < 9 ;i++){
                Cell cell = row.createCell(i);
                ExamGrade examGrade= Listexamgrade.get(j-1);
                if(i == 0){
                    cell.setCellValue(j);
                }else if(i == 1){
                    cell.setCellValue(examGrade.getCompellation());
                }else if(i == 2){
                    cell.setCellValue(examGrade.getJobnumber());
                }else if(i == 3){
                    cell.setCellValue(examGrade.getExamname());
                }else if(i == 4){
                    cell.setCellValue(examGrade.getGrade());
                }else if(i == 5){
                    cell.setCellValue(examGrade.getWhetherPass());
                }else if(i == 6){
                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
                    String str = df.format(examGrade.getExamstarttime());
                    cell.setCellValue(str);
                }else if(i == 7){
                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
                    String str = df.format(examGrade.getExamendtime());
                    cell.setCellValue(str);
                }else if(i == 8){
                    cell.setCellValue(examGrade.getTotalscore());
                }
            }
        }
        // 设置生成的Excel的文件名,并以中文进行编码
        String codedFileName = "****表";
        response.setHeader("Content-Disposition", "attachment;filename=" + codedFileName + ".xlsx");
        // 响应类型,编码
        response.setContentType("application/octet-stream;charset=UTF-8");
        // 形成输出流
        OutputStream osOut = response.getOutputStream();
        // 将指定的字节写入此输出流
        wb.write(osOut);
        // 刷新此输出流并强制将所有缓冲的输出字节被写出
        osOut.flush();
        // 关闭流
        osOut.close();
        wb.close();
        }

二.前端
前端接收后端传输的流,使用Blob对象下载文件

  this.$http({
        url: this.$http.adornUrl("请求路径"),//这里进行过封装
        method: "get",
        params: { 参数key: 参数value },
        headers: {
          "Content-Type": "application/json; application/octet-stream"
        },
        responseType: "blob" // 服务器返回的数据类型
      })
      .then(function(res) {
        console.log(res);
        // 此处有个坑。这里用content保存文件流,最初是content=res,但下载的test.xls里的内容如下图1,
        // 检查了下才发现,后端对文件流做了一层封装,所以将content指向res.data即可
        // 另外,流的转储属于浅拷贝,所以此处的content转储仅仅是便于理解,并没有实际作用=_=
        const content = res.data;
        const blob = new Blob([content], { type: "application/excel" }); // 构造一个blob对象来处理数据
        const fileName = self.examname + "员工成绩.xlsx"; // 导出文件名
        // 对于标签,只有 Firefox 和 Chrome(内核) 支持 download 属性
        // IE10以上支持blob但是依然不支持download
        if ("download" in document.createElement("a")) {
          // 支持a标签download的浏览器
          const link = document.createElement("a"); // 创建a标签
          link.download = fileName; // a标签添加属性
          link.style.display = "none";
          link.href = URL.createObjectURL(blob);
          document.body.appendChild(link);
         link.click(); // 执行下载
          URL.revokeObjectURL(link.href); // 释放url
          document.body.removeChild(link); // 释放标签
        } else {
          // 其他浏览器
          navigator.msSaveBlob(blob, fileName);
        }
      })
      .catch(error => {
        console.log(error);
      });

实现该功能所遇问题:
1.文件已损坏,无法打开。解决方法:设置一下Excel信任中心。转载:https://blog.csdn.net/weixin_34329187/article/details/94566162

你可能感兴趣的:(个人经验)