如何实现用自定义注解导出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());
        }
    }
最后修改:2023 年 10 月 05 日
如果觉得我的文章对你有用,请随意赞赏