springboot基于EasyExcel使用AOP封装注解统一处理导出Excel

项目中经常遇到导出excel的功能,如果每次都写导出代码是很不方便的,现在基于EasyExcel上,使用aop封装一个导出excel的注解。
1、在项目添加需要的依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.0</version>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
    <scope>provided</scope>
</dependency>

2、新建一个导出数据实的实体类,并加上EasyExcel的注解,需要定义样式什么的,这个里直接使用EasyExcel的注解进行定义样式

@Data
@AllArgsConstructor
@NoArgsConstructor
public class DemoData {
    @ExcelProperty("主键")
    private Long id;
    @ExcelProperty("名字")
    private String name;
    @ExcelProperty("生日")
    private Date birthday;
    @ExcelProperty("年龄")
    private Long age;
    @ExcelProperty("地址")
    private String address;
}

3、新建一个service,开发中这些数据是查询数据库的,现在只是简单准备数据

public interface ExcelDemoService {
    List<ExcelDemoDTO> list();
}


@Service
public class ExcelDemoServiceImpl implements ExcelDemoService{
    @Override
    public List<DemoData> list() {
        List<DemoData> list=new ArrayList<>();
        list.add(new DemoData(1L,"jack",new Date(),12L,"广州"));
        list.add(new DemoData(2L,"lonk",new Date(),15L,"北京"));
        list.add(new DemoData(3L,"kolin",new Date(),17L,"上海"));
        list.add(new DemoData(4L,"java",new Date(),11L,"南昌"));
        list.add(new DemoData(5L,"spring",new Date(),11L,"广州"));
        return list;
    }
}

4、这时我们需要新建一个注解,用来标注需要导出excel的接口

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelExport {
    Class<?> value();//目标类型
    String fileName();//文件名
    String sheetName();//表名
}

5、有了注解,我们还需要定义一个切面来处理导出的逻辑

/**
 * 定义切面
 */
@Component
@Aspect
public class ExcelExportAspect{
    @Pointcut("@annotation(com.demo.annotation.ExcelExport)")
    public void ExcelExportTarget(){}

    //定义通知
    @Around("ExcelExportTarget() && @annotation(excelParam)")
    public void doProceed(ProceedingJoinPoint joinPoint, ExcelExport excelParam) throws Throwable {
        //获取导出类型字节码对象
        Class<?> clazz = excelParam.value();
        //获取注解上设定的名字
        String sheetName = excelParam.sheetName();
        String fileName = excelParam.fileName();
        //获取参数中的输出流对象
        HttpServletResponse response=null;
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            System.out.println(arg.getClass());
            if (arg instanceof ResponseFacade || arg instanceof Response || arg instanceof HttpServletResponse) {
                response = (HttpServletResponse)arg;
            }
        }
        //执行目标方法   获取导出数据
        List data= (List)joinPoint.proceed();

        //设置响应参数
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        //执行导出
        EasyExcel.write(response.getOutputStream(), clazz).sheet(sheetName).doWrite(data);
    }

}

6、好了,这时我们已经有注解和对应的切面了,我们现在可以在需要导出excel的接口上使用这个注解实现导出excel了
*【注意】这时有两个注意点

  • 1、方法返回值必段是一个List,且对应的数据是需要导出excel的数据
  • 2、参数中必须定义HttpServletResponse
@RestController
@RequestMapping("/excel-demo")
public class ExcelDemoController {
    @Autowired
    private ExcelDemoService excelDemoService;
    
    /**
     *【注意】这时有两个注意点
     * 1、方法返回值必段是一个List,且对应的数据是需要导出excel的数据
     * 2、参数中必须定义HttpServletResponse
     */
    @ExcelExport(value = DemoData.class,fileName = "测试aop导出Excel",sheetName = "重点人员数据")
    @RequestMapping("/get-list-aop")
    public List<DemoData> getListAop(HttpServletResponse response){
        System.out.println(response.getClass());
        List<DemoData> list = excelDemoService.list();
        return list;
    }
}

7、到这里你们已经完成了代码的需要你们写了,启动项目访问这个接口
localhost:8080/excel-demo/get-list-aop
在这里插入图片描述

打开excel
在这里插入图片描述

8、优化

文件名与表名我们现在是写在接口@ExcelExport这个注解上的,按照我们平时习惯,文件名与表名应该写在这个实现上面的,下面我们一起来优化一下
8.1新建一个注解,用于在实现类上标注文件名与表名

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelInfo {
    String fileName() default "";
    String sheetName() default "";
}

8.2使用这个注解,修改刚刚那个实体类,实义文件名与表名

