EasyExcel的使用

需求1:能够导出1个Excel文件,能够导入一个Excel文件;

需求2:导出的文件,能实现第1行,第123列的合并单元格:也就是会写注册处理器;知道sheet和cell是什么;

需求3:能实现合并的单元格设置单元格宽高,背景颜色,内容居中,字体大小;

需求4:能控制从任意行开始写入,并让要输出的字段居中;

需求5:导出能实现从任意行开始读入;

导出Excel文件

java 复制代码
<!-- EasyExcel 核心依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.4</version>
</dependency>
java 复制代码
// 用 @Data 简化 getter/setter(需引入 lombok 依赖,也可手动写)
@Data
@NoArgsConstructor
@AllArgsConstructor
// 表头居中 + 内容居中(核心注解)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
public class UserData {

    // @ExcelProperty 注解指定 Excel 列名
    @ExcelProperty("用户ID")
    private Long id;

    @ExcelProperty("姓名")
    private String name;

    @ExcelProperty("年龄")
    private Integer age;
}
java 复制代码
@RestController
public class ExcelExportController {
    @PostMapping("/excelExport")
    public void excelExport() throws IOException {
        // 1.获取当前时间,作文件名拼接使用
        String formattedNow = getFormattedNow();

        // 2. 指定生成的 Excel 文件路径和名称
        String filePath = "C:\\Users\\59742\\Desktop\\IdeaProjects\\ExcelImportExport\\excelFiles/excel_" + formattedNow + ".xlsx";

        // 3. 准备要写入的数据
        List<UserData> dataList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            UserData user = new UserData();
            user.setId((long) i);
            user.setName("用户" + i);
            user.setAge(20 + i);
            dataList.add(user);
        }

        // 4.写入Excel文件
        EasyExcel.write(filePath, UserData.class)
                .sheet("用户信息表")
                .relativeHeadRowIndex(1) // 默认为0行,这里从第一行开始写入
                // 有什么要对表格进行的操作,可以使用注册自定义的处理器
                .registerWriteHandler(new MergeCellWriteHandler())//合并单元格
                .doWrite(dataList);
        System.out.println("Excel 文件生成成功!路径为:" + filePath);
    }

    /**
     * 获取当前时间,格式化输出
     * @return
     */
    private static String getFormattedNow() {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 格式化输出(推荐使用 DateTimeFormatter,取代 SimpleDateFormat)
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss");
        return now.format(formatter);
    }
}
java 复制代码
/**
 * 自定义单元格合并处理器(核心)
 * 实现 SheetWriteHandler接口,拦截单元格写入事件
 */
public class MergeCellWriteHandler implements SheetWriteHandler {

    @Override
    public void afterSheetCreate(SheetWriteHandlerContext context) {
        // 1.想操作excel表,第一步是拿到表里的sheet
        Sheet sheet = context.getWriteSheetHolder().getSheet();
        // 2.拿到sheet,然后操作里面的每一个格子(CELL),然后调用合并单元格方法:addMergedRegion(),然后new一个范围性的cellRangeAddress()
        // 在 sheet 创建后立即合并 A1:C1(第0行,列0~2)
        sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 2));
        sheet.createRow(0)
                .createCell(0)
                .setCellValue("提示:姓名和年龄是必填的");

        // 样式设置
        // 1.设置合并单元格的宽和高
        sheet.setColumnWidth(0, 30 * 256);
        sheet.setColumnWidth(1, 30 * 256);
        sheet.setColumnWidth(2, 30 * 256);
        sheet.getRow(0).setHeightInPoints(200);

        // 设置单元格的背景颜色
        // 1. 先创建样式对象并设置属性(必须分步,无法纯链式)
        CellStyle style = sheet.getWorkbook().createCellStyle();
        style.setFillForegroundColor(IndexedColors.BRIGHT_GREEN1.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);

        // 2. 设置单元格内容居中
        style.setAlignment(HorizontalAlignment.CENTER); // 水平居中
        style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中

        // 3. 设置单元格字体大小
        Font font = sheet.getWorkbook().createFont();
        font.setFontHeightInPoints((short) 32);
        style.setFont(font);

        // 4. 给单元格绑定样式
        sheet.getRow(0).getCell(0).setCellStyle(style);
    }
}

导入Excel文件

java 复制代码
@RestController
public class ImportExcelController {

    @PostMapping("/excelImport")
    public void excelImport(MultipartFile file) throws IOException {

        System.out.println("开始导入");
        ExcelImportListener listener = new ExcelImportListener();
        // 核心:读取 Excel
        EasyExcel.read(file.getInputStream(), UserData.class, listener)
                .sheet("用户信息表")  // 指定要读取的工作表
                .headRowNumber(2) // 这里代表索引2,第3行开始读取
                .doRead(); // 执行读取

        // 获取读取到的数据并打印
        System.out.println("最终读取到的数据:" + listener.getDataList());
    }
}

成功读取到数据

  • 每读取一行,调用invoke一次!!!!
java 复制代码
// 加Slf4j方便打印日志(也可以用System.out)
@Slf4j
public class ExcelImportListener extends AnalysisEventListener<UserData> {

    // 存储读取到的所有数据(适合小文件,大文件建议批量处理)
    private List<UserData> dataList = new ArrayList<>();

    /**
     * 核心方法:每读取一行Excel数据,就会调用这个方法
     * @param userData 一行数据对应的实体类对象
     * @param context 读取上下文(包含sheet、行号等信息)
     */
    @Override
    public void invoke(UserData userData, AnalysisContext context) {
        log.info("读取到第{}行数据:{}", context.readRowHolder().getRowIndex(), userData);
        // 2. 将数据加入集合
        dataList.add(userData);
    }

    /**
     * 所有数据读取完成后调用的方法
     * 适合做最终处理(比如批量入库、数据汇总)
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        log.info("Excel读取完成!共读取{}行有效数据", dataList.size());
        System.out.println("dataList = " + dataList);
        // 这里可以写后续逻辑:比如调用service批量保存到数据库
        // userService.batchSave(dataList);
    }

    // 提供getter方法,方便外部获取读取到的数据
    public List<UserData> getDataList() {
        return dataList;
    }
}
相关推荐
小宋10212 小时前
Java 项目结构 vs Python 项目结构:如何快速搭一个可跑项目
java·开发语言·python
JavaGuide2 小时前
一款悄然崛起的国产规则引擎,让业务编排效率提升 10 倍!
java·spring boot
吃虫子的人2 小时前
记录使用Arthas修改线上源码重新加载的一次过程
java·arthas
figo10tf3 小时前
Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
java·spring boot·后端
zhangyi_viva3 小时前
Spring Boot(七):Swagger 接口文档
java·spring boot·后端
橙露3 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot
小程故事多_803 小时前
Agent Infra核心技术解析:Sandbox sandbox技术原理、选型逻辑与主流方案全景
java·开发语言·人工智能·aigc
冰暮流星3 小时前
sql语言之分组语句group by
java·数据库·sql