SpringBoot Mybatis-plus整合EasyExcel批量导入Ex···

发布时间:2025-05-16 17:28:18 作者:益华网络 来源:undefined 浏览量(2) 点赞(2)
摘要:一、前言 今天小编带大家一起整合一下easyExcel​,之所以用这个,是因为easyExcel​性能比较好,不会报OOM! 市面上常见的导入导出Excel分为三种:hutooleasyExcelpoihutool和easyExcel​都是对poi​的封装,使用起来更加方便! 二、导入依赖 小编这里是3.0.X版本

一、前言

今天小编带大家一起整合一下easyExcel​,之所以用这个,是因为easyExcel​性能比较好,不会报OOM!

市面上常见的导入导出Excel分为三种:

hutooleasyExcelpoi

hutool和easyExcel​都是对poi​的封装,使用起来更加方便!

二、导入依赖

小编这里是3.0.X版本的,版本不同可能导致部分有出入,如果大家版本是3.1.X,可以去官方文档看看有不一样的!

官方文档:https://easyexcel.opensource.alibaba.com/

com.alibaba

easyexcel

3.0.5

</dependency>

三、实体类

这里可以自带的转换器:

@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")LocalDateTimeStringConverter

或者自定义转化器:实现:implements Converter<T>。

具体文档:官方文档:https://easyexcel.opensource.alibaba.com/docs/3.0.x/quickstart/read#%E6%97%A5%E6%9C%9F%E6%95%B0%E5%AD%97%E6%88%96%E8%80%85%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%BC%E5%BC%8F%E8%BD%AC%E6%8D%A2

@ExcelProperty参数注意:

这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配。

用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据。

/**

* @author wangzhenjun

* @date 2022/12/2 15:52

*/

@Data

public class Test {

@TableId

private Integer id;

@ExcelProperty(index = 0)

private String name;

@ExcelProperty(index = 1)

private Integer age;

@ExcelProperty(index = 2,converter = LocalDateTimeStringConverter.class)

private LocalDateTime time;

}

四、编写监听器

注意点:这个监听器一定不要是单例的,被spring管理默认为单例,如果要使用​@Component​,一定要加上:@Scope("prototype")​,这样在创建完后spring不会进行管理,每次都会是新bean!不加​@Component​在导入时要进行new ImportDataListener!小编这里不想new了直接这样写!!如果不想这样,可以使用构造器set进行使用!BATCH_COUNT​:数据阈值,超过了就会清理list,在之前可以进行保存到数据库中,方便内存回收,防治OOM!这里保存到数据库中一般使用​批量保存,不要解析到一行就去保存数据库中,这样数据量大会给数据库增加IO,导致挂掉!这里小编使用ServiceImpl的saveBatch()方法,也可以自己写一下,像小编这样写,会出现循环依赖,加上@Lazy就行!

/**

* @author wangzhenjun

* @date 2022/12/2 15:38

*/

@Slf4j

@Component

// 每次bean都是新的,不要单例

@Scope("prototype")

public class ImportDataListener implements ReadListener {

@Autowired

@Lazy

private TestService testService;

/**

* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收

*/

private static final int BATCH_COUNT = 100;

/**

* 缓存的数据

*/

private List importExcelDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

/**

* 这个每一条数据解析都会来调用

*

* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}

* @param context

*/

@Override

public void invoke(Test data, AnalysisContext context) {

log.info("解析到一条数据:{}", JSON.toJSONString(data));

importExcelDataList.add(data);

// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM

if (importExcelDataList.size() >= BATCH_COUNT) {

saveData();

// 存储完成清理 list

importExcelDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

}

}

/**

* 所有数据解析完成了 都会来调用

*

* @param context

*/

@Override

public void doAfterAllAnalysed(AnalysisContext context) {

// 这里也要保存数据,确保最后遗留的数据也存储到数据库

saveData();

log.info("所有数据解析完成!");

}

/**

* 加上存储数据库

*/

private void saveData() {

log.info("{}条数据,开始存储数据库!", importExcelDataList.size());

testService.saveBatch(importExcelDataList);

log.info("存储数据库成功!");

}

}

五、Controller

/**

* @author wangzhenjun

* @date 2022/10/26 16:51

*/

@Slf4j

@RestController

@RequestMapping("/test")

public class TestController {

@Autowired

private TestService testService;

@PostMapping("/import")

public Result importExcel(@RequestBody MultipartFile multipartFile){

testService.importExcel(multipartFile);

return Result.success("ok");

}

}

六、Service

/**

* @author wangzhenjun

* @date 2022/10/26 16:55

*/

public interface TestService extends IService {

void importExcel(MultipartFile multipartFile);

}

七、ServiceImpl

/**

* @author wangzhenjun

* @date 2022/10/26 16:56

*/

@Service

public class TestServiceImpl extends ServiceImpl implements TestService{

@Autowired

private ImportDataListener importDataListener;

@SneakyThrows

@Override

public void importExcel(MultipartFile multipartFile) {

InputStream inputStream = multipartFile.getInputStream();

// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭

EasyExcel.read(inputStream, Test.class, importDataListener).sheet().doRead();

}

}

八、Mapper

/**

* @author wangzhenjun

* @date 2022/10/26 17:07

*/

public interface TestDbMapper extends BaseMapper{

}

九、测试

准备Excel数据:

postman上传:

控制台打印:

数据库查看:

完美搞定!!

十、总结

这样就完成了easyExcel批量导入Excel到数据库,还是有很多要注意的点:

自定义转换器监听器不要单例保存数据库采用批量版本差距

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!