一、简单使用
引入依赖:
这里我们可以使用最新的4.0.2
版本,也可以选择之前的稳定版本,3.1.x
以后的版本API
大致相同,新的版本也会向前兼容(3.1.x
之前的版本,部分API
可能在高版本被废弃),关于POI、JDK
版本适配问题,具体可参考官网-版本说明。
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.2</version></dependency>
下载excel文件:
@GetMapping("/download")public void excelDownload(HttpServletResponse response) throws IOException {response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");EasyExcel.write(response.getOutputStream(), Data.class).sheet("模板").doWrite(datas);String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");}
读取excel文件:
@PostMapping("/read")public void read(MultipartFile file) throws IOException {1、这只是简单演示,一般不使用 doReadSync 方法,此方法同步执行的,即它会阻塞当前线程,直到读取完整个Excel文件并返回所有数据。读取大型文件时,可能会导致程序响应变慢或阻塞。2、使用head映射字段时,该实体类上不能加 @Accessors 注解,加上此注解会字段映射不成功。3、一般会使用监听器 + doRead 方法实现excel文件的读取List<Data> datas = EasyExcel.read(file.getInputStream()).sheet().head(Data.class).doReadSync();System.out.println(datas);}
二、常用注解
1、@ExcelProperty注解
这个注解应该是最常用的注解,通常用来映射字段跟excel的列名,有以下几个属性:
名称 | 默认值 | 描述 |
---|---|---|
value | 空 | 用于匹配excel中的头,必须全匹配,如果有多行头,会匹配最后一行头 |
order | Integer.MAX_VALUE | 优先级高于value ,会根据order 的顺序来匹配实体和excel中数据的顺序 |
index | -1 | 优先级高于value 和order ,会根据index 直接指定到excel中具体的哪一列 |
converter | 自动选择 | 指定当前字段用什么转换器,默认会自动选择。写的情况下只要实现com.alibaba.excel.converters.Converter#convertToExcelData(com.alibaba.excel.converters.WriteConverterContext<T>) 方法即可 |
注意:
1、如果没有特殊的调整一般,使用value属性就够了,在读取或者导出时都能匹配或者映射为对应的列名。
2、value 跟 index 可以在导出数据的时候配合使用,value指定列名,index指定该列的顺序,例如:@ExcelProperty(value = "性别",index = 3) 代表列名为 性别,导出到第三列的位置。但是在导入时,如果设置了order属性,表示会根据指定列来匹配字段,例如上面就会将第三列匹配为性别字段,如果该列字段为空,或者字段类型不匹配就会报错,一般在读取数据时不会这么使用这个属性。3、order 属性代表按顺序匹配,比如说导出数据时,会按照字段上该属性的顺序,依次为列设置对应字段的值,比如order最小的,就匹配第一列的值,依次往后,在导出时也是一样,order最小的值,导出到第一列依次往后。
4、converter:自定义的类型转换器,该属性可以实现自定义处理类,这个功能通常用来在 Excel 数据与 Java 对象之间进行特定格式的转换,例如日期、布尔值、自定义对象等。
实现
Converter
接口
要自定义一个转换器,需要实现 EasyExcel 提供的Converter
接口。重写必要的方法
supportJavaTypeKey()
: 指定支持的 Java 数据类型。convertToExcelData()
: 将 Java 数据类型转换为 Excel 单元格数据。convertToJavaData()
: 将 Excel 单元格数据转换为 Java 数据类型EasyExcel 自带了一些常用的转换器(例如
LocalDateConverter
、IntegerConverter
等),可以直接使用而无需自定义。
例如:在姓名上加上该属性:
@ExcelProperty(value = "姓名",converter = ExcelStringConverter.class)
private String name;
实现自定义处理类:
public class ExcelStringConverter implements Converter<String> {@Overridepublic Class<?> supportJavaTypeKey() {return String.class;}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}@Overridepublic String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return cellData.getStringValue() + "导入数据进行处理!";}@Overridepublic WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return new WriteCellData<>(value + "导出数据进行处理");}}
例如实现在 Excel 中用 "是"
和 "否"
表示布尔值,而不是默认的 true/false
。
public class BooleanStringConverter implements Converter<Boolean> {@Overridepublic Class<?> supportJavaTypeKey() {return Boolean.class; // 支持的 Java 类型}@Overridepublic WriteCellData<?> convertToExcelData(Boolean value, ExcelContentProperty contentProperty) {return new WriteCellData<>(value ? "是" : "否"); // 将布尔值转为字符串}@Overridepublic Boolean convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty) {String stringValue = cellData.getStringValue();return "是".equals(stringValue); // 将字符串 "是"/"否" 转为布尔值}
}
2、@ExcelIgnore注解
- 作用范围:数据实体类的字段上;
- 注解释义:当前字段不参与excel列的匹配,即处理时忽略该字段;
在默认情况下,数据模型类中的所有字段都会参与匹配,可如果你定义的Java类中,有些字段在读写时并不需要参与进来,这时就可以给对应字段加上@ExcelIgnore
注解,具备该注解的字段会被忽略。
3、@ExcelIgnoreUnannotated注解
- 作用范围:数据模型类上;
- 注解释义:匹配列时忽略所有未使用
@ExcelProperty
注解的字段;
如果类中许多字段都不想参与excel
读写,而你又嫌挨个加@ExcelIgnore
注解麻烦,这时就可以直接在类上加一个@ExcelIgnoreUnannotated
注解,以此来忽略所有未添加@ExcelProperty
注解的字段。
4、@DateTimeFormat注解
- 作用范围:数据实体类的字段上;
- 注解释义:用
String
接收日期数据时,会根据指定格式转换日期; - 可选参数:
value
:日期数据转换为字符串的目标格式;use1904windowing
:excel日期数据默认从1900
年开始,但有些会从1904
开始;
在解析excel
文件时,如果使用String
字段接收日期数据,就会根据指定的格式转换数据,格式可以参考java.text.SimpleDateFormat
的写法,例如yyyy-MM-dd HH:mm:ss
。而在往excel
写数据时,如果Java中的字段类型为Date、LocalDate、LocalDateTime
等日期类型,则会将日期数据转换为指定的格式写入对应列。
例如:
@DateTimeFormat(value = "yyyy年MM月dd日 HH时mm分ss秒")
5、@NumberFormat注解
- 作用范围:数据实体类的字段上;
- 注解释义:用
String
接收数值数据时,会根据指定格式转换数值; - 可选参数:
value
:数值转换为字符串的目标格式;roundingMode
:数值格式化时的舍入模式,如四舍五入、向上取整等;
这个注解和前一个注解类似,只不过是用于将非整数类型的数值数据转换成给定格式,格式可以参考java.text.DecimalFormat
的写法,如#.##
。除了可以指定格式外,还可以指定舍入模式,枚举可参考java.math.RoundingMode
类。
使用方法:
-
指定数字格式
使用@NumberFormat
注解的value
属性指定数字格式。例如:#
: 表示一个数字字符(整数部分)。0
: 表示一个数字字符(小数部分,不足补零)。,
: 表示千分位分隔符。.
: 表示小数点。
-
与
@ExcelProperty
搭配使用
在数值类型字段上添加@NumberFormat
,并用@ExcelProperty
指定列名。
@ExcelProperty("销售金额")@NumberFormat("#,##0.00") // 指定数字格式,保留两位小数,带千分位private BigDecimal salesAmount;
三、常用生成注解
1、@ColumnWidth注解
- 作用范围:数据模型类上、字段上;
- 注解释义:设置列的宽度;
这个注解如果加在类上,则会对所有字段生效;如果单独加在某个字段上,则只对特定的列有效,单位是px
。
例如:
@ExcelProperty("销售金额")@ColumnWidth(200)private BigDecimal salesAmount;
2、@ContentFontStyle注解
- 作用范围:数据模型类上、字段上;
- 注解释义:用于设置单元格内容字体格式的注解;
- 可选参数:
fontName
:字体名称,如“黑体、宋体、Arial”等;fontHeightInPoints
:字体高度,以磅为单位;italic
:是否设置斜体(字体倾斜);strikeout
:是否设置删除线;color
:字体的颜色,通过RGB
值来设置;typeOffset
:偏移量,用于调整字体的位置;underline
:是否添加下划线;bold
:是否对字体加粗;charset
:设置编码格式,只能对全局生效(字段上设置无效)。
这个注解用于设置主体内容的字体样式(不包含表头),与上个注解同理,加在类上对整个excel
文件生效,加在字段上只对单列有效,可以通过该注解来设置字体风格、高度、是否斜体等属性。
@ExcelProperty(value ="日期")@DateTimeFormat(value = "yyyy年MM月dd日 HH时mm分ss秒")@ContentFontStyle(fontName = "黑体",/* 字体类型 */fontHeightInPoints = 50, /* 字体高度,以磅为单位; */italic = BooleanEnum.TRUE,/* 是否设置斜体(字体倾斜); */strikeout = BooleanEnum.TRUE,/* 是否设置删除线; */color = 14,/* 字体的颜色,通过RGB值来设置; 0 黑色 (默认)9 红色10 绿色12 蓝色13 黄色14 粉色15 青色16 白色 */typeOffset = 1,/*偏移量,用于调整字体的位置; */underline = 1,/* 是否添加下划线; */bold = BooleanEnum.TRUE/* 是否对字体加粗; */)private LocalDateTime date;
3、@ContentRowHeight注解
- 作用范围:数据模型类上;
- 注解释义:用于设置行高。
这个注解只能加在类上面,作用就是设置单元格的高度,但这里不能像Excel
那样精准设置不同行的高度,只能设置所有单元格统一的高度。
@ContentRowHeight(80)
4、@ContentStyle注解
- 作用范围:数据模型类上、字段上;
- 注解释义:用于设置内容格式;
属性名 | 类型 | 功能描述 |
horizontalAlignment | HorizontalAlignment | 设置单元格内容的水平对齐方式(如左对齐、居中、右对齐)。 |
verticalAlignment | VerticalAlignment | 设置单元格内容的垂直对齐方式(如顶部对齐、中间对齐、底部对齐)。 |
wrapped | boolean | 是否自动换行(true 开启自动换行)。 |
dataFormat | short | 设置单元格的数据格式(例如日期格式、数字格式等)。 |
fillPatternType | FillPatternType | 设置单元格的填充模式(如纯色填充、斜线填充等)。 |
fillForegroundColor | short | 设置单元格的前景色(通过颜色索引表示)。 |
fillBackgroundColor | short | 设置单元格的背景色(通过颜色索引表示)。 |
borderLeft | BorderStyle | 设置单元格左边框样式(如实线、虚线等)。 |
borderRight | BorderStyle | 设置单元格右边框样式。 |
borderTop | BorderStyle | 设置单元格顶部边框样式。 |
borderBottom | BorderStyle | 设置单元格底部边框样式。 |
leftBorderColor | short | 设置单元格左边框颜色。 |
rightBorderColor | short | 设置单元格右边框颜色。 |
topBorderColor | short | 设置单元格顶部边框颜色。 |
bottomBorderColor | short | 设置单元格底部边框颜色。 |
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER,/* 水平对齐方式,如居中、左对齐等; */verticalAlignment = VerticalAlignmentEnum.CENTER,/*垂直对齐方式,如上对齐、下对齐等;*/wrapped = BooleanEnum.TRUE, /* 设置文本是否应该换行(自动根据内容长度换行); */dataFormat = 0, /*数据格式,对应excel的内置数据格式; */fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,/*设置单元格的填充模式(如纯色填充、斜线填充等)*/fillForegroundColor = 9,/*设置单元格的前景色(通过颜色索引表示)。*/fillBackgroundColor = 12,/*设置单元格的背景色(通过颜色索引表示)。*/borderLeft = BorderStyleEnum.THICK,/*设置单元格左边框样式(如实线、虚线等)。*/borderRight = BorderStyleEnum.THICK,/*设置单元格右边框样式。*/borderTop = BorderStyleEnum.THICK,/*设置单元格顶部边框样式。*/borderBottom = BorderStyleEnum.THICK,/*设置单元格底部边框样式。*/leftBorderColor = 14,/*设置单元格左边框颜色。*/rightBorderColor = 14,/*设置单元格右边框颜色。*/topBorderColor = 14,/*设置单元格顶部边框颜色。*/bottomBorderColor = 14/*设置单元格底部边框颜色。*/)
这个注解的属性还有很多,需要的话可以自行再查阅。
5、@HeadFontStyle注解
- 作用范围:数据模型类上、字段上;
- 注解释义:用于定制标题字体格式。
这个注解的作用和可选参数,与@ContentFontStyle
注解类似,不过这个注解是针对列头(表头)有效罢了。
- 可选参数:
fontName:
字体名称,例如Arial
、宋体
等。- fontHeightInPoints:字体大小,以磅为单位.
- bold:是否加粗。
- color:字体颜色,使用 Excel 的内置颜色索引值。
6、@HeadRowHeight注解
- 作用范围:数据模型类上;
- 注解释义:用于设置标题行的行高。
此注解的作用参考@ContentRowHeight
注解,当前注解只对表头生效。
@HeadRowHeight(30) // 设置表头行高为 30pt
7、@HeadStyle注解
- 作用范围:数据模型类上
- 注解释义:用于设置标题样式。
该注解的作用和可选参数参考@
ContentStyle注解,但是当前注解只对表头生效。
8、@OnceAbsoluteMerge注解
- 作用范围:数据模型类上;
- 注解释义:用于合并指定的单元格;
- 可选参数:
firstRowIndex
:从哪行开始合并;lastRowIndex
:到哪行结束合并;firstColumnIndex
:从哪列开始合并;lastColumnIndex
:到哪列结束合并。
从这个注解提供的可选参数就能看出具体作用,这是通过单元格行、列索引的方式,指定生成excel
文件时要合并的区域。不过要注意,使用该注解只能合并一次(对应OnceAbsoluteMerge
这个合并策略类)。
@OnceAbsoluteMerge(firstRowIndex = 0, lastRowIndex = 1, firstColumnIndex = 0, lastColumnIndex = 1)
9、@ContentLoopMerge注解
- 作用范围:数据模型类的字段上;
- 注解释义:用于合并单元格;
- 可选参数:
eachRow
:指定每x
行合并为一行;columnExtend
:指定每x
列合并为一列。
该注解也是用于合并单元格的,但是可以合并多次,不过只能实现每隔n
个单元格合并,使用起来限制很大,通常也不会选择通过这种注解的形式来合并单元格,这里了解即可。