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"));// 查询当前用户idLong 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> {@Overridepublic 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"));// 查询当前用户idLong 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);