Use EasyExcel in springboot to realize Excel import and export

1. Introduction of EasyExcel

EasyExcel is a simple and easy-to-use Excel file manipulation tool based on Java. It provides a rich API, which can easily read, write and manipulate Excel files, and supports common Excel operations, such as reading/writing cell data, merging cells, setting styles, processing large amounts of data, etc. The main reason why EasyExcel can greatly reduce the memory usage is that it does not load all the file data into the memory at one time when parsing Excel, but reads the data line by line from the disk and parses them one by one.

1. Read Excel file

Use EasyExcel to read the contents of Excel files and convert them into Java objects, or process them by row. For example:

// 读取 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. Write to Excel file

EasyExcel provides a convenient API to write data into Excel files. For example:

// 写入 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. Set the style and operate the cell

EasyExcel allows you to set cell styles, merge cells, set headers, etc. For example:

// 设置表头
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. Large amount of data processing

EasyExcel provides some features to process Excel files with large amount of data, such as using sliding window to limit memory usage, using callback interface to process each row of data, etc. These features can help you efficiently process large Excel files without causing memory leaks. For example:

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


2. Complete example (export and import user table):

1. Introduce dependencies in pom.xml

    <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.3.2</version>
    </dependency>

2. Create and export entity classes and table headers

**
 * 用户 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;

}

① The @ExcelProperty (opens new window) annotation on each field declares the name of the Excel Head
② The value of each field is the data value of its corresponding Excel Row row
③ The converter attribute of the @ExcelProperty annotation is a DictConvert converter , through which status = 1 is converted into an "enabled" column, status = 0 is converted into a "disabled" column, and the annotation @DictFormat (opens new window) is the type of the corresponding dictionary data.
More "Comments in EasyExcel"

3. ExcelUtils class writing and reading

public class ExcelUtils {
    
    

    /**
     * 将列表以 Excel 响应给前端
     *
     * @param response 响应
     * @param filename 文件名
     * @param sheetName Excel sheet 名
     * @param head Excel head 头
     * @param data 数据列表哦
     * @param <T> 泛型,保证 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 class implementation

    @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. Front-end import implementation

insert image description here

Guess you like

Origin blog.csdn.net/weixin_44727769/article/details/131090435