当前位置: 首页 > news >正文

2026.3.20 用EasyExcel实现excel报表的导入与导出

2026.3.20 用EasyExcel实现excel报表的导入与导出

1.在自己模块创建一个实体类

@Data public class User { /** * value表示该属性对应的表头名称, index表示该属性所处的列的位置 */ //该注解能建立Java对象与表格列之间的映射关系 @ExcelProperty(value = "编号", index = 0) private Integer id; @ExcelProperty(value = "姓名", index = 1) private String name; @ExcelProperty(value = "电话", index = 2) private String phone; }

2.在组件扫描类中,扫描excel组件

@Configuration @ComponentScan({ "com.zeroone.star.project.components.easyexcel", }) public class UseCusComponents { }

组件源码如下,了解即可

@Component public class EasyExcelComponent { /** * 定义每个页签存储的数据量 */ private static final int MAX_COUNT_PER_SHEET = 5000; ​ /** * 导出到磁盘中 * @param path Excel 存储路径 * @param sheetName sheet名称 * @param clazz 存储的数据类型 * @param dataList 存储数据集合 * @param <T> 生成元素实体类类型 */ public <T> void export(String path, String sheetName, Class<T> clazz, List<T> dataList) { EasyExcel.write(path, clazz).sheet(sheetName).doWrite(dataList); } ​ /** * 解析Excel * @param path 解析的Excel的路径 * @param sheetName 解析的Excel的sheet名称 * @param clazz 存储的数据类型 * @param <T> 解析元素实体类类型 * @return 解析后的数据集合 */ public <T> List<T> parseExcel(String path, String sheetName, Class<T> clazz) { ExcelReadListener<T> listener = new ExcelReadListener<>(); EasyExcel.read(path, clazz, listener).sheet(sheetName).doRead(); return listener.getDataList(); } ​ /** * 导出到输出流 * @param sheetName sheet名称 * @param os 输出流 * @param clazz 导出数据类型 * @param dataList 导出的数据集 * @param <T> 生成元素实体类类型 * @throws IOException IO异常 */ public <T> void export(String sheetName, OutputStream os, Class<T> clazz, List<T> dataList) throws IOException { ExcelWriterBuilder builder = EasyExcel.write(os, clazz); ExcelWriter writer = builder.build(); //计算总页数 int sheetCount = dataList.size() / MAX_COUNT_PER_SHEET; sheetCount = dataList.size() % MAX_COUNT_PER_SHEET == 0 ? sheetCount : sheetCount + 1; //循环构建分页 for (int i = 0; i < sheetCount; i++) { //创建一个页签 WriteSheet sheet = new WriteSheet(); sheet.setSheetNo(i); sheet.setSheetName(sheetName + (i + 1)); //设置数据起始位置 int start = i * MAX_COUNT_PER_SHEET; int end = (i + 1) * MAX_COUNT_PER_SHEET; end = Math.min(end, dataList.size()); //写入数据到页签 writer.write(dataList.subList(start, end), sheet); } writer.finish(); os.close(); } ​ /** * 解析Excel * @param inputStream 解析的Excel的输入流 * @param sheetName 解析的Excel的sheet名称 * @param clazz 存储的数据类型 * @param <T> 解析元素实体类类型 * @return 解析后的数据集合 */ public <T> List<T> parseExcel(InputStream inputStream, String sheetName, Class<T> clazz) { ExcelReadListener<T> listener = new ExcelReadListener<>(); EasyExcel.read(inputStream, clazz, listener).sheet(sheetName).doRead(); return listener.getDataList(); } }

3.创建测试类

@Controller @RequestMapping("/excel") @Api(tags = "excel") public class ExcelController { //用以创建测试数据,在真实场景中,数据应从数据库中查询 private List<User> list; ​ @Resource EasyExcelComponent excel; }

1.创建测试数据

//用以声明该方法在依赖注入完成后立刻执行,能保证在运行其他方法之前list集合已被初始化 @PostConstruct public void initData() { list = new ArrayList<>(); // 测试数据 for (int i = 1; i < 11; i++) { User user = new User(); user.setId(i); user.setName("控制器用户" + i); user.setPhone("1234567890" + i); list.add(user); } }

2.导出Excel文件供用户下载

@SneakyThrows // @GetMapping(value = "export", produces = "application/octet-stream") @ApiOperation("导出Excel") public ResponseEntity<byte[]> exportExcel() { // 导出到文件流中 ByteArrayOutputStream out = new ByteArrayOutputStream(); excel.export("test", out, User.class, list); // 响应文件 HttpHeaders headers = new HttpHeaders(); String filename = "rep-" + DateTime.now().toString("yyyyMMddHHmmssS") + ".xlsx"; headers.setContentDispositionFormData("attachment", filename); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); byte[] bytes = out.toByteArray(); out.close(); return new ResponseEntity<>(bytes, headers, HttpStatus.CREATED); }

3.导入Excel供管理人员业务调用

@SneakyThrows @PostMapping("/import") @ApiOperation("导入Excel") @ResponseBody public JsonVO<String> importExcel(MultipartFile file) { // 解析Excel InputStream input = file.getInputStream(); List<User> list = excel.parseExcel(input, "test1", User.class); // 保存到数据库的业务调用,使用打印测试解析效果 if (list.size() > 0) { list.forEach(System.out::println); return JsonVO.success("导入成功"); } return JsonVO.fail("导入失败"); } }
http://www.jsqmd.com/news/512655/

相关文章:

  • AI率飙升到60%以上?这3款降AI工具专治算法升级后的高AI率
  • 未来展望: 当 AGI(通用人工智能)出现,网络安全是否会消失?
  • 设计模式:Go常用设计模式概述
  • MATLAB 2024a最新版MinGW配置避坑指南:从下载到环境变量一键搞定
  • 重塑社区体验:打造无广告干扰的第三方酷安客户端
  • 【2026 最新】一篇文章告诉你什么是Skills 同时 告别Prompt工程!用Claude Skills把AI变成你的专属打工人
  • Thonny新手必看:如何用内置工具一键安装numpy和pygame(附常见错误解决)
  • 2026年geo公司推荐:高端制造与专业服务领域GEO优化技术型伙伴深度解析 - 十大品牌推荐
  • 智慧仓储空间智能管理系统技术方案:基于三维重构与轨迹建模的全流程透明化与智能决策体系
  • 跨境电商图片翻译工具推荐:跨马翻译使用体验分享
  • 2026年有机玻璃制品优质厂家合集,选购不迷茫,亚克力真空箱/有机玻璃加工/亚克力制品,有机玻璃制品供应商有哪些 - 品牌推荐师
  • 保姆级教程:在Apollo 8.0中手把手调试FemPos平滑算法(附U型弯道仿真对比)
  • 规范设计(上):项目开发杂乱无章,如何规范?
  • 计算机毕业设计springboot遇见宠物生活馆系统设计与实现 基于SpringBoot的萌宠驿站综合服务管理平台设计与实现 SpringBoot框架下爱宠家园一站式服务平台的设计与实现
  • multiset大全
  • 判断字符大小写(isupper(char a)和(islower(char b))、转换字符大小写(toupper(char c))和(tolower(char d))
  • 工业产线信号不稳怎么破?2026五大品牌连接器与屏蔽电缆实战性能排名解析 - 速递信息
  • 避坑指南:MATLAB串口通信那些‘奇怪’的字节数与终止符问题
  • 销售客户跟进频率难把握?数字员工自动定次数,不烦客户不遗漏
  • Allpairs+Deepseek组合测试实战:5分钟搞定正交表用例生成(附常见报错解决方案)
  • 为什么有的降AI工具降完还是高?深度分析工具选择的关键指标
  • 分析2026年河北信誉好的全屋定制品牌企业,怎么收费 - myqiye
  • 保姆级教程:用PNNX将PyTorch模型一键转成NCNN(附动态输入配置)
  • Hive数据导出实战:4种方法全解析(附避坑指南)
  • 细聊2026年吕梁电气自动化学校排名,哪家值得选择 - mypinpai
  • 告别本地束缚!Open-Lovable,前端克隆网页随时随地用
  • geo公司如何选型不踩坑?2026年综合技术型服务商推荐及适配场景深度解析 - 十大品牌推荐
  • 基于颜色衰减先验的图像去雾MATLAB实现
  • 从参数解析到实战:yocs_velocity_smoother速度平滑在TurtleBot3上的完整配置流程
  • 3分钟看懂怎么选沼气双膜储气柜:重点关注这3项,不花冤枉钱