如何实现用自定义注解导出Excel自定义表头
其实上述功能在很多的轮子里都已经有现成的实现方法,例如阿里的 EasyExcel 等等
我这里只是举例其中实现的一种方式,外加多写一篇博文
代码设计
其实就用到了下述文件
@Excel 注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@Documented
public @interface Excel {
String name() default "";
String dictValue() default "";
}
pom.xml
POI的相关依赖
org.apache.poi
poi
5.2.2
org.apache.poi
poi-ooxml
5.2.2
// 假定的数据集
public class User {
private String id;
@Excel(name = "姓名")
private String name;
@Excel(name = "年龄")
private int age;
/**
* 性别 0-女 1-男
*/
@Excel(name = "性别", dictValue = "0=女,1=男")
private int gender;
}
// 具体实现的逻辑
public class ExcelExport {
public static void main(String[] args) throws IOException {
List users = List.of(
new User("张三", 20, 1),
new User("李四", 30, 0),
new User("王五", 40, 1)
);
// 写入文件
OutputStream outputStream = Files.newOutputStream(Paths.get("C:\\Users\\dnslin\\Downloads\\Programs\\users.xlsx"));
// 执行导出方法
ExcelExport.export(users, outputStream);
}
private static void export(List users, OutputStream outputStream) {
try (Workbook workbook = new XSSFWorkbook()) {
Sheet sheet = workbook.createSheet();
// 获取所有包含注解的字段
Field[] declaredFields = User.class.getDeclaredFields();
List collect = Arrays.stream(declaredFields)
.filter(e -> e.isAnnotationPresent(Excel.class))
.collect(Collectors.toList());
// 写入标题行
writeTitleRow(sheet, collect);
// 写入数据行
for (int i = 0; i < users.size(); i++) {
User user = users.get(i);
Row userRow = sheet.createRow(i + 1);
writeDataRow(userRow, user, collect);
}
// 写入文件
workbook.write(outputStream);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void writeDataRow(Row userRow, User user, List collect) throws IllegalAccessException {
Map> fieldDict = buildFieldDict(collect);
for (int i = 0; i < collect.size(); i++) {
Cell cell = userRow.createCell(i);
Field field = collect.get(i);
field.setAccessible(true);
Excel annotation = field.getAnnotation(Excel.class);
if (annotation.dictValue()!=null && !annotation.dictValue().isEmpty()){
String key = String.valueOf(field.get(user));
cell.setCellValue(fieldDict.get(field).get(key));
}else {
cell.setCellValue(String.valueOf(field.get(user)));
}
field.setAccessible(false);
}
}
private static Map> buildFieldDict(List collect) {
HashMap> fieldMapHashMap = new HashMap<>();
collect.forEach(e->{
Excel annotation = e.getAnnotation(Excel.class);
String dictValue = annotation.dictValue();
if (dictValue != null && !dictValue.isEmpty()) {
String[] split = dictValue.split(",");
Map dict = Arrays.stream(split)
.map(s -> s.split("="))
.collect(Collectors.toMap(e1 -> e1[0], e1 -> e1[1]));
fieldMapHashMap.put(e, dict);
}
});
return fieldMapHashMap;
}
private static void writeTitleRow(Sheet sheet, List collect) {
Row row = sheet.createRow(0);
for (int i = 0; i < collect.size(); i++) {
Cell cell = row.createCell(i);
Excel excel = collect.get(i).getAnnotation(Excel.class);
cell.setCellValue(excel.name());
}
}
此处评论已关闭