EasyExcel使用

EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。 github地址:https:///alibaba/easyexcel

语雀地址:https://www.yuque.com/easyexcel/doc/easyexcel

最新版本

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.0.5</version>
        </dependency>

简单写

1.引入pom.xml

easyexcel LoopMergeStrategy失效 使用easyexcel_User

2.创建实体类

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String name;

    /**
     * 密码
     */
    private String password;


}

3.操作

public List<User> getData() {
        List<User> lists = new ArrayList<>();
        for(int i = 0; i <= 10; i++) {
            User user = new User();
            user.setId(i + 1);
            user.setName("李四" + i);
            user.setPassword("123456");
            lists.add(user);
        }
        return lists;
    }

    @Test
    void contextLoads() {
        EasyExcel.write("账号信息.xlsx", User.class).sheet().doWrite(getData());
    }

4.运行后生成xlsx文件

easyexcel LoopMergeStrategy失效 使用easyexcel_spring_02


easyexcel LoopMergeStrategy失效 使用easyexcel_User_03

解析

EasyExcel.write表示创建一个对象
· 第一个参数:表名称;
· 第二个参数:写入表格数据类型的class对象

public class EasyExcelFactory {
    /**
     * 构建一个Excel写对象
     *
     * @return
     */
    public static ExcelWriterBuilder write() {
        return new ExcelWriterBuilder();
    }

    /**
     * 构建一个Excel写对象
     *
     * @param file 用来写出文件对象
     *            
     * @return Excel writer builder
     */
    public static ExcelWriterBuilder write(File file) {
        return write(file, null);
    }

    /**
     * 构建 Excel写对象
     *
     * @param file
     *           用来写出的文件对象
     * @param head
     *          写出的数据类型的class对象
     * @return Excel writer builder
     */
    public static ExcelWriterBuilder write(File file, Class head) {
        ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
        excelWriterBuilder.file(file);
        if (head != null) {
            excelWriterBuilder.head(head);
        }
        return excelWriterBuilder;
    }

    /**
     * 构建Excel 写对象
     *   
     * @param pathName
     *           写出的文件路径名
     * @return Excel writer builder
     */
    public static ExcelWriterBuilder write(String pathName) {
        return write(pathName, null);
    }

    /**
     * 构建excel 写对象
     *
     * @param pathName
     *            写出的文件路径名
     * @param head
     *            写出数据的数据类型的class对象
     * @return Excel writer builder
     */
    public static ExcelWriterBuilder write(String pathName, Class head) {
        ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
        excelWriterBuilder.file(pathName);
        if (head != null) {
            excelWriterBuilder.head(head);
        }
        return excelWriterBuilder;
    }

    /**
     * 构建excel写对象
     *
     * @param outputStream
     *            写出的输出流对象
     * @return Excel writer builder
     */
    public static ExcelWriterBuilder write(OutputStream outputStream) {
        return write(outputStream, null);
    }

    /**
     * 构建excel写对象
     *
     * @param outputStream
     *           写出的输出流
     * @param head
     *           写出数据的数据类型的class对象
     * @return Excel writer builder
     */
    public static ExcelWriterBuilder write(OutputStream outputStream, Class head) {
        ExcelWriterBuilder excelWriterBuilder = new ExcelWriterBuilder();
        excelWriterBuilder.file(outputStream);
        if (head != null) {
            excelWriterBuilder.head(head);
        }
        return excelWriterBuilder;
    }
}

由上可知构建write有多种形式,具体看业务需求

easyexcel LoopMergeStrategy失效 使用easyexcel_java_04


==sheet()==代表要在表格中第几页写数据,默认第0页。

easyexcel LoopMergeStrategy失效 使用easyexcel_数据类型_05

doWrite表示写出的数据,为list集合

定义表格

自定义表头及表头排序

easyexcel LoopMergeStrategy失效 使用easyexcel_java_06


easyexcel LoopMergeStrategy失效 使用easyexcel_java_07


easyexcel LoopMergeStrategy失效 使用easyexcel_User_08

easyexcel LoopMergeStrategy失效 使用easyexcel_数据类型_09


order越大约靠右

自定义表头

多数情况下需要多级表头,于是

@ExcelProperty(value = {"账户信息","账号"} ,order = 3)
    private Integer id;
    @ExcelProperty(value = {"账户信息","用户名"} ,order = 2)
    private String name;

    /**
     * 密码
     */
    @ExcelProperty(value = {"账户信息","密码"} , order = 1)
    private String password;

easyexcel LoopMergeStrategy失效 使用easyexcel_spring_10

定义长宽高以及自适应

① 定义长宽高

@HeadRowHeight(value = 35) // 表头行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 50) // 列宽
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @ExcelProperty(value = {"账户信息","账号"} ,order = 3)
    private Integer id;
    @ExcelProperty(value = {"账户信息","用户名"} ,order = 2)
    private String name;

    /**
     * 密码
     */
    @ExcelProperty(value = {"账户信息","密码"} , order = 1)
    private String password;

easyexcel LoopMergeStrategy失效 使用easyexcel_java_11


② 自定义

去掉实体类中列宽注解

@Test
    void contextLoads() {
        EasyExcel.write("账号信息.xlsx", User.class)
                // 自适应宽度,非百分百精致
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .sheet()
                .doWrite(getData());
    }

easyexcel LoopMergeStrategy失效 使用easyexcel_User_12


提供日期格式化注解

easyexcel LoopMergeStrategy失效 使用easyexcel_数据类型_13


提供忽略写入注解

easyexcel LoopMergeStrategy失效 使用easyexcel_spring_14

读操作

数据需要在规定的模板上才可读

@Test
    void readExcel() throws Exception {

        List<User> list = new ArrayList<>();

        /*
         * EasyExcel 读取 是基于SAX方式
         * 因此在解析时需要传入监听器
         */
        // 第一个参数 为 excel文件路径
        // 读取时的数据类型
        // 监听器
        EasyExcel.read("账号信息" + ExcelTypeEnum.XLSX.getValue(), User.class, new AnalysisEventListener<User>() {

            // 每读取一行就调用该方法
            @Override
            public void invoke(User data, AnalysisContext context) {
                list.add(data);
            }

            // 全部读取完成就调用该方法
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                System.out.println("读取完成");
            }
        }).sheet().doRead();

        list.forEach(System.out::println);
    }

easyexcel LoopMergeStrategy失效 使用easyexcel_intellij-idea_15

注意

实体类中有下列注解会导致读取失败

easyexcel LoopMergeStrategy失效 使用easyexcel_数据类型_16

代码解释
EasyExcel.read 该方法是用来创建ExcelReaderBuilder对象,该对象就是用来解析Excel文档

read需要传递三个参数
① 需要解析文件的路径
② 数据类型的Class类型对象,可以不传
③ 事件监听器,在之前介绍这款框架时说过,该框架是基于SAX的一种解析,加载一行数据到内存就会去解析一行,主要是为了节约内存。

invoke方法代表每解析一行就会调用一次,data数据表示解析出来一行的数据

doAfterAllAnalysed 该方法表示将所有数据解析完毕以后才会去调用该方法