时间:2025-03-06 09:26
人气:
作者:admin
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.3</version>
</dependency>
指定当前字段对应 excel 中的那一列,可以根据名字或者 Index 去匹配,当然也可以不写。
@Data
public class User {
private Integer userId;
private String name;
private String phone;
private String email;
private Date createTime;
}
@RestController
public class TestController {
@GetMapping("/test1")
public void test1(HttpServletResponse response) {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("test1", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename" + fileName + ".xls");
User user = new User();
user.setUserId(123);
user.setName("as");
user.setPhone("15213");
user.setEmail("5456");
user.setCreateTime(13213L);
EasyExcel.write(response.getOutputStream(), User.class)
.sheet("test")
.doWrite(Arrays.asList(user));
} catch (Exception e) {
e.printStackTrace();
}
}
}

默认情况下,使用类的属性名作为 Excel 的列表,当然也可以使用@ExcelProperty 注解来重新指定属性名称。
@Data
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机")
private String phone;
@ExcelProperty(value = "邮箱")
private String email;
@ExcelProperty(value = "创建时间")
private Date createTime;
}

value 在写的时候,如果指定了多个值,会自动进行合并
@Data
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = {"用户基本信息", "姓名"})
private String name;
@ExcelProperty(value = {"用户基本信息", "手机"})
private String phone;
@ExcelProperty(value = {"用户基本信息", "邮箱"})
private String email;
@ExcelProperty(value = "创建时间")
private Date createTime;
}

@ExcelProperty 注解有两个属性 index 和 order,如果不指定则按照属性在类中的排列顺序来。index 是指定该属性在 Excel 中列的下标,下标从 0 开始
@Data
public class User {
@ExcelProperty(value = "用户Id", index = 2)
private Integer userId;
@ExcelProperty(value = "姓名", index = 1)
private String name;
@ExcelProperty(value = "手机")
private String phone;
@ExcelProperty(value = "邮箱")
private String email;
@ExcelProperty(value = "创建时间")
private Date createTime;
}

@Data
public class User {
@ExcelProperty(value = "用户Id", index = 2)
private Integer userId;
@ExcelProperty(value = "姓名", index = 1)
private String name;
@ExcelProperty(value = "手机", index = 10)
private String phone;
@ExcelProperty(value = "邮箱", index = 12)
private String email;
@ExcelProperty(value = "创建时间")
private Date createTime;
}

@Data
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机", order = 11)
private String phone;
@ExcelProperty(value = "邮箱", order = 10)
private String email;
@ExcelProperty(value = "创建时间")
private Long createTime;
}

order 的默认值为 Integer.MAX_VALUE,通过效果我们可以得出结论:order 值越小,越排在前面
注意:
在读写 EXCEL 时,有时候需要我们进行数据类型转换,例如我们这里的创建时间,在实体对象中是 Long 类型,但是这样直接导出到 Excel 中不太直观。我们需要转换成 yyyy-MM-dd HH:mm:ss 格式,此时我们就可以用到转换器。
public class DateTimeConverter implements Converter<Long> {
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 支持导入的Java类型
@Override
public Class<?> supportJavaTypeKey() {
return Long.class;
}
// 支持导出的Excel类型
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
// 转换为Java
@Override
public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return null;
}
// 转换为Excel
@Override
public 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);
}
}
@Data
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机", order = 11)
private String phone;
@ExcelProperty(value = "邮箱", order = 10)
private String email;
@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)
private Long createTime;
}

/**
* Excel 性别转换器
*/
public class GenderConverter implements Converter<Integer> {
@Override
public Class<?> supportJavaTypeKey() {
return Integer.class;
}
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
@Override
public Integer convertToJavaData(ReadConverterContext<?> context) {
return GenderEnum.convert(context.getReadCellData().getStringValue()).getValue();
}
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
return new WriteCellData<>(GenderEnum.convert(context.getValue()).getDescription());
}
}
/**
* 性别枚举
*/
@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);
}
}
默认所有字段都会和 excel 去匹配,加了这个注解会忽略该字段
@Data
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机")
private String phone;
@ExcelProperty(value = "邮箱")
@ExcelIgnore
private String email;
@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)
@ExcelIgnore
private Long createTime;
}

不标注该注解时,默认类中所有成员变量都会参与读写,无论是否在成员变量上加了@ExcelProperty 的注解。标注该注解后,类中的成员变量如果没有标注 @ExcelProperty 注解将不会参与读写。
@ExcelIgnoreUnannotated
@Data
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机")
private String phone;
private String email;
private Long createTime;
}

用于设置表格列的宽度
@Data
public class User {
@ColumnWidth(200)
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机")
private String phone;
@ExcelProperty(value = "邮箱")
private String email;
@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)
private Long createTime;
}

标注在类上,指定内容行高
@Data
@ContentRowHeight(value = 50)
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机")
private String phone;
@ExcelProperty(value = "邮箱")
private String email;
@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)
private Long createTime;
}

标注在类上,指定列头行高
@Data
@HeadRowHeight(80)
@ContentRowHeight(value = 50)
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机")
private String phone;
@ExcelProperty(value = "邮箱")
private String email;
@ExcelProperty(value = "创建时间", converter = DateTimeConverter.class)
private Long createTime;
}

用于设置内容格式注解
用于设置单元格内容字体格式的注解
用于设置标题样式
用于定制标题字体格式
用于设置合并单元格的注解,作用于字段上
用于指定位置的单元格合并,作用于类上
日期转换,读取 Excel 文件时用 String 去接收 excel 日期格式的数据会调用这个注解。里面的 value 参照 java.text.SimpleDateFormat
@Data
public class User {
@ExcelProperty(value = "用户Id")
private Integer userId;
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "手机")
private String phone;
@ExcelProperty(value = "邮箱")
private String email;
@DateTimeFormat("yyyy-MM-dd")
@ExcelProperty(value = "创建时间")
private Date createTime;
}
数字转换,用 String 去接收 excel 数字格式的数据会调用这个注解。里面的 value 参照 java.text.DecimalFormat

Hutool 的 `TimedCache` 到期会自动清理吗?