前言

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测试文件自己提前准备多,多测几次,表格列名需要跟你配置的模板类中保持一致,包括顺序。
在这里插入图片描述

总结

感谢大家的观看,有什么问题大家可以指出

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