1. 前言
官方文档:http://doc.wupaas.com/docs/easypoi/
1.1 简介
Easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板语言(熟悉的表达式语法),完成以前复杂的写法。
1.2 环境搭建
如果使用maven,请使用如下坐标:
<!--导入导出的工具包,可以完成Excel导出,导入,Word的导出,Excel的导出功能--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>4.1.0</version> </dependency> <!--耦合了spring-mvc 基于AbstractView,极大的简化spring-mvc下的导出功能--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>4.1.0</version> </dependency> <!--基础注解包,作用与实体对象上,拆分后方便maven多工程的依赖管理--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-annotation</artifactId> <version>4.1.0</version> </dependency>
2. 使用EasyPOI
2.1 相关注解
easypoi起因就是Excel的导入导出,最初的模板是实体和Excel的对应,model–row,filed–col 这样利用注解我们可以和容易做到excel到导入导出
经过一段时间发展,现在注解有5个类分别是
- @ExcelTarget 这个是作用于最外层的对象,描述这个对象的id,以便支持一个对象可以针对不同导出做出不同处理
- @Excel 作用到filed上面,是对Excel一列的一个描述
- @ExcelCollection 表示一个集合,主要针对一对多的导出,比如一个老师对应多个科目,科目就可以用集合表示
- @ExcelEntity 表示一个继续深入导出的实体,但他没有太多的实际意义,只是告诉系统这个对象里面同样有导出的字段
- @ExcelIgnore 和名字一样表示这个字段被忽略跳过这个导出
2.1.1 注解@ExcelTarget
作用于实体类上,同时实体类需要实现序列化接口。value需要给定一个唯一的ID,使用类名即可。
@ExcelTarget("user") public class User implements Serializable {
2.1.2 注解@Excel
作用于实体类的属性上,每一个属性将会对应Excel上的一列。
属性 | 类型 | 默认值 | 功能 |
name | String | null | 列名,支持name_id |
needMerge | boolean | fasle | 是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row) |
orderNum | String | “0” | 列的排序,支持name_id |
replace | String[] | {} | 值得替换 导出是{a_id,b_id} 导入反过来 |
savePath | String | “upload” | 导入文件保存路径,如果是图片可以填写,默认是upload/className/ IconEntity这个类对应的就是upload/Icon/ |
type | int | 1 | 导出类型 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本 |
width | double | 10 | 列宽 |
isStatistics | boolean | fasle | 自动统计数据,在追加一行统计,把所有数据都和输出[这个处理会吞没异常,请注意这一点] |
isHyperlink | boolean | false | 超链接,如果是需要实现接口返回对象 |
isImportField | boolean | true | 校验字段,看看这个字段是不是导入的Excel中有,如果没有说明是错误的Excel,读取失败,支持name_id |
exportFormat | String | “” | 导出的时间格式,以这个是否为空来判断是否需要格式化日期 |
importFormat | String | “” | 导入的时间格式,以这个是否为空来判断是否需要格式化日期 |
format | String | “” | 时间格式,相当于同时设置了exportFormat 和 importFormat |
databaseFormat | String | “yyyyMMddHHmmss” | 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string 类型,这个需要设置这个数据库格式,用以转换时间格式输出 |
numFormat | String | “” | 数字格式化,参数是Pattern,使用的对象是DecimalFormat |
imageType | int | 1 | 导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的 |
suffix | String | “” | 文字后缀,如% 90 变成90% |
isWrap | boolean | true | 是否换行 即支持\n |
mergeRely | int[] | {} | 合并单元格依赖关系,比如第二列合并是基于第一列 则{0}就可以了 |
mergeVertical | boolean | fasle | 纵向合并内容相同的单元格 |
fixedIndex | int | -1 | 对应excel的列,忽略名字 |
isColumnHidden | boolean | false | 导出隐藏列 |
2.1.3 注解@ExcelCollection
一对多的集合注解,用以标记集合是否被数据以及集合的整体排序。
属性 | 类型 | 默认值 | 功能 |
id | String | null | 定义ID |
name | String | null | 定义集合列名,支持nanm_id |
orderNum | int | 0 | 排序,支持name_id |
type | Class<?> | ArrayList.class | 导入时创建对象使用 |
@ExcelCollection(name = "订单列表",orderNum = "8") private List<Order> orders; • 1 • 2
@ExcelTarget("orders") @Data @AllArgsConstructor public class Order implements Serializable { /** * 订单编号 */ @Excel(name = "订单编号",orderNum = "8",width = 20.0) private String num; /** * 订单名称 */ @Excel(name = "订单名称",orderNum = "9",width = 20.0) private String name; }
2.1.4 注解@ExcelEntity
一对一实体对应,作用在实体类里面的属性又是一个实体类的情况。同时被组合的实体类也需要使用ExcelTarget和Excel进行标识。同时实现序列化接口。
@ExcelEntity private Department department;
@Data @NoArgsConstructor @AllArgsConstructor @Builder @ExcelTarget("department") public class Department implements Serializable { /** * 部门ID */ private Integer deptId; /** * 部门名称 */ @Excel(name = "部门") private String deptName; /** * 地址 */ private String address; }
2.1.5 注解@ExcelIgnore
忽略这个属性。
2.2. Maven项目整合EasyPOI
2.2.1 引入依赖
<dependencies> <!--引入EasyPOI--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-annotation</artifactId> <version>4.1.0</version> </dependency> <!--引入Junit测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <!--引入Lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
2.2.2 创建实体类
2.2.2.1 用户实体
/** * @ClassName: User * @Description: 用户实体类,需要实现对象序列化接口 * @author: 莫提 * @date 2020/11/27 8:55 * @Version: 1.0 */ @Data @AllArgsConstructor @Builder @ExcelTarget("user") public class User implements Serializable { /** * 用户 ID */ @Excel(name = "编号",orderNum = "0",suffix = "号") private Integer id; /** * 姓名 */ @Excel(name = "姓名",orderNum = "1") private String name; /** * 性别 */ @Excel(name = "性别",orderNum = "2",replace = {"男性_男","女性_女"}) private String sex; /** * 生日 */ @Excel(name = "生日",width = 35.0,format = "yyyy-MM-dd HH:mm:ss",orderNum = "4") private Date birthday; /** * 用户状态:【1:正常】【0:封禁】 */ @Excel(name = "用户状态",replace = {"正常_1","封禁_0"},orderNum = "3") private Integer status; /** * 密码 */ @ExcelIgnore private String password; /** * 爱好 */ @Excel(name = "爱好",orderNum = "5",width = 40.0) private List<String> hobbies; /** * 爱好字符串 */ @Excel(name = "爱好",orderNum = "5",width = 40.0) private String hobbyStr; /** * 身份证【一对一】 */ @ExcelEntity private Card card; /** * 订单列表【一对多】 */ @ExcelCollection(name = "订单列表",orderNum = "8") private List<Order> orders; /** * 头像信息,type = 2表示图片 */ @Excel(name = "头像",width = 20,height = 40,type = 2) private String photo; public String getHobbyStr(){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < hobbies.size(); i++) { sb.append(hobbies.get(i)); if (i != hobbies.size() -1){ sb.append(","); } } return sb.toString(); } }
Excel轻松操控:掌握EasyPoi的妙用技巧(二)https://developer.aliyun.com/article/1480479