如果有问题欢迎指出
之前有用过poi做导入功能,easyExcel比poi导入效率真的高太多了,并且防止内存oom,读取速度非常快,亲测有效,直接上代码,
我的业务逻辑和各位不一样,但是模板是一样的,注意自己改正,我下面有标记
excel模板:
pom文件
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.7</version>
</dependency>
编写pojo类
//最重要的是@ExcelProperty(“单据编号”)注解对应的excel的标题,一个字都不能差,他会自动读取
@Column(name = "unit_no")
@ExcelProperty("单据编号")
private String unitNo;
@Column(name = "unit_price")
@ExcelProperty("单价")
private String unitPrice;
@Column(name = "unit")
@ExcelProperty("单位")
private String unit;
//此处省略。。。。
编写controller类
@PostMapping(value = "/outStorageExcel")
@ApiOperation("读取出库excel表")
public DeviceResponse storageService(@RequestBody MultipartFile file) {
try {
storageService.storageService(file);
} catch (Exception e) {
return new DeviceResponse(Constant.FAIL_CODE, "出库导失败");
}
return new DeviceResponse(Constant.SUCCESS_CODE, "出库导入成功");
}
编写service接口
void storageService(MultipartFile file)
编写service实现类
@Autowired
private StorageService storageService;
@Override
public void storageService(MultipartFile file) {
InputStream is = null;
try {
is = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
//1.进行读取数据,StorageRetrieval是我的pojo类,
//2.new SorageListener(storageService)这个是监听器,主要用来读取数据的,别急后面会讲
//3.特别注意的是storageService这个service,我上面有注入进去 @Autowired,切记不要new会报错
EasyExcel.read(is, StorageRetrieval.class, new SorageListener(storageService)).sheet().doRead();
}
编写SorageListener监听器
@Component
public class SorageListener extends AnalysisEventListener<pojo类> {
private static final Logger LOGGER = LoggerFactory.getLogger(SorageListener.class);
//读取数据初始化值
private static final int BATCH_COUNT = 50;
List<pojo类> list = new ArrayList<pojo类>();
private StorageService storageService;
public SorageListener() {
storageService=new StorageServiceImpl();
}
public SorageListener(StorageService storageService) {
this.storageService = storageService;
}
/**
* 这个每一条数据解析都会来调用,数据是一条一条进行解析的
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(StorageRetrieval data, AnalysisContext context) {
list.add(data);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (list.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
list.clear();
}
}
/**
* 所有excel表中数据解析完成了 都会来调用这个
* 解释为什么要保存数据?
*初始化读取数量为50,表中信息已经加载完毕,,假设excel表中最后只剩下30行遗留数据,所以为了防止存在遗留数据 尽量判断下集合是否为空,不为空在进行存储(这是我的逻辑需要判断,如果不需要也可进行不判断)
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
if(list.size()==0){
return;
}
saveData();
LOGGER.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
public void saveData() {
storageService.save(list); //代码实现类层保存数据
LOGGER.info("存储数据库成功!");
}
}
postman进行测试
很详细啦喜欢记得点个赞哦吼吼吼