基于EasyExcel实现动态表头导出
在众多Excel数据导入导出的应用场景中,对Excel表头进行动态处理已成为一种常见需求。这种动态表头的处理方式,不仅需要灵活适应不同数据结构的变化,还要确保在导入和导出过程中保持数据的准确性和完整性。为了应对这一挑战,我们选择了EasyExcel作为解决方案,它为我们提供了高效而强大的工具来实现动态表头的导入和导出功能。通过这种高端的技术手段,我们能够更加轻松地应对各种复杂的数据处理需求,为业务的发展提供了更加稳健和可靠的支持。
Maven引入pom
本次SpringBoot的版本为2.2.4.RELEASE
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.2.1</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<!-- hutool -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
动态表头导出
设置导出类
/**
* 测试demo实体类
*
* @author 端木超群
* @date 2023/9/28
*/
@Data
public class DemoExcel {
@ExcelProperty( "姓名")
private String name;
@ExcelProperty( "年龄")
private String age;
@ExcelProperty( "性别")
private String sex;
@ExcelProperty( "分数")
private String score;
}
编写动态表头导出的方法
/**
* 动态Excel导出,先sourceList转换成List<targetClass>,再导出
*
* @param response response
* @param fileName 文件名
* @param sheetName sheetName
* @param headRow 动态表头
* @param sourceList 原数据List
* @param targetClass 目标对象Class
*/
public static void exportDynamicExcel(HttpServletResponse response, String fileName ,String sheetName,List<?> sourceList,Class<?> targetClass,List<String> headRow) throws Exception {
if (StrUtil.isBlank(fileName)) {
//当前日期
fileName = DateUtils.format(new Date(),"yyyy-MM-dd");
}
// 转换赋值
List targetList = new ArrayList<>(sourceList.size());
for (Object source : sourceList) {
Object target = targetClass.newInstance();
BeanUtils.copyProperties(source, target);
targetList.add(target);
}
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, CHARACTER_ENCODING) + ".xlsx");
// 设置动态表头对象
List<List<String>> head = new ArrayList<>();
// 获取对象属性
Field[] fields = targetClass.getDeclaredFields();
// 设置对应表头转换属性名列表
List<String> headPropertyList = new ArrayList<>();
// 列表设置列头
headRow.forEach(item -> {
List<String> list = new ArrayList<>();
list.add(item);
head.add(list);
// 遍历属性,获取注解值
for (Field field : fields) {
// 对ExcelProperty属性注解进行设置
if (field.isAnnotationPresent(ExcelProperty.class)) {
ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);
// 获取注解值
String annotationValue = annotation.value()[0];
String name = field.getName();
// 判断转换表头名为属性名
if(annotationValue.equals(item)){
headPropertyList.add(name);
}
}
}
});
// 构造数据列表
List<List<Object>> excelData = new ArrayList<>();
for (Object obj : sourceList) {
List<Object> row = new ArrayList<>();
for (String field : headPropertyList) {
try {
// 使用反射获取对象属性值
Field declaredField = obj.getClass().getDeclaredField(field);
declaredField.setAccessible(true);
Object value = declaredField.get(obj);
// 转换为字符串,如果为null则填充空字符串
row.add(value != null ? value.toString() : "");
} catch (NoSuchFieldException | IllegalAccessException e) {
// 或者进行异常处理,比如记录日志
e.printStackTrace();
}
}
excelData.add(row);
}
EasyExcel.write(response.getOutputStream()).head(head).registerConverter(new LongStringConverter()).sheet(sheetName).doWrite(excelData);
}
使用Api接口测试
@GetMapping("exportDynamicExcel")
@ApiOperation("动态表头导出")
public void exportDynamicExcel( HttpServletResponse response) throws Exception {
List<String> headRow = Lists.newArrayList();
headRow.add("姓名");
headRow.add("年龄");
// headRow.add("性别");
// headRow.add("分数");
List<Demo> dataList = Lists.newArrayList();
Demo demo1 = new Demo();
demo1.setAge("18");
demo1.setName("张三");
demo1.setSex("男");
Demo demo2 = new Demo();
demo2.setAge("18");
demo2.setName("李四");
demo2.setSex("男");
Demo demo3 = new Demo();
demo3.setSex("女");
demo3.setName("王五");
demo3.setAge("22");
dataList.add(demo1);
dataList.add(demo2);
dataList.add(demo3);
ExcelUtils.exportDynamicExcel(response, null,"sheet1",dataList,DemoExcel.class,headRow);
}
以上代码,你可以自己传参,我这里为了方面所以写死了。