news 2026/2/6 19:42:00

java实现自定义注解导出excel

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java实现自定义注解导出excel

结合Spring AOP (面向切面编程)Alibaba EasyExcel

EasyExcel 是阿里巴巴开源的工具,相比 Apache POI,它极其节省内存(基于流式读写),并且对注解支持非常好。


1. 引入依赖 (Maven)

pom.xml中引入 EasyExcel 和 Spring Boot AOP。

<dependencies><!-- Web 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- AOP 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- Alibaba EasyExcel (高性能 Excel 工具) --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version><!-- 请检查最新版本 --></dependency><!-- Lombok (简化代码,可选) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>

2. 定义自定义注解@ResponseExcel

创建一个注解,用于标记 Controller 方法,告诉 AOP 这个接口需要导出 Excel。

packagecom.example.demo.annotation;importjava.lang.annotation.*;@Target(ElementType.METHOD)// 作用于方法@Retention(RetentionPolicy.RUNTIME)// 运行时有效@Documentedpublic@interfaceResponseExcel{// 导出的文件名StringfileName()default"data";// Sheet 名称StringsheetName()default"Sheet1";// 导出的实体类类型(用于解析表头)Class<?>clazz();}

3. 定义导出实体类 (Model)

使用 EasyExcel 提供的@ExcelProperty注解来定义表头。

