龙空技术网

SpringBoot+Mybatis-plus整合easyExcel导入Excel到数据库+导出

掉发的小王 374

前言:

目前小伙伴们对“resteasy上传文件”大概比较珍视,同学们都需要知道一些“resteasy上传文件”的相关内容。那么小编也在网上收集了一些对于“resteasy上传文件””的相关文章,希望同学们能喜欢,姐妹们快快来学习一下吧!

一、前言

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

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

hutooleasyExcelpoi

hutooleasyExcel都是对poi的封装,使用起来更加方便!

如果想使用poihutool导出的可以看一下小编的之前写的文章:

使用POI+hutool导入Excel并把内容添加到数据库中,直接可以用!!!_掉发的小王的博客-CSDN博客_hutool导入excel

使用POI把查询到的数据表数据导出到Excel中,一个表一个sheet.最详细!!!_掉发的小王的博客-CSDN博客

导出的话看一下这篇,下面主要以导入来展开介绍!

EasyExcel导出Excel表格到浏览器,并通过Postman测试导出Excel【入门案例】

二、导入依赖

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

官方文档

<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>

具体文档:官方文档

@ExcelProperty参数注意:

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

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

/** * @author wangzhenjun * @date 2022/12/2 15:52 */@Datapublic 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,导致挂掉!这里小编使用ServiceImplsaveBatch()方法,也可以自己写一下,像小编这样写,会出现循环依赖,加上@Lazy就行!

/** * @author wangzhenjun * @date 2022/12/2 15:38 */@Slf4j@Component// 每次bean都是新的,不要单例@Scope("prototype")public class ImportDataListener implements ReadListener<Test> {    @Autowired    @Lazy    private TestService testService;    /**     * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收     */    private static final int BATCH_COUNT = 100;    /**     * 缓存的数据     */    private List<Test> 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<Test> {    void importExcel(MultipartFile multipartFile);}
七、ServiceImpl
/** * @author wangzhenjun * @date 2022/10/26 16:56 */@Servicepublic class TestServiceImpl extends ServiceImpl<TestDbMapper, Test> 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<Test> {}
九、测试

准备Excel数据:

在这里插入图片描述

postman上传:

在这里插入图片描述

控制台打印:

在这里插入图片描述

数据库查看:

在这里插入图片描述

完美搞定!!

十、总结

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

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

如果对你有帮助,还请不要吝啬您的发财小手,你的一键三连是我写作的动力,谢谢大家哈!!

可以看下小编的微信公众号首发看,欢迎关注,一起交流哈!!

标签: #resteasy上传文件