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("导入失败");
     }
 }
相关推荐
Javatutouhouduan1 小时前
SpringBoot如何快速精通?
java·spring boot·mybatis·java面试·后端开发·java编程·java程序员
iPadiPhone1 小时前
破茧成蝶:从底层内核到 Java NIO/AIO 异步架构全解析
java·架构·nio
weixin_433179331 小时前
python - 正则表达式Regex
python·正则表达式
菜鸟小九1 小时前
hot100(81-90)
java·数据结构·算法
皙然2 小时前
线上问题定位与排查实战:从日志到优化的完整思路
java·jvm
Riemann~~2 小时前
ros2写一个可以修改参数的node
开发语言·python·ros2·机器人系统
郝学胜-神的一滴2 小时前
PyTorch 张量基础:零张量/一张量/指定值张量全解析
人工智能·pytorch·python
7yewh2 小时前
Dense / 全连接层 / Gemm — 综合全局特征理解与运用
网络·人工智能·python·深度学习·cnn
无巧不成书02182 小时前
Java核心技术全景解析:从白皮书到实战踩坑
java·开发语言