@Data
@AllArgsConstructor
@NoArgsConstructor
//添加注解
@ExcelInfo(fileName = "这是通过注解来定义的文件名",sheetName = "注解定义的表名")
public class DemoData {
    @ExcelProperty("主键")
    private Long id;
    @ExcelProperty("名字")
    private String name;
    @ExcelProperty("生日")
    private Date birthday;
    @ExcelProperty("年龄")
    private Long age;
    @ExcelProperty("地址")
    private String address;
}

8.3修改刚刚@ExcelExport那个注解,移除文件名与表名两个属性,修改后如下

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelExport {
    Class<?> value();
}

8.4由于指定义的文件名与表名位置发生了改变,那么我们要切面中需要修改一下获取文件名与表名的代码

/**
 * 定义切面
 */
@Component
@Aspect
public class ExcelExportAspect{
    @Pointcut("@annotation(com.demo.annotation.ExcelExport)")
    public void ExcelExportTarget(){}

    //定义通知
    @Around("ExcelExportTarget() && @annotation(excelParam)")
    public void doProceed(ProceedingJoinPoint joinPoint, ExcelExport excelParam) throws Throwable {
        //获取导出类型字节码对象
        Class<?> clazz = excelParam.value();
        //-------------------------------修改部分--------------------------------------
        //定义默认文件名与表名
        String fileName="数据导出";
        String sheetName="sheet1";
        //获取注解上设定的名字
        boolean isClassAnnotation = clazz.isAnnotationPresent(ExcelInfo.class);
        if(isClassAnnotation){
            ExcelInfo excelInfo = clazz.getAnnotation(ExcelInfo.class);
            fileName= StringUtils.isEmpty(excelInfo.fileName())?fileName:excelInfo.fileName();
            sheetName=StringUtils.isEmpty(excelInfo.sheetName())?sheetName:excelInfo.sheetName();;
        }
        //-----------------------------------------------------------------------------
        //获取参数中的输出流对象
        HttpServletResponse response=null;
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            System.out.println(arg.getClass());
            if (arg instanceof ResponseFacade || arg instanceof Response || arg instanceof HttpServletResponse) {
                response = (HttpServletResponse)arg;
            }
        }
        //执行目标方法   获取导出数据
        List data= (List)joinPoint.proceed();

        //设置响应参数
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        //执行导出
        EasyExcel.write(response.getOutputStream(), ExcelDemoDTO.class).sheet(sheetName).doWrite(data);
    }

}

8.5修改接口,移除文件名与表名

@ExcelExport(value = DemoData.class)  //这里就变得好干净了,不会有业务代码了
@RequestMapping("/get-list-aop")
public List<DemoData> getListAop(HttpServletResponse response){
    System.out.println(response.getClass());
    List<DemoData> list = excelDemoService.list();
    return list;
}

8.6重新访问
localhost:8080/excel-demo/get-list-aop

在这里插入图片描述

【注意】@ExcelExport(value = DemoData.class)这个注解是通用的,后面如果需要导出其它的数据,只需要新建一个实体类,在接口中使用这个注解即可,如:@ExcelExport(value = Student.class)

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
EasyExcel Plus提供了一些注解实现导出功能。其中,最常用的注解是`@ExcelProperty`和`@ExcelIgnore`。`@ExcelProperty`用于指定字段在Excel中的列的位置和名称,而`@ExcelIgnore`用于排除不需要导出的字段。除了这两个基本的注解EasyExcel Plus还提供了其他一些注解来增强导出功能,如`@ExcelColumnWidth`用于设置列宽,`@ExcelFontStyle`用于设置字体样式等。 以下是使用EasyExcel Plus注解进行导出的步骤: 1. 在需要导出的实体类中,使用`@ExcelProperty`注解标记需要导出的字段,并设置对应的列位置和名称。例如: ``` @ExcelProperty(index = 0, value = "姓名") private String name; ``` 2. 如果有一些字段不需要导出,可以使用`@ExcelIgnore`注解进行标记。例如: ``` @ExcelIgnore private String password; ``` 3. 如果需要设置列宽,可以使用`@ExcelColumnWidth`注解。例如: ``` @ExcelColumnWidth(20) private String name; ``` 4. 如果需要设置字体样式,可以使用`@ExcelFontStyle`注解。例如: ``` @ExcelFontStyle(fontName = "Arial", fontSize = 12, bold = true) private String name; ``` 通过以上步骤,你可以使用EasyExcel Plus的注解实现导出功能。请注意,你还需要按照EasyExcel的规范进行导出操作,例如使用`EasyExcel.write().sheet().doWrite()`来执行导出操作。 : 这是EasyExcel Plus项目的说明,提供了一些扩展功能和注解使用方法。 : 这是EasyExcel Plus的使用文档,请参考官方的代码仓库获取详细的代码示例。 : EasyExcel Plus适用于SpringBoot和SSH框架,并提供了简单的注解和模板语言来实现复杂的导出操作。 希望以上信息能够帮助到你。如果你还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值