上接《Springboot下导入导出excel》,本篇详细介绍 EasyExcel
注解使用。
1. @ExcelProperty
value
:指定写入的列头,如果不指定则使用成员变量的名字作为列头;如果要设置复杂的头,可以为value指定多个值order
:优先级高于value
,会根据order
的顺序来匹配实体和excel中数据的顺序index
:优先级高于value
和order
,指定写到第几列,如果不指定则根据成员变量位置排序;默认第一个字段就是index=0
converter
:指定当前字段用什么转换器,默认会自动选择。可以用来设置类型转换器,需要实现Converter
接口
1.1 value
默认情况下,使用类的属性名作为Excel的列表,当然也可以使用 @ExcelProperty
注解来重新指定属性名称。
public class Student {@ExcelProperty(value = "姓名")String name;@ExcelProperty(value = "年龄")Integer age;@ExcelProperty(value = "出生日期")String birthday;@ExcelProperty(value = "分数")Double score;
}
1.1.1 表头合并
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"})String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;
}
1.2 index
如果不指定则按照属性在类中的排列顺序来。index
是指定该属性在Excel中列的下标,下标从 0
开始。
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"}, index = 2)String name;@ExcelProperty(value = {"用户基本信息", "年龄"}, index = 1)Integer age;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数", index = 10)Double score;
}
1.3 order
order
的默认值为 Integer.MAX_VALUE
,通过效果我们可以得出结论:order值越小,越排在前面
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"}, order = 5)Integer age;@ExcelProperty(value = {"用户基本信息", "出生日期"}, order = 6)String birthday;@ExcelProperty(value = "分数")Double score;
}
✨⚠️注意:
优先级
:index > order > 默认配置index
相当于绝对位置,下标从0开始order
相当于相对位置,值越小的排在越前面
1.4 convert
在读写EXCEL时,有时候需要我们进行数据类型转换,例如我们这里的创建时间,在实体对象中是 Long
类型,但是这样直接导出到Excel中不太直观。我们需要转换成 yyyy-MM-dd HH:mm:ss
格式,此时我们就可以用到转换器。
📝DateTimeConverter:
public class DateTimeConverter implements Converter<Long> {private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");// 支持导入的Java类型@Overridepublic Class<?> supportJavaTypeKey() {return Long.class;}// 支持导出的Excel类型@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}// 转换为Java@Overridepublic Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return null;}// 转换为Excel@Overridepublic WriteCellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {if (value == null) {return new WriteCellData(CellDataTypeEnum.STRING, null);}LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneId.systemDefault());String dateStr = localDateTime.format(dateTimeFormatter);return new WriteCellData(dateStr);}
}
supportJavaTypeKey
:导入的Java类型supportExcelTypeKey
:导出的Excel类型,返回CellDataTypeEnum
类型。convertToJavaData
:导入转换逻辑。convertToExcelData
:导出转换逻辑,返回WriteCellData
类型。
📝Student:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
1.4.1 枚举转换
📝GenderEnum:
/*** 性别枚举*/
@Getter
@AllArgsConstructor
public enum GenderEnum {UNKNOWN(0, "未知"),MALE(1, "男性"),FEMALE(2, "女性");private final Integer value;private final String description;public static GenderEnum convert(Integer value) {return Stream.of(values()).filter(bean -> bean.value.equals(value)).findAny().orElse(UNKNOWN);}public static GenderEnum convert(String description) {return Stream.of(values()).filter(bean -> bean.description.equals(description)).findAny().orElse(UNKNOWN);}
}
Stream.of(values())
是 Java 8 中 Stream API 的一种用法,用于将枚举类型的 values()
方法返回的数组转换为一个流。这样可以方便地对枚举常量进行各种操作,如过滤、映射等。
- 每个枚举类型都有一个隐式的
values()
方法,该方法返回一个包含所有枚举常量的数组。Stream.of(T... values)
是一个静态方法,它接受一个可变参数列表,并返回一个包含这些元素的流。当你将values()
方法的结果传递给Stream.of
时,它会将枚举常量数组转换为一个流
。- 使用
findAny()
找到第一个匹配的枚举常量,如果没有找到匹配的枚举常量,则返回 UNKNOWN。
📝GenderConverter:
public class GenderConverter implements Converter<Integer> {// 支持导入的Java类型@Overridepublic Class<?> supportJavaTypeKey() {return Integer.class;}// 支持导出的Excel类型@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}// 转换为Java@Overridepublic Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return GenderEnum.convert(cellData.getStringValue()).getValue();}// 转换为Excel@Overridepublic WriteCellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return new WriteCellData(GenderEnum.convert(value).getDescription());}
}
2. @ExcelIgnore
默认所有字段都会和excel去匹配,加了这个注解会忽略该字段
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ExcelProperty(value = {"用户基本信息", "性别"}, converter = GenderConverter.class)@ExcelIgnoreInteger gender;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
3. @ExcelIgnoreUnannotated
修饰类,如果类不标注该注解时,默认类中所有成员变量都会参与读写,无论是否在成员变量上加了 @ExcelProperty
的注解。标注该注解后,类中的成员变量如果没有标注 @ExcelProperty
注解将不会参与读写。
@Data
@NoArgsConstructor
@AllArgsConstructor
@ExcelIgnoreUnannotated
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;Integer gender;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
4. @HeadRowHeight
修饰类,指定列头行高
@Data
@NoArgsConstructor
@AllArgsConstructor
@HeadRowHeight(80)
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ExcelProperty(value = {"用户基本信息", "性别"}, converter = GenderConverter.class)@ExcelIgnoreInteger gender;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
5. @HeadStyle
设置标题样式
属性 | 描述 |
---|---|
dataFormat | 日期格式 |
hidden | 设置单元格使用此样式隐藏 |
locked | 设置单元格使用此样式锁定 |
quotePrefix | 在单元格前面增加 ' 单引号,数字或公式将以字符串形式展示 |
horizontalAlignment | 设置是否水平居中 |
wrapped | 设置文本是否应换行。将此标志设置为true通过在多行上显示使单元格中的所有内容可见 |
verticalAlignment | 设置是否垂直居中 |
rotation | 设置单元格中文本旋转角度。03版本的Excel旋转角度区间为-90°90°,07版本的Excel旋转角度区间为0°180° |
indent | 设置单元格中缩进文本的空格数 |
borderLeft | 设置左边框的样式 |
borderRight | 设置右边框样式 |
borderTop | 设置上边框样式 |
borderBottom | 设置下边框样式 |
leftBorderColor | 设置左边框颜色 |
rightBorderColor | 设置右边框颜色 |
topBorderColor | 设置上边框颜色 |
bottomBorderColor | 设置下边框颜色 |
fillPatternType | 设置填充类型 |
fillBackgroundColor | 设置背景色 |
fillForegroundColor | 设置前景色 |
shrinkToFit | 设置自动单元格自动大小 |
@Data
@NoArgsConstructor
@AllArgsConstructor
@HeadRowHeight(80)
@HeadStyle(fillForegroundColor = 10, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, wrapped = BooleanEnum.TRUE)
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ExcelProperty(value = {"用户基本信息", "性别"}, converter = GenderConverter.class)@ExcelIgnoreInteger gender;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
6. @HeadFontStyle
设置标题字体格式
属性 | 描述 |
---|---|
fontName | 设置字体名称 |
fontHeightInPoints | 设置字体高度 |
italic | 设置字体是否斜体 |
strikeout | 是否设置删除线 |
color | 设置字体颜色 |
typeOffset | 设置偏移量 |
underline | 设置下划线 |
charset | 设置字体编码 |
bold | 设置字体是否加粗 |
@Data
@NoArgsConstructor
@AllArgsConstructor
@HeadRowHeight(80)
@HeadStyle(fillForegroundColor = 10, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, wrapped = BooleanEnum.TRUE)
@HeadFontStyle(fontHeightInPoints = 10, color = 5)
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ExcelProperty(value = {"用户基本信息", "性别"}, converter = GenderConverter.class)@ExcelIgnoreInteger gender;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
✨💎注:如果需要自定义样式,可以通过继承 AbstractCellStyleStrategy
类(public abstract class AbstractCellStyleStrategy implements CellWriteHandler
),实现其setHeadCellStyle
和 setContentCellStyle
方法可以自定义设置表头和单元格内容样式。
参见📖 Easyexcel(7-自定义样式)
7. @ContentRowHeight
修饰类,指定内容行高
@Data
@NoArgsConstructor
@AllArgsConstructor
@HeadRowHeight(80)
@HeadStyle(fillForegroundColor = 10, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, wrapped = BooleanEnum.TRUE)
@HeadFontStyle(fontHeightInPoints = 10, color = 5)
@ContentRowHeight(value = 30)
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ExcelProperty(value = {"用户基本信息", "性别"}, converter = GenderConverter.class)@ExcelIgnoreInteger gender;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
8. @ColumnWidth
设置表格列的宽度
@Data
@NoArgsConstructor
@AllArgsConstructor
@HeadRowHeight(80)
@HeadStyle(fillForegroundColor = 10, fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, wrapped = BooleanEnum.TRUE)
@HeadFontStyle(fontHeightInPoints = 10, color = 5)
@ContentRowHeight(value = 30)
public class Student {@ExcelProperty(value = {"用户基本信息", "姓名"} )String name;@ExcelProperty(value = {"用户基本信息", "年龄"})Integer age;@ColumnWidth(25)@ExcelProperty(value = {"用户基本信息", "性别"}, converter = GenderConverter.class)Integer gender;@ExcelProperty(value = {"用户基本信息", "出生日期"})String birthday;@ExcelProperty(value = "分数")Double score;@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)private Long createTime;
}
9. @ContentStyle
设置内容格式注解,和 @HeadStyle
属性一致。
属性 | 描述 |
---|---|
dataFormat | 日期格式 |
hidden | 设置单元格使用此样式隐藏 |
locked | 设置单元格使用此样式锁定 |
quotePrefix | 在单元格前面增加`符号,数字或公式将以字符串形式展示 |
horizontalAlignment | 设置是否水平居中 |
wrapped | 设置文本是否应换行。将此标志设置为true通过在多行上显示使单元格中的所有内容可见 |
verticalAlignment | 设置是否垂直居中 |
rotation | 设置单元格中文本旋转角度。03版本的Excel旋转角度区间为-90°90°,07版本的Excel旋转角度区间为0°180° |
indent | 设置单元格中缩进文本的空格数 |
borderLeft | 设置左边框的样式 |
borderRight | 设置右边框样式 |
borderTop | 设置上边框样式 |
borderBottom | 设置下边框样式 |
leftBorderColor | 设置左边框颜色 |
rightBorderColor | 设置右边框颜色 |
topBorderColor | 设置上边框颜色 |
bottomBorderColor | 设置下边框颜色 |
fillPatternType | 设置填充类型 |
fillBackgroundColor | 设置背景色 |
fillForegroundColor | 设置前景色 |
shrinkToFit | 设置自动单元格自动大小 |
注解 @HeadStyle
的属性 dataFormat
没有说明,在此处说明一下。@ContentStyle
注解的 dataFormat
属性可以接受一个整数,该整数对应于 Excel 的预定义格式代码。
常见值:
- 0 或 General:通用格式
- 1:数字格式(0.00)
- 2:货币格式(#,##0.00_); (#,##0.00)
- 9:百分比格式(0%)
- 20:日期格式(yyyy-mm-dd)
- 21:日期格式(mm/dd/yyyy)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题 (yyyy-mm-dd)")@ContentStyle(dataFormat = 22) // yyyy-mm-dd 格式private Date date;@ExcelProperty("百分比标题")@ContentStyle(dataFormat = 9) // 百分比格式private Double percentage;@ExcelProperty("货币标题")@ContentStyle(dataFormat = 2) // 货币格式private Double currency;
}
public static void exportExcel(String fileName) {// 写入数据List<Student> data = new ArrayList<>();data.add(new Student("张三", new Date(), 0.2, 100.25));data.add(new Student("李四", new Date(), 0.35, 200.0));data.add(new Student("李丽", new Date(), 0.27, 345.5));data.add(new Student("王二", new Date(), 0.65, 123458.9));// 创建写入对象EasyExcel.write(fileName, Student.class).sheet("学生信息").doWrite(data);
}
10. @ContentFontStyle
设置单元格内容字体格式,和 @HeadFontStyle
属性一致。
属性 | 描述 |
---|---|
fontName | 设置字体名称 |
fontHeightInPoints | 设置字体高度 |
italic | 设置字体是否斜体 |
strikeout | 是否设置删除线 |
color | 设置字体颜色 |
typeOffset | 设置偏移量 |
underline | 设置下划线 |
charset | 设置字体编码 |
bold | 设置字体是否加粗 |
✨💎注:如果需要自定义样式,可以通过继承 AbstractCellStyleStrategy
(public abstract class AbstractCellStyleStrategy implements CellWriteHandler
)类,实现其setHeadCellStyle
和 setContentCellStyle
方法可以自定义设置表头和单元格内容样式
11. @ContentLoopMerge
修饰字段,设置合并单元格的注解。
属性 | 描述 |
---|---|
eachRow | 合并列 |
columnExtend | 合并行 |
12. @OnceAbsoluteMerge
修饰类,用于指定位置的单元格合并。
属性 | 描述 |
---|---|
firstRowIndex | 第一行下标 |
lastRowIndex | 最后一行下标 |
firstColumnIndex | 第一列下标 |
lastColumnIndex | 最后一列下标 |
13. @DateTimeFormat
日期转换,value参照 java.text.SimpleDateFormat
14. @NumberFormat
数字转换,value参照java.text.DecimalFormat
15. 日期、数字导出方式
实际导出Excel会要求导出格式,整理以下4种方式。
15.1 注解@ContentStyle
15.2 注解@DateTimeFormat、@DateTimeFormat
15.3 自定义Converter
自定义Converter,重写convertToExcelData,实现转换;实体类成员变量的注解上增加 @ExcelProterty(value = “工作时间”,converter = DateConverter.class)
15.4 自定义CellWriteHandler
自定义CellWriteHandler,重写afterCellDispose,可以自定义内容样式、值等,自由度更高。构建Excel的时候,注册到处理类
EasyExcel.write(fileName, Student.class)
.registerWriteHandler(new SimpleColumnWidthStyleStrategy(15)) // 设置列宽策略
.registerWriteHandler(new CustomCellWriteHandler()) // 自定义样式
.sheet(“学生信息”)
.doWrite(data);
参考文章:📖Easyexcel(注解使用)
https://blog.csdn.net/q1468051413/article/details/139348375
https://blog.csdn.net/weiwosuoai/article/details/141338421
https://cloud.tencent.com/developer/article/1671316
📖 Easyexcel