EasyExcel
注意点
不支持的功能
单个文件的并发写入、读取
读取图片
宏
csv读取
出现 NoSuchMethodException, ClassNotFoundException, NoClassDefFoundError
jar包冲突
读Excel
easyExcel.xlsx文件
地区
2000年人口数(万人)
2000年比重
安徽省
5986
4.73%
北京市
1382
1.09%
福建省
3471
2.74%
甘肃省
2562
2.02%
广东省
8642
6.83%
广西壮族自治区
4489
3.55%
贵州省
3525
2.78%
海南省
787
0.62%
河北省
6744
5.33%
河南省
9256
7.31%
黑龙江省
3689
2.91%
湖北省
6028
4.76%
湖南省
6440
5.09%
吉林省
2728
2.16%
江苏省
7438
5.88%
江西省
4140
3.27%
辽宁省
4238
3.35%
难以确定常住地
105
0.08%
内蒙古自治区
2376
1.88%
宁夏回族自治区
562
0.44%
青海省
518
0.41%
山东省
9079
7.17%
山西省
3297
2.60%
陕西省
3605
2.85%
上海市
1674
1.32%
四川省
8329
6.58%
天津市
1001
0.79%
西藏自治区
262
0.21%
新疆维吾尔自治区
1925
1.52%
云南省
4288
3.39%
浙江省
4677
3.69%
中国人民解放军现役军人
250
0.20%
重庆市
3090
2.44%
对象
public class MyExcel {
private String province;
private Integer personNum;
// 接收百分比的数字
@NumberFormat("#.##")
private String percent;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public Integer getPersonNum() {
return personNum;
}
public void setPersonNum(Integer personNum) {
this.personNum = personNum;
}
public String getPercent() {
return percent;
}
public void setPercent(String percent) {
this.percent = percent;
}
}
简单的读取
创建excel的对象
由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器
直接读即可
监听器类
/**
* 监听器
* 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
*/
public class MyExcelListener extends AnalysisEventListener {
private static final Logger LOGGER = LoggerFactory.getLogger(MyExcelListener.class);
//控制存放在内存的数据的条数 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
private static final int BATCH_COUNT = 5;
//当一个临时缓存器 当存储器中数据超过BATCH_COUNT后进行释放
List list=new ArrayList();
/**
* 如果要存储到数据库 则在这里接入dao 层
*
*/
private MyDao myDao;
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*
*/
public DemoDataListener(DemoDAO demoDAO) {
this.demoDAO = demoDAO;
}
/**
* 这个每一条数据解析都会来调用
* @param myExcel
* @param analysisContext
*/
public void invoke(MyExcel myExcel, AnalysisContext analysisContext) {
System.out.println("解析到一条数据"+JSON.toJSONString(myExcel));
LOGGER.info("解析到一条数据", JSON.toJSONString(myExcel));
list.add(myExcel);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (list.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
list.clear();
}
}
/**
* 所有数据解析完成了 都会来调用
* @param analysisContext
*/
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();
LOGGER.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*
* */
private void saveData() {
LOGGER.info("{}条数据,开始存储数据库!", list.size());
demoDAO.save(list); //dao层方法 存储到数据库
LOGGER.info("存储数据库成功!");
}
}
**执行 **
String fileName="C:/Users/风筝/OneDrive/桌面/easyExcel.xlsx";
/**
* 文件路径 模板实体类 监听器
*/
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
//方法1
EasyExcel.read(fileName,MyExcel.class,new MyExcelListener()).sheet().doRead();
//方法2
ExcelReader excelReader = EasyExcel.read(fileName, MyExcel.class, new MyExcelListener()).build();
ReadSheet readSheet = EasyExcel.readSheet(0).build();
excelReader.read(readSheet);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
有个很重要的点 这里的 监听器 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
存入到持久层
/**
* 假设这个是DAO存储。
**/
public class DemoDAO {
public void save(List list) {
// mybatis,尽量别直接调用多次insert,自己写一个mapper里面新增一个方法batchInsert,所有数据一次性插入
}
}
指定列的下标或名称
/**
* 强制读取第三个 不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配
*/
@ExcelProperty(index = 0)
private String province;
/**
*
* 用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据
*
*/
@ExcelProperty("2000年人口数(万人)")
private Integer personNum;
// 接收百分