SpringBoot+Mybatis-plus整合EasyExcel批量导入Excel到数据库+导出Excel

一、前言

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

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

  • hutool
  • easyExcel
  • poi

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

二、导入依赖

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

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

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</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
publicclassTest {

@TableId
privateIntegerid;
@ExcelProperty(index=0)
privateStringname;
@ExcelProperty(index=1)
privateIntegerage;
@ExcelProperty(index=2,converter=LocalDateTimeStringConverter.class)
privateLocalDateTimetime;
}

四、编写监听器

注意点:这个监听器一定不要是单例的,被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")
publicclassImportDataListenerimplementsReadListener<Test> {

@Autowired
@Lazy
privateTestServicetestService;

/**
* 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
*/
privatestaticfinalintBATCH_COUNT=100;
/**
* 缓存的数据
*/
privateList<Test>importExcelDataList=ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);


/**
* 这个每一条数据解析都会来调用
*
* @param data one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
publicvoidinvoke(Testdata, AnalysisContextcontext) {
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
publicvoiddoAfterAllAnalysed(AnalysisContextcontext) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
log.info("所有数据解析完成!");
}

/**
* 加上存储数据库
*/
privatevoidsaveData() {
log.info("{}条数据,开始存储数据库!", importExcelDataList.size());
testService.saveBatch(importExcelDataList);
log.info("存储数据库成功!");
}
}

五、Controller

/**
* @author wangzhenjun
* @date 2022/10/26 16:51
*/
@Slf4j
@RestController
@RequestMapping("/test")
publicclassTestController {

@Autowired
privateTestServicetestService;

@PostMapping("/import")
publicResultimportExcel(@RequestBodyMultipartFilemultipartFile){
testService.importExcel(multipartFile);
returnResult.success("ok");
}
}

六、Service

/**
* @author wangzhenjun
* @date 2022/10/26 16:55
*/
publicinterfaceTestServiceextendsIService<Test> {
voidimportExcel(MultipartFilemultipartFile);
}

七、ServiceImpl

/**
* @author wangzhenjun
* @date 2022/10/26 16:56
*/
@Service
publicclassTestServiceImplextendsServiceImpl<TestDbMapper, Test>implementsTestService{

@Autowired
privateImportDataListenerimportDataListener;

@SneakyThrows
@Override
publicvoidimportExcel(MultipartFilemultipartFile) {
InputStreaminputStream=multipartFile.getInputStream();
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
EasyExcel.read(inputStream, Test.class, importDataListener).sheet().doRead();
}
}

八、Mapper

/**
* @author wangzhenjun
* @date 2022/10/26 17:07
*/
publicinterfaceTestDbMapperextendsBaseMapper<Test> {
}

九、测试

准备Excel数据:

postman上传:

控制台打印:

数据库查看:

完美搞定!!

十、总结

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

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

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/293594.html<

(0)
管理的头像管理
上一篇2025-05-20 16:43
下一篇 2025-05-20 16:45

相关推荐

  • 云服务器和云虚拟主机怎么选?云服务器和虚拟主机区别

    云服务器适合业务增长快、需弹性扩展的场景,而云虚拟主机适合预算有限、技术门槛低的小型静态网站或测试环境,二者核心区别在于资源独享性与运维复杂度,核心差异解析:从底层架构到使用体验很多人容易混淆这两者,觉得它们都是“买空间建站”,它们的底层逻辑完全不同,云服务器(ECS)就像是你租了一整栋别墅,水电网络独立,你想……

    2026-06-29
    0
  • 赣州智慧旅游招聘是真的吗?赣州旅游人才招聘信息

    中级岗位(3-5年经验)月薪范围通常在6000-10000元,这类岗位需要独立负责项目模块,如独立运营一个抖音账号,或维护一个景区小程序的功能迭代,具备成功案例的候选人议价能力较强,高级岗位(5年以上经验)月薪范围通常在10000-20000元,部分核心管理岗可达更高,这类人才需要具备战略规划能力,如制定整个景……

    2026-06-29
    0
  • 赣州智能物联网车位锁如何管理?智能车位锁管理系统多少钱

    赣州智能物联网车位锁管理的核心在于通过云端平台实现远程控锁、状态实时监控及自动计费,彻底解决传统车位“被占难管”与“找位难”的痛点,在赣州这样的城市,随着机动车保有量的持续增长,老旧小区、商业综合体以及私人固定车位的资源矛盾日益凸显,传统的机械地锁或简易遥控锁,不仅操作繁琐,更无法实现数据化管理,引入智能物联网……

    2026-06-29
    0
  • 赣州智能消防栓好用吗,智能消防栓多少钱一个

    赣州智能消防栓通过物联网技术实现实时监测与远程报警,能显著降低火灾响应时间并提升城市消防安全管理水平,是目前智慧城市建设中不可或缺的基础设施,赣州智能消防栓的核心价值与应用场景传统消防栓往往存在“看不见、摸不着、用不了”的痛点,在赣州这样地形复杂、老城区与新城区并存的区域,传统设施的管理难度极大,智能消防栓的出……

    2026-06-29
    0
  • 云服务器和物理机到底有啥区别?

    云服务器本质上是虚拟化资源池中的弹性实例,而传统物理服务器是独占的硬件实体,前者胜在弹性与运维便捷,后者强在物理隔离与性能稳定,具体选择取决于业务对成本、扩展性及安全合规的权衡,很多人初次接触服务器时,容易把“云服务器”和“传统物理服务器”混为一谈,觉得它们都是用来跑网站或存数据的盒子,这两者的底层逻辑完全不同……

    2026-06-29
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注