1 EasyExcel简介

EasyExcel是阿里巴巴开源的一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。

github地址:https://github.com/alibaba/easyexcel

官方文档:https://www.yuque.com/easyexcel/doc/easyexcel

2 EasyExcel的使用

2.1 写入Excel

将一个实体类的数据写入到Excel表格中。

POM导入依赖:

com.alibaba easyexcel 3.0.3

实体类:

@Data public class User { private String name; private String gender; private Integer age; private String phone; private String address; }

设计测试数据:

public static List getDate() { List list = new ArrayList<>(); User u1 = new User("张三", "男", 23, "18888888888", "深圳市"); User u2 = new User("李四", "男", 20, "16666666666", "北京市"); User u3 = new User("王五", "女", 18, "19999999999", "上海市"); User u4 = new User("赵六", "女", 34, "15555555555", "广州市"); list.add(u1); list.add(u2); list.add(u3); list.add(u4); return list; }

写入代码:

public static void write(){ String fileName = "D:\test\test.xlsx"; EasyExcel.write(fileName, User.class) .sheet("模板") .doWrite(getDate()); }

最后通过主类调用write()方法,出现如下运行结果则表示写入成功

输出

打开写入后生成的Excel文件,可见数据都成功写入到Excel文件中。

表格

2.1.1 代码解析

通过简单的代码就实现了将数据写入到Excel文件中,重点就是写入部分的代码:

首先声明一个文件路径用于保存生成的文件,不需要文件存在,在写入的时候会自动生成该文件。

String fileName = "F:\test\test.xlsx";

然后就是关键的写入部分,在写入的时候直接通过EasyExcel调用write方法,write方法需要传入两个参数,第一个是文件路径,第二个是指定用哪个类去写入,也就是需要写入到Excel文件中数据对应的实体类,然后使用sheet方法指定Excel的sheet名称,再使用doWrite方法指定需要写入的具体数据,本例中再doWrite方法中调用getData方法获取到我们设计好的测试数据。

EasyExcel.write(fileName, User.class) .sheet("模板") .doWrite(getDate());

2.1.2 格式设置

通过写入的Excel文件可以看到,在文件中表头就是我们实体类中的属性名,但是在实际开发中肯定不会直接导出属性名,所以就需要给属性名指定对应的中文名称,在EasyExcel中可以使用@ExcelProperty注解指定写入到Excel中的名字:

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

在@ExcelProperty中除了可以指定表头名称之外,还可以指定该列在整张表中排在第几列,默认的话在Excel中就是按照属性的顺序排列,通过index属性可以指定在第几列,从0开始。

@ExcelProperty(value = "性别", index = 0) private String gender;

还可以看到写入的Excel文件中电话号码列没有完全将电话显示出来,我们则可以通过@ColumnWidth注解指定某一列的宽度。

@ExcelProperty("电话") @ColumnWidth(15) private String phone;

还可以在实体类上使用@ColumnWidth,这样表示将表中的所有列都设置成指定的宽度,实体类上还可以使用@ContentRowHeight指定行高,@HeadRowHeight指定表头高度。

@Data @ContentRowHeight(25) @HeadRowHeight(30) @ColumnWidth(10) public class User { @ExcelProperty("姓名") private String name; @ExcelProperty(value = "性别", index = 0) private String gender; @ExcelProperty("年龄") private Integer age; @ExcelProperty("电话") @ColumnWidth(15) private String phone; @ExcelIgnore private String address; }

通过指定以上表格格式之后再写入的样子就不一样了。

表格

2.1.3 颜色字体设置

在Easy中可以通过注解设置表格的填充颜色和字体,这些注解使用到实体类上。

@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 10) @HeadFontStyle(fontHeightInPoints = 20) @ContentStyle(fillPatternType = FillPatternTypeEnum.LESS_DOTS, fillForegroundColor = 17) @ContentFontStyle(fontHeightInPoints = 20)

HeadStyle和ContentStyle分别用于设置表头填充和内容填充,fillPatternType注定填充类型,填充类型使用枚举类FillPatternTypeEnum获取,在该枚举类中定义了不同的填充类别,通过名称可以大致判断出是哪种填充类型。

