将execl导出功能进行AOP切面

背景

写了不少的项目,不少的项目中都遇到过execl导出功能。前一阵子再次写导出功能,当时突然有个想法。能不用使用aop切面,将导出功能切出来写。以后用到的话,直接加注释多好。说干就干。

引入版本

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
		 <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>
        
       

核心方法

/**
 * Description: AOP方法增强
 *
 * @author dzp
 * @version 1.0
 * @date: 2021-1-12 15:02
 * @since JDK 1.8
 */
@Component
@Aspect
@Slf4j
public class ExportAspect {
    @Pointcut("@annotation(com.example.demo.export.ExportExcel)")
    public void exportPointcut() {

    }

    /***
     * 导出不需要有返回值
     * @param point
     * @throws Throwable
     */
    @Around("exportPointcut()")
    public void doExport(ProceedingJoinPoint point) throws Throwable {
        Object o = point.proceed();
        if (o instanceof List) {
            List list = (List) o;
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method;
            method = point.getTarget().getClass().getMethod(signature.getName(), signature.getMethod().getParameterTypes());
            ExportExcel annotation = method.getAnnotation(ExportExcel.class);
            //1.获取ExportExcel注解上beanClass的值
            Class<?> aClass = annotation.beanClass();
            Object[] args = point.getArgs();
            //2.获取方法第一个参数值
            HttpServletResponse response = (HttpServletResponse) args[0];
            exportUtils(response, list, aClass);
        }

    }

    /**
     * 导出
     * @param response
     * @param list
     * @param aClass
     * @param <T>
     */
    public <T> void exportUtils(HttpServletResponse response, List<T> list, Class<T> aClass) {

        try {
            XSSFWorkbook workbook = exportExcelByAnnotation(list, aClass);

            OutputStream output = getOutputStream(response);
            //FileOutputStream output = getOutputStreamForTest();
            workbook.write(output);
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
            response.setStatus(500);
        }
    }

    /**
     * 更改response中数据
     * @param response
     * @return
     * @throws IOException
     */
    private OutputStream getOutputStream(HttpServletResponse response) throws IOException {
        response.reset(); // 清除buffer缓存
        //处理请求
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream;charset=utf-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + DateFormatUtils.format(new Date(), "yyyy-MM-dd") + ".xlsx");
        return response.getOutputStream();
    }

    /**
     * 导出
     * @param list
     * @param relClass
     * @param <T>
     * @return
     * @throws Exception
     */
    public <T> XSSFWorkbook exportExcelByAnnotation(List<T> list, Class<T> relClass) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//日期类型数据导出格式化

        XSSFWorkbook book = new XSSFWorkbook();
        Sheet sheet = book.createSheet();

        List<FieldEntity> fieldEntityList = Lists.newArrayList();
        Field[] fields = relClass.getDeclaredFields();
        Row row = sheet.createRow(0);
        int titleNum = 0;
        //利用反射获取对象属性
        for (Field field : fields) {
            FieldEntity fieldEntity = new FieldEntity();
            //获取标注了注解的字段
            ExportFiled fieldAnnotation = field.getAnnotation(ExportFiled.class);
            //如果没有标注注解,直接跳过循环
            if (fieldAnnotation == null) {
                continue;
            }
            field.setAccessible(true);
            fieldEntity.setFieldName(field.getName());
            fieldEntity.setNumber(fieldAnnotation.number());
            //获取字段标注的title
            String titleName = fieldAnnotation.name();
            Cell cell = row.createCell(titleNum);
            cell.setCellType(CellType.STRING);
            cell.setCellValue(titleName);
            fieldEntityList.add(fieldEntity);
            titleNum++;
            field.setAccessible(false);
        }
        //按number排序
        List<FieldEntity> fieldEntitiesAfterSorted = fieldEntityList.stream().sorted(Comparator.comparing(FieldEntity::getNumber)).collect(Collectors.toList());
        List<String> fieldList = fieldEntitiesAfterSorted.stream().map(FieldEntity::getFieldName).collect(Collectors.toList());
        for (int i = 1; i <= list.size(); i++) {
            T obj = list.get(i - 1);
            Row dataRow = sheet.createRow(i);
            for (int j = 0; j < fieldList.size(); j++) {
                String fieldName = fieldList.get(j);
                Field field = obj.getClass().getDeclaredField(fieldName);
                Cell dataCell = dataRow.createCell(j);
                dataCell.setCellType(CellType.STRING);
                field.setAccessible(true);
                if (field.get(obj) != null) {
                    Object o = field.getType().toString();
                    if (("java.util.Date").equals(field.getType().getTypeName())) {
                        dataCell.setCellValue(sdf.format(field.get(obj)));
                    } else {
                        dataCell.setCellValue(String.valueOf(field.get(obj)));
                    }
                } else {
                    dataCell.setCellValue("");
                }
                field.setAccessible(false);
            }
        }
        return book;
    }

    @Data
    private  class FieldEntity {
        private String number;
        private String FieldName;
    }
}

自定义注解

标记哪一个接口需要导出
/**
 * Description: 导出Excel
 *
 * @author dzp
 * @version 1.0
 * @date: 2021-1-12 15:02
 * @since JDK 1.8
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExportExcel {
    /**
     *  需要导出的实体class
     */
    Class<?> beanClass();
}

例子如下:

@GetMapping("/get")
    @ExportExcel(beanClass =User.class )
    public List<User> select(HttpServletResponse response){
        return userService.selectList();
    }
标记需要导出那些字段和顺序

/**
 * Description: 导出字段注解
 *
 * @author dzp
 * @version 1.0
 * @date: 2021-1-12 15:02
 * @since JDK 1.8
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExportFiled {
    /**
     * 导出字段顺序
     */
    String number();

    /**
     * 导出字段名称
     */
    String name();
}

例子如下:

public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键ID
     */
    @ExportFiled(number = "0", name ="id" )
    private Long id;
    /**
     * 姓名
     */
    @ExportFiled(number = "1", name ="姓名" )
    private String name;
    /**
     * 年龄
     */
    @ExportFiled(number = "2", name ="年龄" )
    private Integer age;
    /**
     * 邮箱
     */
    @ExportFiled(number = "3", name ="邮箱" )
    private String email;

    /***
     *性别
     */
    @ExportFiled(number = "4", name ="性别" )
    private UserSexEnum sex;

    /**
     * TableLogic注解表示逻辑删除 在执行删除的时候 会把删除方法调用成修改的方法
     */
    @TableLogic
    private Integer deleted;

    @ExportFiled(number = "5", name ="时间" )
    private Date time;
}

调用案例

controller层

 
@GetMapping("/get")
    @ExportExcel(beanClass =User.class )
    public List<User> select(HttpServletResponse response){
        return userService.selectList();
    }

成功截图

在这里插入图片描述

学习java群

java交流群:868794080

源码下载链接

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一枚开发小咸鱼

原创不宜,请作者喝杯咖啡吧。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值