文章目录
- 前言
- 一、使用步骤
- 1.添加依赖:
- 2.创建和实体类对应的用于导入导出的模板类,尽量不要直接使用实体类。
- 每个字段需添加@ExcelProperty注解,作为导入导出的识别的依据。注意value值是跟excel里的列名保持一致,不是跟数据库里的字段。
- 3.相关代码
- Cotroller类:
- Service类
- Service实现类
- dao类
- mapper.xml
- 使用到的监听器类
- 测试接口(使用的postman)
- 总结
前言
SpringBoot+EasyExcel实现导入
一、使用步骤
1.添加依赖:
代码如下(示例):
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
2.创建和实体类对应的用于导入导出的模板类,尽量不要直接使用实体类。
每个字段需添加@ExcelProperty注解,作为导入导出的识别的依据。注意value值是跟excel里的列名保持一致,不是跟数据库里的字段。
3.相关代码
Cotroller类:
/**
* 导入Excel
*/
@RequestMapping("/importExcel")
@ResponseBody
public String importExcel(@RequestParam(value = "file") MultipartFile file) throws IOException{
EasyExcel.read(file.getInputStream(), UrbanFacilityManageModel.class, new ExcelListener(urbanFacilityManageService)).sheet().doRead();
return "success";
}
Service类
/**
* 一次性存储导入的excel文件
* @param list
*/
void saveList(List<UrbanFacilityManageModel> list);
Service实现类
/**
* 存列表,excel文件
* @param list
*/
@Override
public void saveList(List<UrbanFacilityManageModel> list) {
urbanFacilityManageDao.saveList(list);
}
dao类
/**
*excel导入
*/
int saveList(List<UrbanFacilityManageModel> urbanFacilityManageModelList);
mapper.xml
<!--一次性存储导入excel-->
<insert id="saveList" parameterType="java.util.List">
insert into urban_facility_manage (facility_code,facility_type,facility_name,specs_message,charge_branch,owner_organ,curing_organ,data_sources,area_code,area_name,grid_code,geo_x,geo_y,position,audit_idea,remark,db_status)
values
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.facilityCode},
#{item.facilityType},
#{item.facilityName},
#{item.specsMessage},
#{item.chargeBranch},
#{item.ownerOrgan},
#{item.curingOrgan},
#{item.dataSources},
#{item.areaCode},
#{item.areaName},
#{item.gridCode},
#{item.geoX},
#{item.geoY},
#{item.position},
#{item.auditIdea},
#{item.remark},
#{item.dbStatus}
)
</foreach>
</insert>
使用到的监听器类
package com.topevery.pss.utils;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.topevery.pss.facility.po.UrbanFacilityManage;
import com.topevery.pss.facility.po.UrbanFacilityManageModel;
import com.topevery.pss.facility.service.UrbanFacilityManageService;
import java.util.ArrayList;
import java.util.List;
// 有个很重要的点 ExcelListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class ExcelListener extends AnalysisEventListener<UrbanFacilityManageModel> {
private List<UrbanFacilityManageModel> list = new ArrayList<>();
/**
* 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 3000;
/**
* 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
*/
private UrbanFacilityManageService urbanFacilityManageService;
/**
* 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
*/
public ExcelListener(UrbanFacilityManageService urbanFacilityManageService) {
this.urbanFacilityManageService = urbanFacilityManageService;
}
/**
* 这个每一条数据解析都会来调用
*/
@Override
public void invoke(UrbanFacilityManageModel urbanFacilityManageModel, AnalysisContext analysisContext) {
System.out.println("解析到一条数据:========================"+urbanFacilityManageModel.toString());
// 数据存储到datas,供批量处理,或后续自己业务逻辑处理。
if(ObjectUtil.isNotEmpty(urbanFacilityManageModel.getFacilityType()) && ObjectUtil.isNotEmpty(urbanFacilityManageModel.getFacilityName()) ) {
list.add(urbanFacilityManageModel);
}
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if(list.size() >= BATCH_COUNT){
saveData();
// 存储完成清理datas
list.clear();
}
}
/**
* 所有数据解析完成了 都会来调用
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
saveData();//确保所有数据都能入库
}
/**
* 加上存储数据库
*/
private void saveData() {
System.out.println("=============================="+list.size()+"条数据,开始存储到数据库");
urbanFacilityManageService.saveList(list);
}
}
测试接口(使用的postman)
excel测试文件自己提前准备多,多测几次,表格列名需要跟你配置的模板类中保持一致,包括顺序。
总结
感谢大家的观看,有什么问题大家可以指出