前后端关于导出excel的处理 EasyExcel

介绍

本文会简单地做一个将列表数据导出excel功能的例子,excel框架将采用EasyExcel的,前端使用vue,后端使用Java。
EasyExcel是一个基于Java的简单、省内存的读写Excel的阿里巴巴开源项目。在尽可能节约内存的情况下支持读写百M的Excel。官方文档

代码

后端

依赖

        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>easyexcelartifactId>
            <version>3.0.5version>
        dependency>

导出的model类,使用了@ExcelIgnoreUnannotated和@ExcelProperty两个EasyExcel的注解。具体的注释可以查看文档,进行配置。

@Data
@ExcelIgnoreUnannotated //没有注解的字段都不转换
public class Book{
    @ExcelProperty("编号")//设置了表中列的名称
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ExcelProperty("书名")
    private String name;

    @ExcelProperty("封面图片")
    private String image;

    @ExcelProperty("作者")
    private String author;
}

导出excel的接口

    @GetMapping("/book/export")
    public void export(HttpServletResponse response) throws IOException {
        //获取需要导出的数据
        List<Book> dataList = bookService.list();
        //excel文件名
        final String FILENAME = "图书信息";
        //sheetName
        final String SHEETNAME = "用户信息表";
        //获取model对象类
        Class book = Book.class;

        try {
             //表头样式策略
             WriteCellStyle headWriteCellStyle = new WriteCellStyle();
             //设置头居中
             headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
             //内容策略
             WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
             //设置 水平居中
             contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
             //初始化表格样式
             HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

//                response.setContentType("application/vnd.ms-excel;charset=utf-8");
             response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
             response.setCharacterEncoding("utf-8");
             // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
             String fileName = URLEncoder.encode(FILENAME, "UTF-8").replaceAll("\\+", "%20");
             //响应首部 Access-Control-Expose-Headers 就是控制“暴露”的开关,它列出了哪些首部可以作为响应的一部分暴露给外部。
             //此处设置了开放Content-Disposition,前端可获取该响应参数获取文件名称
             response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
             response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");
             // 这里需要设置不关闭流
             EasyExcel.write(response.getOutputStream(), book).autoCloseStream(Boolean.FALSE)
                     .registerWriteHandler(horizontalCellStyleStrategy).sheet(SHEETNAME).doWrite(dataList);

         } catch (IOException e) { //下载失败情况的处理
             // 重置response
             response.reset();
             response.setContentType("application/json");
             response.setCharacterEncoding("utf-8");
             Map<String, String> map = MapUtils.newHashMap();
             map.put("status", "failure");
             map.put("message", "下载文件失败" + e.getMessage());
             response.getWriter().println(JSON.toJSONString(map));
         }
    }

前端

导出excel的接口调用

      this.$axios({
        method: "get",
        url: "/book/export",
        responseType: "blob", // 表明返回服务器返回的数据类型
      })
        .then((res) => {
          // 处理返回的文件流
          let blob = new Blob([res.data], { type: res.data.type });
          //获取fileName,截取content-disposition的filename;按=分割,取最后一个
          const fileName = decodeURI(res.headers['content-disposition'].split("=")[1], "UTF-8");
          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.success("[图书信息]已成功导出!");
        })
        .catch(function(error) {
          // 请求失败处理
          console.log(error);
        });

实现结果

excel导出成功

前后端关于导出excel的处理 EasyExcel_第1张图片

Fiddler抓包显示的接口数据

前后端关于导出excel的处理 EasyExcel_第2张图片

导出的excel数据

前后端关于导出excel的处理 EasyExcel_第3张图片

本文参考

springboot+easyExcel+vue导出excel
axios无法获取响应头headers的Content-Disposition字段
header中Content-Disposition的作用与使用方法

你可能感兴趣的:(java,java,vue.js)