定义注解@Excel、@PrintExcelLog。
- @Excel用于设置excel的标题和默认值
- @PrintExcelLog用于标识是否打印excel导出日志
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE}) @Component public @interface Excel { String title() default ""; String value() default ""; } ```j ```java
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface PrintExcelLog { boolean value() default true; }
|
其中@Retention是用来定义生命周期,我们这里是运行时;
@Target表示作用目标,有以下8种:
ElementType.TYPE: 可以应用于类、接口、枚举(enum)。
ElementType.FIELD: 可以应用于字段(包括枚举常量)。
ElementType.METHOD: 可以应用于方法。
ElementType.PARAMETER: 可以应用于方法的参数。
ElementType.CONSTRUCTOR: 可以应用于构造方法。
ElementType.LOCAL_VARIABLE: 可以应用于局部变量。
ElementType.ANNOTATION_TYPE: 可以应用于注解类型。
ElementType.PACKAGE: 可以应用于包。
创建实体类
创建一个用户类和用户性别枚举,并加上@Excel注解指定excel的标题和默认值
@Data public class User { private String id; @Excel(title = "姓名") private String name; @Excel(title = "年龄") private int age;
@Excel(title = "性别", value = "未知") private int gender; public User(String name, int age, int gender) { this.name = name; this.age = age; this.gender = gender; } }
|
@Getter public enum Gender { MALE(1, "男"), FEMALE(0, "女"), UNKNOWN(2, "未知") ; private final int code; private final String description; Gender(int code, String description) { this.code = code; this.description = description; } public static String getDescriptionByCode(int code) { for (Gender gender : Gender.values()) { if (code == gender.code) { return gender.description; } } throw new RuntimeException("编码不存在!"); } }
|
创建工具类
创建excel导出工具类,这里我们使用的是XssWorkbook这个工具类,通过反射获取注解的title值之后设置给excel的cellValue。并且对于性别我们需要把0、1转换成男、女,默认未知。
@Component public class ExcelExportUtil { @PrintExcelLog public void exportUserData(List<User> userList, OutputStream outputStream) { try (Workbook workbook = new XSSFWorkbook()) { Sheet sheet = workbook.createSheet(); Row row = sheet.createRow(0); Field[] declaredFields = User.class.getDeclaredFields(); int columnIndex = 0; for (Field field : declaredFields) { if (field.isAnnotationPresent(Excel.class)) { String title = field.getAnnotation(Excel.class).title(); Cell cell = row.createCell(columnIndex++); cell.setCellValue(title); } } for (int i = 0; i < userList.size(); i++) { Row userRow = sheet.createRow(i + 1); writeRowData(userRow, userList.get(i)); } workbook.write(outputStream); } catch (IOException | IllegalAccessException e) { throw new RuntimeException(e); } } private static void writeRowData(Row userRow, User user) throws IllegalAccessException { Field[] fields = User.class.getDeclaredFields(); int columnIndex = 0; for (Field field : fields) { if (field.isAnnotationPresent(Excel.class)) { field.setAccessible(true); Cell cell = userRow.createCell(columnIndex++); String value = field.getAnnotation(Excel.class).value(); if (StringUtils.hasLength(value)) { String description = Gender.getDescriptionByCode(user.getGender()); cell.setCellValue(description); } else { cell.setCellValue(String.valueOf(field.get(user))); } field.setAccessible(false); } } } }
|
实现AOP
对方法exportUserData()进行aop,获取它的参数值及注解信息,打印相关日志。
@Slf4j @Aspect @Component public class GenderAspect { @Pointcut("execution(* com.xxl.job.admin.annotationdemo.util.ExcelExportUtil.exportUserData(..))") public void setGenderValue() { } @Around("setGenderValue()") public Object doSetGenderValue(ProceedingJoinPoint point) { List<?> userList = new ArrayList<>(); Object[] args = point.getArgs(); if (args != null && args.length > 0 && args[0] instanceof List) { userList = (List<?>) args[0]; } MethodSignature signature = (MethodSignature) point.getSignature(); Method method = signature.getMethod(); PrintExcelLog annotation = method.getAnnotation(PrintExcelLog.class); if (Objects.nonNull(annotation) && annotation.value()) { userList.forEach(user -> log.info("正在进行Excel导出,用户信息为:{}, 当前时间:{}", user, LocalDateTime.now())); } try { return point.proceed(); } catch (Throwable e) { e.printStackTrace(); } return null; } }
|
测试
@RestController @RequestMapping("/test") public class test { @Autowired private ExcelExportUtil excelExportUtil; @GetMapping("/userDataExport") public void userDataExport() throws IOException { List<User> users = List.of( new User("张三", 20, 1), new User("李四", 30, 0), new User("王五", 40, 1) ); OutputStream outputStream = Files.newOutputStream(Paths.get("F:\\Edge\\springcloud-hrm-master\\xxl-job\\xxl-job-admin\\target\\users.xlsx")); excelExportUtil.exportUserData(users, outputStream); } }
|
最终效果