springboot中使用EasyExcel实现Excel 导入导出

一、EasyExcel的介绍

EasyExcel 是一款基于 Java 的简单易用的 Excel 文件操作工具。它提供了丰富的 API,可以方便地读取、写入和操作 Excel 文件,支持常见的 Excel 操作,如读取/写入单元格数据、合并单元格、设置样式、处理大数据量等。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

1、读取 Excel 文件

使用 EasyExcel 可以读取 Excel 文件的内容并将其转化为 Java 对象,或者按行进行处理。例如:

// 读取 Excel 文件内容并转化为 Java 对象
List<User> userList = EasyExcel.read("path/to/excel.xlsx").sheet().doReadSync(User.class);

// 按行处理 Excel 文件
EasyExcel.read("path/to/excel.xlsx").sheet().doReadSync(new AnalysisEventListener<User>() {
    @Override
    public void invoke(User user, AnalysisContext context) {
        // 处理每行数据
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 处理完成后的回调
    }
});

2、写入 Excel 文件

EasyExcel 提供了方便的 API 来写入数据到 Excel 文件中。例如:

// 写入 Java 对象到 Excel 文件
EasyExcel.write("path/to/excel.xlsx").sheet().doWrite(userList);

// 写入指定数据到 Excel 文件
List<List<Object>> data = new ArrayList<>();
// 添加数据到 data 列表...
EasyExcel.write("path/to/excel.xlsx").sheet().doWrite(data);

3、设置样式和操作单元格

EasyExcel 允许你设置单元格的样式、合并单元格、设置表头等操作。例如:

// 设置表头
List<List<String>> head = new ArrayList<>();
// 添加表头数据到 head 列表...
EasyExcel.write("path/to/excel.xlsx").head(head).sheet().doWrite(data);

// 设置单元格样式
WriteCellStyle style = new WriteCellStyle();
// 设置样式属性...
WriteSheet sheet = EasyExcel.writerSheet(0).build();
sheet.setCellStyle(style);
EasyExcel.write("path/to/excel.xlsx").sheet(sheet).doWrite(data);

// 合并单元格
WriteSheet sheet = EasyExcel.writerSheet(0).build();
sheet.setAutomaticMergeHead(true); // 自动合并表头
sheet.merge(firstRow, lastRow, firstCol, lastCol); // 合并单元格
EasyExcel.write("path/to/excel.xlsx").sheet(sheet).doWrite(data);

4、大数据量处理

EasyExcel 提供了一些特性来处理大数据量的 Excel 文件,如使用滑动窗口来限制内存占用、使用回调接口来处理每行数据等。这些特性可以帮助你高效地处理大型 Excel 文件而不会导致内存溢出。例如:

// 大数据量写入
EasyExcel.write("path/to/excel.xlsx", User.class).sheet().registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).doWrite(userList);


二、完整示例(将用户表导出导入):

1、在pom.xml引入依赖

    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>easyexcelartifactId>
        <version>3.3.2version>
    dependency>

2、创建导出实体类跟表头

**
 * 用户 Excel 导出 VO
 */
@Data
public class UserExcelVO {

    @ExcelProperty("用户编号")
    private Long id;

    @ExcelProperty("用户名称")
    private String username;

    @ExcelProperty("用户昵称")
    private String nickname;

    @ExcelProperty("用户邮箱")
    private String email;

    @ExcelProperty("手机号码")
    private String mobile;

    @ExcelProperty(value = "用户性别", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.USER_SEX)
    private Integer sex;

    @ExcelProperty(value = "帐号状态", converter = DictConvert.class)
    @DictFormat(DictTypeConstants.COMMON_STATUS)
    private Integer status;

    @ExcelProperty("最后登录IP")
    private String loginIp;

    @ExcelProperty("最后登录时间")
    private LocalDateTime loginDate;

    @ExcelProperty("部门名称")
    private String deptName;

    @ExcelProperty("部门负责人")
    private String deptLeaderNickname;

}

① 每个字段上的 @ExcelProperty (opens new window)注解,声明 Excel Head 头部的名字
② 每个字段的值,就是它对应的 Excel Row 行的数据值
③ @ExcelProperty 注解的 converter 属性是 DictConvert 转换器,通过它将 status = 1 转换成“开启”列,status = 0 转换成”禁用”列,注解 @DictFormat (opens new window)为对应的字典数据的类型。
更多《EasyExcel 中的注解 》

3、ExcelUtils类 写入以及读取

public class ExcelUtils {

    /**
     * 将列表以 Excel 响应给前端
     *
     * @param response 响应
     * @param filename 文件名
     * @param sheetName Excel sheet 名
     * @param head Excel head 头
     * @param data 数据列表哦
     * @param  泛型,保证 head 和 data 类型的一致性
     * @throws IOException 写入失败的情况
     */
    public static <T> void write(HttpServletResponse response, String filename, String sheetName,
                                 Class<T> head, List<T> data) throws IOException {
        // 输出 Excel
        EasyExcel.write(response.getOutputStream(), head)
                .autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
                .sheet(sheetName).doWrite(data);
        // 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
    }
    public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
       return EasyExcel.read(file.getInputStream(), head, null)
                .autoCloseStream(false)  // 不要自动关闭,交给 Servlet 自己处理
                .doReadAllSync();
    }
 }
 

4、Controller类实现

    @GetMapping("/export")
    @Operation(summary = "导出用户")
    @OperateLog(type = EXPORT)
    public void exportUserList(@Validated UserExportReqVO reqVO,
                               HttpServletResponse response) throws IOException {
        // 获得用户列表
        List<UserDO> users = userService.getUserList(reqVO);
        UserExcelVO excelVO = UserConvert.INSTANCE.convert02(user);
        // 输出
        ExcelUtils.write(response, "用户数据.xls", "用户列表", UserExcelVO.class, excelVO );
    }
    
    @PostMapping("/import")
    @Operation(summary = "导入用户")
    @Parameters({
            @Parameter(name = "file", description = "Excel 文件", required = true),
            @Parameter(name = "updateSupport", description = "是否支持更新,默认为 false", example = "true")
    })
    public void importExcel(@RequestParam("file") MultipartFile file,
                                                      @RequestParam(value = "updateSupport", required = false, defaultValue = "false") Boolean updateSupport) throws Exception {
        List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);
    }

5、前端导入实现

springboot中使用EasyExcel实现Excel 导入导出_第1张图片

你可能感兴趣的:(springboot,excel,spring,boot,java)