easyexcel是alibaba开发简单导出未excel的工具。使用的情况还是比较多的。
文章目录
- 依赖导入
- 写Excel
- 快速入门
- 对象设置
- @ExcelProperty设置列属性
- @ExcelIgnore 忽视
- 列宽、行高
- 格式转换
- 时间格式化
- 数字格式化
- 自定义格式化
- 合并单元格
- 其他更加个性化需求
- 动态表头以及其宽高设置
- 读excel
依赖导入
使用一个工具第一步肯定是导入,pom导入下面依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.1</version>
</dependency>
写Excel
快速入门
一般在controller进行
需要HttpServletResponse且返回值为null。
@GetMapping("_export")
public void exportUsers(Query query, HttpServletResponse response) throws IOException {
// 导出文件名
String fileName = "短信记录.xlsx";
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 查询当前用户id
Long userId = SecurityUtils.getUser().getUserId();
// 查询数据
List<Record> page = service.lambdaQuery()
.page(query.getPage()).getRecords();
// 写入数据
EasyExcel.write(response.getOutputStream(), Record.class).sheet("sheet标题")
.doWrite(page);
}
对象设置
入门的输出,我们会发现所有属性都输出了,且是按照属性名作为列名,这一般不是我们所需要的。
所以自定义的设置就很需要了。设置是通过在实体类上写注解来设置的。
@ExcelProperty设置列属性
-
value
列名称,改属性。
也可以复杂头进行输出,如{“主标题”, “标题1”},{“主标题”, “标题2”},这样设置。
那么样式就会是差不多下面这样
-
index
设置改属性在列的索引,默认-1,按照java类属性的顺序进行。从0开始。
如果填不满的也不会顺序递增,如index 设置了0,1,3那么第3列(索引2)会为空. -
order
定义列的排序顺序。优先级:索引>顺序>默认排序 -
converter
自定义转换器,这个后面在放大的讲。
@ExcelIgnore 忽视
设置后将不在输出该属性。
列宽、行高
可以放到放到类设置通用的列高,也可以在属性上设置这个属性的列宽。
-1为自动
- ColumnWidth列宽
- ContentRowHeight 列高
- HeadRowHeight头高
格式转换
时间格式化
@DateTimeFormat(“yyyy年MM月dd日HH时mm分ss秒”)
数字格式化
@NumberFormat
- style
用于设置字段格式的样式模式。可以通过NumberFormat.Style枚举,默认 NumberFormat.Style.DEFAULT
style枚举- DEFAULT 注释类型的默认格式:通常是“数字”,但货币类型可能是“货币
- NUMBER 当前区域设置的通用数字格式。
- PERCENT 当前区域设置的百分比格式。
- CURRENCY 当前区域设置的货币格式。
- pattern
用于设置字段格式的自定义模式。例如 #, ###.##。
自定义格式化
使用ExcelProperty的converter 属性,属性值为自定义转换器
自定义转换器类,需要继承Converter 泛型T为对于的java属性类型
对于写重写下面这一个就能用了
WriteCellData<?> convertToExcelData(Boolean value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception
如:我需要转换一个boolean类型,true则输出成功false失败
public class BooleanConverter implements Converter<Boolean> {
@Override
public WriteCellData<?> convertToExcelData(Boolean value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {
System.out.println(value);
return value ? new WriteCellData<>("成功") : new WriteCellData<>("失败");
}
}
合并单元格
- 属性
这一列 每隔2行 合并单元格
@ContentLoopMerge(eachRow = 2) - 类
将第6-7行的2-3列合并成一个单元格
@OnceAbsoluteMerge(firstRowIndex = 5, lastRowIndex = 6, firstColumnIndex = 1, lastColumnIndex = 2)
其他更加个性化需求
参考官方文档,我感觉其他的用到的很少,到时候翻一下就可以了
如果有用到会在下面继续更新
动态表头以及其宽高设置
需求,表头的列数量不确定,且需要设置表头的宽度为20.
我这里是一个每天的计数统计,依据用户输入的时间间隔生成列。
这里直接给代码了,里面有注释比较容易看。
// 导出文件名
String fileName = "短信统计.xlsx";
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 查询当前用户id
Long userId = SecurityUtils.getUserId();
// 查询数据
LocalDate start = query.getStartTime().toLocalDate();
LocalDate end = query.getEndTime().toLocalDate();
ColumnsResult<CountRecordBO> result = null;
if (StrUtil.equals(type, "0")) {
result = service.countRecordByDay(start, end, query.getPageNum(), query.getPageSize());
} else if (StrUtil.equals(type, "1")) {
result = service.countRecordByMonth(start, end, query.getPageNum(), query.getPageSize());
} else {
throw new IllegalArgumentException("type参数错误");
}
// 生成表头
List<List<String>> header = new ArrayList<>();
List<String> head0 = new ArrayList<>(1);
head0.add("手机号");
List<String> head1 = new ArrayList<>(1);
head1.add("总数");
header.add(head0);
header.add(head1);
result.getColumns().forEach(i -> {
List<String> head = new ArrayList<>(1);
head.add(i);
header.add(head);
});
// 生成数据
List<List<String>> data = result.getData().stream().map(count -> {
List<String> columns = new ArrayList<>();
columns.add(count.getPhone());
columns.add(count.getCount().toString());
columns.addAll(count.getList().stream().map(Object::toString).collect(Collectors.toList()));
return columns;
}).collect(Collectors.toList());
// 写入数据
EasyExcel.write(response.getOutputStream())
// 设置宽度
.registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
.head(header)
.sheet("短信记录")
.doWrite(data);