需求1:能够导出1个Excel文件,能够导入一个Excel文件;
需求2:导出的文件,能实现第1行,第123列的合并单元格:也就是会写注册处理器;知道sheet和cell是什么;
需求3:能实现合并的单元格设置单元格宽高,背景颜色,内容居中,字体大小;
需求4:能控制从任意行开始写入,并让要输出的字段居中;
需求5:导出能实现从任意行开始读入;
导出Excel文件
1<!-- EasyExcel 核心依赖 --> 2<dependency> 3 <groupId>com.alibaba</groupId> 4 <artifactId>easyexcel</artifactId> 5 <version>3.3.4</version> 6</dependency> 7
1// 用 @Data 简化 getter/setter(需引入 lombok 依赖,也可手动写) 2@Data 3@NoArgsConstructor 4@AllArgsConstructor 5// 表头居中 + 内容居中(核心注解) 6@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER) 7@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER) 8public class UserData { 9 10 // @ExcelProperty 注解指定 Excel 列名 11 @ExcelProperty("用户ID") 12 private Long id; 13 14 @ExcelProperty("姓名") 15 private String name; 16 17 @ExcelProperty("年龄") 18 private Integer age; 19} 20
1@RestController 2public class ExcelExportController { 3 @PostMapping("/excelExport") 4 public void excelExport() throws IOException { 5 // 1.获取当前时间,作文件名拼接使用 6 String formattedNow = getFormattedNow(); 7 8 // 2. 指定生成的 Excel 文件路径和名称 9 String filePath = "C:\\Users\\59742\\Desktop\\IdeaProjects\\ExcelImportExport\\excelFiles/excel_" + formattedNow + ".xlsx"; 10 11 // 3. 准备要写入的数据 12 List<UserData> dataList = new ArrayList<>(); 13 for (int i = 0; i < 5; i++) { 14 UserData user = new UserData(); 15 user.setId((long) i); 16 user.setName("用户" + i); 17 user.setAge(20 + i); 18 dataList.add(user); 19 } 20 21 // 4.写入Excel文件 22 EasyExcel.write(filePath, UserData.class) 23 .sheet("用户信息表") 24 .relativeHeadRowIndex(1) // 默认为0行,这里从第一行开始写入 25 // 有什么要对表格进行的操作,可以使用注册自定义的处理器 26 .registerWriteHandler(new MergeCellWriteHandler())//合并单元格 27 .doWrite(dataList); 28 System.out.println("Excel 文件生成成功!路径为:" + filePath); 29 } 30 31 /** 32 * 获取当前时间,格式化输出 33 * @return 34 */ 35 private static String getFormattedNow() { 36 // 获取当前时间 37 LocalDateTime now = LocalDateTime.now(); 38 // 格式化输出(推荐使用 DateTimeFormatter,取代 SimpleDateFormat) 39 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss"); 40 return now.format(formatter); 41 } 42} 43
1/** 2 * 自定义单元格合并处理器(核心) 3 * 实现 SheetWriteHandler接口,拦截单元格写入事件 4 */ 5public class MergeCellWriteHandler implements SheetWriteHandler { 6 7 @Override 8 public void afterSheetCreate(SheetWriteHandlerContext context) { 9 // 1.想操作excel表,第一步是拿到表里的sheet 10 Sheet sheet = context.getWriteSheetHolder().getSheet(); 11 // 2.拿到sheet,然后操作里面的每一个格子(CELL),然后调用合并单元格方法:addMergedRegion(),然后new一个范围性的cellRangeAddress() 12 // 在 sheet 创建后立即合并 A1:C1(第0行,列0~2) 13 sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 2)); 14 sheet.createRow(0) 15 .createCell(0) 16 .setCellValue("提示:姓名和年龄是必填的"); 17 18 // 样式设置 19 // 1.设置合并单元格的宽和高 20 sheet.setColumnWidth(0, 30 * 256); 21 sheet.setColumnWidth(1, 30 * 256); 22 sheet.setColumnWidth(2, 30 * 256); 23 sheet.getRow(0).setHeightInPoints(200); 24 25 // 设置单元格的背景颜色 26 // 1. 先创建样式对象并设置属性(必须分步,无法纯链式) 27 CellStyle style = sheet.getWorkbook().createCellStyle(); 28 style.setFillForegroundColor(IndexedColors.BRIGHT_GREEN1.getIndex()); 29 style.setFillPattern(FillPatternType.SOLID_FOREGROUND); 30 31 // 2. 设置单元格内容居中 32 style.setAlignment(HorizontalAlignment.CENTER); // 水平居中 33 style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中 34 35 // 3. 设置单元格字体大小 36 Font font = sheet.getWorkbook().createFont(); 37 font.setFontHeightInPoints((short) 32); 38 style.setFont(font); 39 40 // 4. 给单元格绑定样式 41 sheet.getRow(0).getCell(0).setCellStyle(style); 42 } 43} 44

导入Excel文件
1@RestController 2public class ImportExcelController { 3 4 @PostMapping("/excelImport") 5 public void excelImport(MultipartFile file) throws IOException { 6 7 System.out.println("开始导入"); 8 ExcelImportListener listener = new ExcelImportListener(); 9 // 核心:读取 Excel 10 EasyExcel.read(file.getInputStream(), UserData.class, listener) 11 .sheet("用户信息表") // 指定要读取的工作表 12 .headRowNumber(2) // 这里代表索引2,第3行开始读取 13 .doRead(); // 执行读取 14 15 // 获取读取到的数据并打印 16 System.out.println("最终读取到的数据:" + listener.getDataList()); 17 } 18} 19
成功读取到数据


- 每读取一行,调用invoke一次!!!!
1 2// 加Slf4j方便打印日志(也可以用System.out) 3@Slf4j 4public class ExcelImportListener extends AnalysisEventListener<UserData> { 5 6 // 存储读取到的所有数据(适合小文件,大文件建议批量处理) 7 private List<UserData> dataList = new ArrayList<>(); 8 9 /** 10 * 核心方法:每读取一行Excel数据,就会调用这个方法 11 * @param userData 一行数据对应的实体类对象 12 * @param context 读取上下文(包含sheet、行号等信息) 13 */ 14 @Override 15 public void invoke(UserData userData, AnalysisContext context) { 16 log.info("读取到第{}行数据:{}", context.readRowHolder().getRowIndex(), userData); 17 // 2. 将数据加入集合 18 dataList.add(userData); 19 } 20 21 /** 22 * 所有数据读取完成后调用的方法 23 * 适合做最终处理(比如批量入库、数据汇总) 24 */ 25 @Override 26 public void doAfterAllAnalysed(AnalysisContext context) { 27 log.info("Excel读取完成!共读取{}行有效数据", dataList.size()); 28 System.out.println("dataList = " + dataList); 29 // 这里可以写后续逻辑:比如调用service批量保存到数据库 30 // userService.batchSave(dataList); 31 } 32 33 // 提供getter方法,方便外部获取读取到的数据 34 public List<UserData> getDataList() { 35 return dataList; 36 } 37} 38
《EasyExcel的使用》 是转载文章,点击查看原文。
