使用EasyExcel读取Excel文件遇到的小问题

没有读取到内容的问题

excel内容

具体代码

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;

import java.io.File;
import java.util.List;

public class TestEasyExcel {
    public static void main(String[] args) {
        List<User> users = EasyExcel.read(new File("/Users/xxx/testjars/Users.xlsx"))
                .head(User.class)
                .sheet()
                .doReadSync();
        System.out.println(users); // [User{username='null', pwd='null'}, User{username='null', pwd='null'}]
    }

    public static class User {
        @ExcelProperty("用户名")
        private String username;
        @ExcelProperty("密码")
        private String pwd;

        public String getUsername() {
            return username;
        }

        public User setUsername(String username) {
            this.username = username;
            return this;
        }

        public String getPwd() {
            return pwd;
        }

        public User setPwd(String pwd) {
            this.pwd = pwd;
            return this;
        }

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", pwd='" + pwd + '\'' +
                    '}';
        }
    }
}

如果属性的set()方法返回值不是void,就不会调用set()方法,就读取不到数据。

原因分析

easyexcel 库内部使用了 cglib 中的 BeanMap 来设置属性

  1. 具体类为 com.alibaba.excel.read.listener.ModelBuildEventListener 的 buildUserModel() 方法。
  2. 进入 BeanMap 的 create() 方法
  3. 进入 DefaultGeneratorStrategy 的 generate() 方法
  4. 继续进入 net.sf.cglib.beans.BeanMap.Generator 的 generateClass() 方法
  5. 进入 BeanMapEmitter 构造器,继续 net.sf.cglib.core.ReflectUtils 的 getBeanSetters() 方法
  6. 最终调用 java.beans.PropertyDescriptor 的 getWriteMethod() 方法来获取 set() 方法,这里判断了方法返回值必须为 void 类型

跳过前面几行的实现

excel 内容为

跳过第一行,将第二行当作属性头,具体代码为

public static void main(String[] args) {
        List<User> users = EasyExcel.read(new File("/Users/xxx/testjars/Users.xlsx"))
                .head(User.class)
                .sheet()
                .headRowNumber(2) // 默认值为1
                .doReadSync();
        System.out.println(users);
    }

疑惑

easyexcel 读取 excel 文件会自动去除单元格内容的前后空格,原理暂时未知。

posted @ 2024-03-14 21:14  strongmore  阅读(26)  评论(0编辑  收藏  举报