EasyExcel优雅实现Excel导入导出

EasyExcel 优雅实现Excel导入导出 一、简介 传统操作Excel大多都是利用Apach POI进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多的缺陷。 动态操作Excel非常繁琐,对于新手来说,很难在短时间内上手; 读写时需要占用较大的内存,当数据量大时容易发生内存溢出问题(

EasyExcel 优雅实现Excel导入导出

一、简介

传统操作Excel大多都是利用Apach POI进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多的缺陷。

  • 动态操作Excel非常繁琐,对于新手来说,很难在短时间内上手;
  • 读写时需要占用较大的内存,当数据量大时容易发生内存溢出问题(OOM);
    而EasyExcel 是一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。它能让你在不用考虑性能、内存的等因素的情况下,快速完成 Excel 的读、写等功能。

注意:easyExcel底层也是使用POI实现的;

官网地址:https://developer.aliyun.com/article/787306
相关依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.3</version>
</dependency>

Excel相关结构说明:
image-couk.png

二、EasyExcel导出数据

2.1 定义实体类

在EasyExcel中,以面向对象思想来实现导入导出,无论是导入数据还是导出数据都可以想象成具体某个对象的集合,所以为了实现导出用户信息功能,首先创建一个用户对象UserDO实体类,用于封装用户信息:

@Data
public class UserDO {
    @ExcelProperty("用户编号")
    @ColumnWidth(20)
    private Long id;

    @ExcelProperty(value = {"用户名"},index = 1)
    @ColumnWidth(20)
    private String username;

    @ExcelIgnore
    private String password;

    @ExcelProperty("生日")
    @ColumnWidth(20)
    @DateTimeFormat("yyyy-MM-dd")
    private Date birthday;

    @ExcelProperty("身高(米)")
    @NumberFormat("#.##")
    @ColumnWidth(20)
    private Double height;

    @ExcelProperty(value = "性别", converter = GenderConverter.class)
    @ColumnWidth(10)
    private Integer gender;
}

类属性上使用了EasyExcel核心注解解释:

  • @ExcelProperty:核心注解,value属性可用来设置表头名称,converter属性可以用来设置类型转换器,index是排序规则,值越大 越靠近右边;
  • @ColumnWidth:用于设置表格列的宽度;
  • @DateTimeFormat:用于设置日期转换格式;
  • @NumberFormat:用于设置数字转换格式。
  • @ExcelIgnore:忽略指定表头信息,就不会到处此字段。
    image-qlzb.png

2.2 合并表头

添加合并表头信息:

@Data
public class User implements Serializable {
    @ExcelProperty(value = {"用户基本信息","用户名"},index = 1)
    private String userName;
    @ExcelProperty(value = {"用户基本信息","年龄"},index = 2)
    private Integer age;
    @ExcelProperty(value = {"用户基本信息","地址"} ,index = 4)
    private String address;
    @ExcelProperty(value = {"用户基本信息","生日"},index = 3)
    //注意:日期格式注解由alibaba.excel提供
    @DateTimeFormat("yyyy/MM/dd HH:mm")
    private Date birthday;
}

image-pnbt.png

2.3 设置单元格大小

@Data
@HeadRowHeight(value = 35) // 表头行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 50) // 列宽
public class User implements Serializable {
    ....
}
  • @HeadRowHeight:表头行高
  • @ContentRowHeight:内容行高
  • @ColumnWidth:列宽

2.4 定义导出接口

//EasyExcel.write("C:\\Users\\46035\\Desktop\\ex\\用户.xls",User.class).sheet("用户信息").doWrite(users);
List<UserDO> userList = this.getUserList();
EasyExcel.write(response.getOutputStream())
                    .head(UserDO.class) //出入的对象类
                    .excelType(ExcelTypeEnum.XLSX) //导出的文档类型
                    .sheet("用户列表") //文档名称
                    .doWrite(userList); //传入的对象

2.5 web数据写出

@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
    response.setContentType("application/vnd.ms-excel");
    response.setCharacterEncoding("utf-8");
    // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
    String fileName = URLEncoder.encode("数据写出", "UTF-8");
    response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
}

二、EasyExcel导入数据

/**
     * excel数据格式必须与实体类定义一致,否则数据读取不到
     */
    @Test
    public void readExcel(){
        ArrayList<User> users = new ArrayList<>();
        //读取数据
        EasyExcel.read("C:\\Users\\46035\\Desktop\\ex\\用户.xls", User.class, new AnalysisEventListener<User>() {
            //开始解析
            @Override
            public void invoke(User o, AnalysisContext analysisContext) {
                System.out.println(o);
                users.add(o);
            }
            //解析完成
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                System.out.println("完成。。。。");
            }
        }).sheet().doRead();
    }

批量导入导出教程:http://t.csdnimg.cn/Zw6ir

Comment