后台网站开发文档,建站软件可以不通过网络建设吗,文件管理系统wordpress,html5 微网站开发结合 Spring AOP (面向切面编程) 和 Alibaba EasyExcel。
EasyExcel 是阿里巴巴开源的工具#xff0c;相比 Apache POI#xff0c;它极其节省内存#xff08;基于流式读写#xff09;#xff0c;并且对注解支持非常好。1. 引入依赖 (Maven)
在 pom.xml 中引入 EasyExcel 和…结合Spring AOP (面向切面编程)和Alibaba EasyExcel。EasyExcel 是阿里巴巴开源的工具相比 Apache POI它极其节省内存基于流式读写并且对注解支持非常好。1. 引入依赖 (Maven)在pom.xml中引入 EasyExcel 和 Spring Boot AOP。dependencies!-- Web 依赖 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- AOP 依赖 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId/dependency!-- Alibaba EasyExcel (高性能 Excel 工具) --dependencygroupIdcom.alibaba/groupIdartifactIdeasyexcel/artifactIdversion3.3.2/version!-- 请检查最新版本 --/dependency!-- Lombok (简化代码可选) --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependencies2. 定义自定义注解ResponseExcel创建一个注解用于标记 Controller 方法告诉 AOP 这个接口需要导出 Excel。packagecom.example.demo.annotation;importjava.lang.annotation.*;Target(ElementType.METHOD)// 作用于方法Retention(RetentionPolicy.RUNTIME)// 运行时有效DocumentedpublicinterfaceResponseExcel{// 导出的文件名StringfileName()defaultdata;// Sheet 名称StringsheetName()defaultSheet1;// 导出的实体类类型用于解析表头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;DataAllArgsConstructorNoArgsConstructorpublicclassUserExcelVO{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;AspectComponentpublicclassExcelExportAspect{/** * 环绕通知 * 拦截被 ResponseExcel 注解的方法 */Around(annotation(responseExcel))publicObjectaround(ProceedingJoinPointpoint,ResponseExcelresponseExcel)throwsThrowable{// 1. 执行目标方法获取返回的数据列表Objectresultpoint.proceed();// 如果返回的不是 List或者为空则直接返回原结果或抛出异常视业务而定if(!(resultinstanceofList)){returnresult;}List?dataList(List?)result;// 2. 获取 Response 对象ServletRequestAttributesrequestAttributes(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if(requestAttributesnull){returnnull;}HttpServletResponseresponserequestAttributes.getResponse();if(responsenull){returnnull;}// 3. 设置响应头信息response.setContentType(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet);response.setCharacterEncoding(utf-8);// 防止中文乱码StringfileNameURLEncoder.encode(responseExcel.fileName(),UTF-8).replaceAll(\\,%20);response.setHeader(Content-Disposition,attachment;filename*utf-8fileName.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;RestControllerRequestMapping(/excel)publicclassExcelController{/** * 导出用户列表 * 访问地址: http://localhost:8080/excel/export */GetMapping(/export)ResponseExcel(fileName用户列表,sheetName用户数据,clazzUserExcelVO.class)publicListUserExcelVOexportUsers(){// 模拟查询数据库获取数据ListUserExcelVOlistnewArrayList();list.add(newUserExcelVO(1L,张三,20,newDate(),123));list.add(newUserExcelVO(2L,李四,25,newDate(),456));list.add(newUserExcelVO(3L,王五,30,newDate(),789));// 直接返回 List 数据即可AOP 会自动接管导出逻辑returnlist;}}注意事项返回类型被注解的方法必须返回ListT类型的数据否则 AOP 可能会抛错或忽略。JDK 8 兼容性EasyExcel 和上述代码完全兼容 JDK 8。文件名乱码代码中使用了URLEncoder.encode(..., UTF-8)并设置了filename*utf-8这是标准的 HTTP 协议写法能兼容绝大多数现代浏览器下载中文文件不乱码。大数据量导出上面的代码是一次性把 List 加载到内存。如果你要导出 10 万行以上的数据建议修改 Controller 和 AOP 逻辑使其支持分页查询写入doWrite可以多次调用或者直接在 AOP 中接受Collection。EasyExcel 本身是流式的只要你不把百万条数据一次性new出来放到 List 里它就不会 OOM。前端联调前端调用此接口时需要将responseType设置为blob否则下载的文件可能是乱码字符串。