当前位置: 首页 > news >正文

Java实战之自定义注解(以excel导出为案例)

  一、注解的作用

        在java中,注解其实就是一个标识,他可以标注类、方法、字段。然后我们可以通过反射判断该类、方法、字段上面有没有该注解,并同时可以获取注解设置的值。在我们的项目中,往往会和aop联合使用,去做一些日志打印或者容器初始化工作等等。

二、接下来直接进入实战

1、首先定义两个注解@Excel、@PrintExcelLog。

@Excel用于设置excel的标题和默认值

@PrintExcelLog用于标识是否打印excel导出日志

/*** 用于设置excel的标题和默认值*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Component
public @interface Excel {String title() default "";String value() default "";
}
/*** 用于标识是否打印excel导出日志*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PrintExcelLog {boolean value() default true;}

其中@Retention是用来定义生命周期,我们这里是运行时;

@Target表示作用目标,有以下8种:

  1. ElementType.TYPE: 可以应用于类、接口、枚举(enum)。

  2. ElementType.FIELD: 可以应用于字段(包括枚举常量)。

  3. ElementType.METHOD: 可以应用于方法。

  4. ElementType.PARAMETER: 可以应用于方法的参数。

  5. ElementType.CONSTRUCTOR: 可以应用于构造方法。

  6. ElementType.LOCAL_VARIABLE: 可以应用于局部变量。

  7. ElementType.ANNOTATION_TYPE: 可以应用于注解类型。

  8. ElementType.PACKAGE: 可以应用于包。

2、然后创建一个用户类和用户性别枚举,并加上@Excel注解指定excel的标题和默认值

/*** 用户*/
@Data
public class User {// 唯一标识private String id;@Excel(title = "姓名")private String name;@Excel(title = "年龄")private int age;/*** 性别 0-女 1-男*/@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("编码不存在!");}
}

3、创建excel导出工具类,这里我们使用的是XssWorkbook这个工具类,通过反射获取注解的title值之后设置给excel的cellValue。并且对于性别我们需要把0、1转换成男、女,默认未知。

/*** excel导出工具类*/
@Component
public class ExcelExportUtil {@PrintExcelLogpublic 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);}}}
}

4、接下来我们对方法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;}
}

5、最后创建测试类进行测试,这里就不用post方式传参了,简单new一下,注意java9才支持List.of()写法,java8的需要一个个add了或者使用其他工具类。

@RestController
@RequestMapping("/test")
public class test {@Autowiredprivate 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);}}

6、最终效果

ps:以下是我整理的java面试资料,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!

链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java知识宝典》  

http://www.dtcms.com/a/458510.html

相关文章:

  • 做网站东莞选哪家公司好制作企业网站多少钱
  • 【赵渝强老师】Docker容器的资源管理机制
  • 贸易网站建站旅游网站模板设计
  • 高端 网站有哪些炫酷的官方网站
  • 专注于响应式网站开发交换链接的作用
  • 重庆网站推广营销微信小程序项目开发
  • 【图像处理基石】如何把我的头像转换成提埃坡罗风格?
  • 黄河道网站建设公司北京所有公司名单
  • 发帖推广哪个平台好seo中心
  • Windows11恢复系统无法进入恢复环境, Windows RE(恢复环境)启用不成功如何解决
  • 2014 个人网站备案北京seo公司助力网络营销
  • 网站百度搜索第一页网页游戏排行榜电脑
  • 国庆作业day4
  • 天津网站快速备案外贸网站模板有什么用
  • 百度网站关键词wordpress菜单栏改成小写
  • 昆明网站seo诊断互联网公司排名待遇阶梯
  • Rust 中的数组和数组切片引用
  • 洛阳网站建设建站系统懒人建站
  • 模型网站大全免费wordpress drupal
  • .removeClass() 方法详解
  • 免费网站建设制作视频云南旅游网站设计
  • 加盟网官方网站微信小商城怎么开通
  • 微信小程序网站建设定制铜仁市住房和城乡建设部网站
  • 做网站如何赚钱知乎如何免费开个人网站
  • iis虚拟网站古典网站案例
  • 高水平的番禺网站建设网站的内链建设
  • 易语言建设网站点击网络网站
  • 给传销产品做网站黑龙江网站备案管理局
  • 镜像网站能否做google排名网站手机版排名seo
  • 初学者的网站建设在线电子商务网站开发