枚举值

fillForegroundColor指定填充颜色,颜色传入的是整数值,整数值可以通过IndexedColors类获取,同样通过名称可知具体颜色。

枚举值

指定了颜色和字体之后再次运行程序生成的Excel文件如下:

表格

这里电话号码一列显示异常是因为我们指定了字体的大小,但是电话这一列的列宽只有15,所以就导致电话号码溢出了单元格外。

2.1.4 常用注解

@ExcelProperty:指定属性写入文件后的名称和在那一列

@ColumnWidth:指定列宽

@ContentRowHeight:指定行高

@HeadRowHeight:指定表头高度

@ExcelIgnore:忽略某属性

@HeadStyle:设置表头填充颜色,fillPatternType属性指定填充类型,fillForegroundColor属性指定填充颜色。

@HeadFontStyle:指定表头字体大小,通过fontHeightInPoints属性指定。

@ContentStyle:指定内容区域填充颜色,同@HeadStyle

@ContentFontStyle:指定内容区域字体大小,同@HeadFontStyle

2.2 读取Excel

读取Excel文件相比于写Excel文件要麻烦,我们这里将之前写入到本地的文件再读取出来,使用的User实体类恢复到最初。

@Data public class User { @ExcelProperty("姓名") private String name; @ExcelProperty("性别") private String gender; @ExcelProperty("年龄") private Integer age; @ExcelProperty("电话") private String phone; @ExcelProperty("地址") private String address; }

要读取Excel首先需要定义一个监听器:

public class UserExcelListener extends AnalysisEventListener { // 每次读取一条数据时都会调用到这个方法 @Override public void invoke(User user, AnalysisContext analysisContext) { System.out.println("读取到一条数据:" + JSON.toJSONString(user) ); } // 读取Excel完了之后回调用这个方法 @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { System.out.println("文件读取完毕"); } }

读取代码:

public static void read(){ String fileName = "F:\test\test1.xlsx"; EasyExcel.read(fileName, User.class, new UserExcelListener()) .sheet("模板") .doRead(); }

测试类调用read方法,运行结果:

输出

2.2.1 代码解析

自定义监听器需要继承AnalysisEventListener类,然后重写invoke和doAfterAllAnalysed方法,在读取Excel文件时每次读取一行,当每次读取到一行的时候都会调用invoke方法,当整个Excel文件读取完成之后就会调用doAfterAllAnalysed方法。

具体的读取代码和写入代码结构含义大致相同,除了在读取文件的时候需要多传入一个监听的参数。

特别注意: 自定义的监听器不能被spring管理,所以每次读取Excel都要使用new关键字,不能使用@Autowired注解注入,同样如果需要在监听器里面用到spring管理的类,可以通过监听器的构造方法传进去,例如需要在监听器中使用Dao层,用于将读取到的数据保存到数据库中,可以使用以下方式:

public class UserExcelListener extends AnalysisEventListener { private UserDao userDao; public UserExcelListener(UserDao userDao) { this.userDao = userDao; } }

2.2.2 @ExcelProperty

在读取Excel的时候也可以使用@ExcelProperty,这时候使用该注解同样可以指定名称和index,指定名称则表示要读取与表中名称一样的数据,例如上面的实体类,全部使用的都是这种方法,如果名字重复,会导致只有一个字段读取到数据,指定index表示读取指定列的数据。

@ExcelProperty(index = 3) private String name;

这里的@ExcelProperty(index = 3)表示name属性强制地去读取第四列的内容,这样读取出来的数据就是电话号码会赋值到name中,不推荐这样做。在一个实体类中,最好全部都用名称去匹配或者全部用index去匹配,名称匹配灵活度更高。

2.2.3 读取表头

如果需要读取表头,则需要在自定义监听器的时候实现invokeHeadMap方法,在自定义监听器的时候invoke和doAfterAllAnalysed方法是必须要实现的方法,而invokeHeadMap则没有强制实现。

@Override public void invokeHeadMap(Map headMap, AnalysisContext context) { System.out.println("表头数据:" + headMap); }

输出

原文地址:https://mp.weixin.qq.com/s/LRaUAye30eMAJ-MVIlXTzQ