news 2026/6/15 10:19:05

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/6/12 19:06:19

A7 PRE接口发布

风风kong4324324324434324243244324423444334344E324

作者头像 李华
网站建设 2026/6/9 19:47:37

GPT-SoVITS语音合成技术实现与应用指南

GPT-SoVITS语音合成技术实现与应用指南 你有没有想过&#xff0c;只需一段60秒的录音&#xff0c;就能让AI用你的声音朗读任何文字&#xff1f;无论是中英混合、日语播报&#xff0c;还是为虚拟角色配音——这一切在今天已经不再是科幻。GPT-SoVITS 正是让这种“数字分身”成为…

作者头像 李华
网站建设 2026/6/15 10:29:04

ASJ10-GQ自复式过欠压保护器,电网波动的“隐形防护盾”

唐雪阳安科瑞电气股份有限公司 上海嘉定 201801一、电网波动突袭&#xff0c;设备“躺枪”谁来救&#xff1f;你是否遇到过这些糟心事&#xff1a;车间里运行正酣的冷水机组突然停机&#xff0c;只因电网电压瞬间飙升&#xff1b;商场的空调频繁报错&#xff0c;竟是电压偏低导…

作者头像 李华
网站建设 2026/6/15 11:29:18

基于R语言森林生态系统结构、功能与稳定性分析与可视化

在生态学研究中&#xff0c;森林生态系统的结构、功能与稳定性是核心研究内容之一。R语言因其强大的统计分析和数据可视化能力&#xff0c;已成为生态学领域的重要工具。通过R语言的多种分析包&#xff0c;研究者可以对森林生态系统的结构、功能与稳定性进行系统研究。R语言的机…

作者头像 李华
网站建设 2026/6/14 8:18:57

阿尔泰科技 NET8722多功能测量仪:多类型测量、通道拓展无压力!

一、产品简介 NET8722是阿尔泰科技面向“结构测试、强度验证、健康监测”推出的16通道同步应变、桥路&#xff0c;电阻/RTD和电压信号采集仪。它在紧凑的1U半机壳内集成24-bit ADC、可编程桥激励、导线电阻补偿&#xff0c;采集端使用全功能嵌入式web接口有效保障测试前仪器的…

作者头像 李华
网站建设 2026/6/15 10:28:19

禁毒拼图 VR 互动学习软件

VR 禁毒拼图软件以拼图互动为载体&#xff0c;助力公众认识DP、学习禁毒相关知识。软件内收录多类DP图片&#xff0c;体验者点击任意一张DP图片即可进入对应拼图页面&#xff0c;将零散的DP图片碎片拼接成完整图像即完成挑战。挑战成功后&#xff0c;系统将自动跳转至该DP的专属…

作者头像 李华