packagecom.example.demo.model;importcom.alibaba.excel.annotation.ExcelIgnore;importcom.alibaba.excel.annotation.ExcelProperty;importcom.alibaba.excel.annotation.write.style.ColumnWidth;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importjava.util.Date;@Data@AllArgsConstructor@NoArgsConstructorpublicclassUserExcelVO{@ExcelProperty("用户ID")@ColumnWidth(20)privateLongid;@ExcelProperty("用户名")@ColumnWidth(30)privateStringusername;@ExcelProperty("年龄")privateIntegerage;@ExcelProperty("注册时间")@ColumnWidth(30)privateDatecreateTime;@ExcelIgnore// 忽略该字段,不导出privateStringpassword;}

4. 实现 AOP 切面处理逻辑 (核心)

这是整个功能的“大脑”。它拦截带有@ResponseExcel的方法,获取返回值(数据列表),然后直接写入 HttpServletResponse 流中。

packagecom.example.demo.aspect;importcom.alibaba.excel.EasyExcel;importcom.example.demo.annotation.ResponseExcel;importorg.aspectj.lang.ProceedingJoinPoint;importorg.aspectj.lang.annotation.Around;importorg.aspectj.lang.annotation.Aspect;importorg.springframework.stereotype.Component;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjavax.servlet.http.HttpServletResponse;importjava.net.URLEncoder;importjava.util.List;@Aspect@ComponentpublicclassExcelExportAspect{/** * 环绕通知 * 拦截被 @ResponseExcel 注解的方法 */@Around("@annotation(responseExcel)")publicObjectaround(ProceedingJoinPointpoint,ResponseExcelresponseExcel)throwsThrowable{// 1. 执行目标方法,获取返回的数据列表Objectresult=point.proceed();// 如果返回的不是 List,或者为空,则直接返回原结果(或抛出异常,视业务而定)if(!(resultinstanceofList)){returnresult;}List<?>dataList=(List<?>)result;// 2. 获取 Response 对象ServletRequestAttributesrequestAttributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if(requestAttributes==null){returnnull;}HttpServletResponseresponse=requestAttributes.getResponse();if(response==null){returnnull;}// 3. 设置响应头信息response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// 防止中文乱码StringfileName=URLEncoder.encode(responseExcel.fileName(),"UTF-8").replaceAll("\\+","%20");response.setHeader("Content-Disposition","attachment;filename*=utf-8''"+fileName+".xlsx");// 4. 调用 EasyExcel 写入数据到流中try{EasyExcel.write(response.getOutputStream(),responseExcel.clazz()).sheet(responseExcel.sheetName()).doWrite(dataList);}catch(Exceptione){// 导出异常处理,比如重置 response 输出 JSON 错误信息response.reset();response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().println("{\"code\": 500, \"message\": \"导出Excel失败: "+e.getMessage()+"\"}");}// 5. 返回 null,因为数据已经写入 Response 流,不需要 Spring MVC 再处理返回值returnnull;}}

5. Controller 调用示例

现在,你只需要在 Controller 方法上加上@ResponseExcel即可实现导出,业务逻辑只需返回List

packagecom.example.demo.controller;importcom.example.demo.annotation.ResponseExcel;importcom.example.demo.model.UserExcelVO;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.ArrayList;importjava.util.Date;importjava.util.List;@RestController@RequestMapping("/excel")publicclassExcelController{/** * 导出用户列表 * 访问地址: http://localhost:8080/excel/export */@GetMapping("/export")@ResponseExcel(fileName="用户列表",sheetName="用户数据",clazz=UserExcelVO.class)publicList<UserExcelVO>exportUsers(){// 模拟查询数据库获取数据List<UserExcelVO>list=newArrayList<>();list.add(newUserExcelVO(1L,"张三",20,newDate(),"123"));list.add(newUserExcelVO(2L,"李四",25,newDate(),"456"));list.add(newUserExcelVO(3L,"王五",30,newDate(),"789"));// 直接返回 List 数据即可,AOP 会自动接管导出逻辑returnlist;}}

注意事项:

  1. 返回类型:被注解的方法必须返回List<T>类型的数据,否则 AOP 可能会抛错或忽略。
  2. JDK 8 兼容性:EasyExcel 和上述代码完全兼容 JDK 8。
  3. 文件名乱码:代码中使用了URLEncoder.encode(..., "UTF-8")并设置了filename*=utf-8'',这是标准的 HTTP 协议写法,能兼容绝大多数现代浏览器下载中文文件不乱码。
  4. 大数据量导出
    • 上面的代码是一次性把 List 加载到内存。如果你要导出 10 万行以上的数据,建议修改 Controller 和 AOP 逻辑,使其支持分页查询写入(doWrite可以多次调用),或者直接在 AOP 中接受Collection。EasyExcel 本身是流式的,只要你不把百万条数据一次性new出来放到 List 里,它就不会 OOM。
  5. 前端联调:前端调用此接口时,需要将responseType设置为blob,否则下载的文件可能是乱码字符串。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/6 12:33:56

基于Python的高考志愿报名推荐系统源码设计与文档

前言 在高考志愿填报精细化需求提升、传统填报模式存在 “数据维度单一、匹配精准度低、政策解读滞后、风险评估不足” 的痛点背景下&#xff0c;基于 Python 的高考志愿报名推荐系统构建具有重要的教育与实用价值&#xff1a;从数据处理层面&#xff0c;系统依托 Python 的 Pa…

作者头像 李华
网站建设 2026/2/4 21:24:31

飞桨PaddlePaddle入门与核心实践

飞桨PaddlePaddle入门与核心实践 在人工智能技术飞速发展的今天&#xff0c;深度学习早已不再是实验室里的神秘概念&#xff0c;而是真正走进了搜索引擎、推荐系统、语音助手、自动驾驶等我们每天都在使用的应用中。然而&#xff0c;面对TensorFlow、PyTorch、MindSpore、JAX等…

作者头像 李华
网站建设 2026/2/5 23:20:27

使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第四十讲)

这一期讲解的控件是二维码&#xff0c;二维码是一种基于矩阵排列的二维条码技术&#xff0c;它以矩阵的形式存储数据&#xff0c;与传统的条形码相比&#xff0c;二维码可以存储更多的信息&#xff0c;并且能够处理数字、字母和汉字等多种数据类型。二维码由寻像图形、定界符、…

作者头像 李华
网站建设 2026/2/4 17:11:22

热销榜单:2025年高口碑数字人推荐,解决你的选择难题!

在这个数字化时代&#xff0c;选择合适的数字人产品变得尤为重要。本文将为你盘点2025年高口碑的数字人TOP10&#xff0c;帮助你找到最值得信赖的产品。无论是功能强大还是使用便捷&#xff0c;这些精选产品都在全网热议中备受关注。了解这些产品的特性&#xff0c;让你做出明智…

作者头像 李华
网站建设 2026/2/6 18:48:39

应“双碳”考核!安科瑞通信机房能耗监测方案,让PUE管控精准落地

唐雪阳安科瑞电气股份有限公司 上海嘉定 201801当5G网络加速渗透、数据中心规模呈爆发式增长&#xff0c;通信机房作为数字经济的“核心枢纽”&#xff0c;正面临着能耗与日俱增的严峻挑战。机房内服务器、空调、UPS等设备24小时不间断运行&#xff0c;能源消耗分散且管控难度…

作者头像 李华
网站建设 2026/2/7 1:58:17

1天净流入10亿!A500ETF南方凭什么成为布局中国核心资产的优选?

近期A股市场暖风频吹&#xff0c;政策发力、新质生产力加速崛起&#xff0c;中长期布局窗口已然打开。而在众多投资工具中&#xff0c;一只中盘宽基ETF意外“出圈”。12月8日&#xff0c;A500ETF南方&#xff08;交易代码&#xff1a;159352&#xff09;单日份额激增8.19亿份&a…

作者头像 李华