使用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 来设置属性
- 具体类为 com.alibaba.excel.read.listener.ModelBuildEventListener 的 buildUserModel() 方法。
- 进入 BeanMap 的 create() 方法
- 进入 DefaultGeneratorStrategy 的 generate() 方法
- 继续进入 net.sf.cglib.beans.BeanMap.Generator 的 generateClass() 方法
- 进入 BeanMapEmitter 构造器,继续 net.sf.cglib.core.ReflectUtils 的 getBeanSetters() 方法
- 最终调用 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 文件会自动去除单元格内容的前后空格,原理暂时未知。