栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用EasyExcel将本地excel数据读取后导入mysql数据库中

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用EasyExcel将本地excel数据读取后导入mysql数据库中

EasyExcel 是做什么的?

首先看下EasyExcel解释:
EasyExcel是阿里巴巴开源的一个excel处理框架,是一个基于Java的简单、省内存的读写Excel的开源项目。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

开源地址:
github地址:https://github.com/alibaba/easyexcel

	光看代码我还是有点懵懵,到小破站搜了相关视频,狂神的一个视频直接解释得一清二楚。几乎直接照着他说的做就好了,当然了要根据自己的实际情况进行适当改动。

背景:我做的一个小项目需要把excel表中的数据导入到数据库中,然而有些数据列中还包含了很多数组对象,而这里面的内容是要当成一个一个字段分别储存到数据库里的,因为人工或者excel都不太现实。所以就去了解了一下这个框架的使用。

本篇文章只记录EasyExcel的读(read)

总的步骤来说就是:

  1. 创建excel对应的实体对象Dao类;
  2. 监听器:由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器(根据自己储存的excel位置或者读取需要将监听器配置成能够读取到excel表的样子);
  3. 根据需要选择是否对读取到的数据进行二次处理,然后通过mapper层存入数据库;

表格如下:

注意:直接从实体类对应的参数列开始读取,不要有任何表头

此excel对应的实体类:
使用 @ExcelProperty 注解来说明对应的excel列

"电阻测试数据"对应的实体类
使用 @ExcelProperty 注解来说明对应的excel列

如果数据库结构和excel对应的实体类有出入(比如读取到的数组数据还需要经过处理拆分成多个字段),那么还需要额外建立一个与数据库对应的实体类。
数据库创建的表:

pom.xml 配置:

		 
            com.alibaba
            easyexcel
            2.2.6
        
        
        
            com.alibaba
            fastjson
            1.2.75
        

Controller层

@RestController
@Controller
@RequestMapping("/product/charging_station")
public class ChargingStationController {

    @Resource
    CharingStationService charingStationService;
    
    @PostMapping()
    public void saveExcel(){
        charingStationService.saveData();
    	}
    }

Service层

@Service
public class CharingStationServiceImpl implements CharingStationService {

    @Resource
    ChargingStationMapper chargingStationMapper;
    @Resource
    ExcelUtil excelUtil;
    @Resource
    ChargingStationAcceptancevalueMapper chargingStationAcceptancevalueMapper;

    
    @Override
    public void saveData() {
        excelUtil.excelRead();
    }

监听器入口
配置好文件地址、文件名、excel对应的实体类

@Component
public class ExcelUtil {

    @Autowired
    private CharingStationServiceImpl charingStationServiceImpl;


    

    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelUtil.class);
    //文件位置
    String PATH = "D:\excelTest\";


    public void excelRead() {

        // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
        String fileName = PATH + "充电桩验收测试数据.xlsx";
        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, ExcelModel.class, new DemoDataListener(charingStationServiceImpl)).sheet().doRead();

    }
}

监听器具体实现

@Component
public class DemoDataListener extends AnalysisEventListener {

    @Resource
    ChargingStationMapper charingStationResistanceReportMapper;
    @Resource
    CharingStationServiceImpl charingStationServiceImpl;

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);

    
    public DemoDataListener(CharingStationServiceImpl serviceImpl) {
        this.charingStationServiceImpl = serviceImpl;
    }
    //无参构造
    public DemoDataListener() {
    }
    
    @Override
    public void invoke(ExcelModel excelModel, AnalysisContext context) {
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(excelModel));
        //最终要保存到数据库的数据
        ChargingStationModel reportModelData = new ChargingStationModel();

        String productModelNum = "";
        String itemNo = "";
        Double groundResistance = 0.0;
        Double insulationResistance = 0.0;
        Byte type = 1;
        Integer singlePilePower = 0;
        
        String str1 = excelModel.getInfoData();
        JSONArray array1 = JSON.parseArray(str1);
        //如果不为空,就解析[{},{},{},{}]类型的数组对象并获取值
        if (!ObjectUtils.isEmpty(array1)) {
            for (Object obj : array1) {
                JSONObject jsonObject = (JSONObject) obj;
                ChargingStationInfoDataExcelModel infoExcelModel = JSONObject.parseObject(String.valueOf((JSONObject) obj), ChargingStationInfoDataExcelModel.class);
                type = infoExcelModel.getType();
                singlePilePower = infoExcelModel.getSinglePilePower();
            }
        }
        
        String str = excelModel.getResistanceData();
        JSONArray array = JSON.parseArray(str);
        //电阻不为空,就解析[{},{},{},{}]类型的数组对象并获取值
        if (!ObjectUtils.isEmpty(array)) {
            for (Object obj : array) {
                JSONObject jsonObject = (JSONObject) obj;
                ChargingStationResistanceDataExcelModel reportModel = JSONObject.parseObject(String.valueOf((JSONObject) obj), ChargingStationResistanceDataExcelModel.class);
                productModelNum = reportModel.getProductModelNum();
                itemNo = reportModel.getItemNo();
                groundResistance = reportModel.getGroundResistance();
                insulationResistance = reportModel.getInsulationResistance();
                //插入数据到数据库
                reportModelData = new ChargingStationModel(excelModel.getReportNo(), excelModel.getModelNum(), productModelNum, itemNo, groundResistance, insulationResistance, type, singlePilePower,
                        excelModel.getOutputVoltageControlErrorOfCharger(), excelModel.getOutputCurrentControlErrorOfCharger(), excelModel.getActiveStopChargeTestOutputCurrentStopRate(), excelModel.getPassiveStopChargeTestOutputCurrentStopRate(),
                        excelModel.getChargerOutputCurrentAdjustmentTimeAbove20A(), excelModel.getChargerOutputCurrentAdjustmentTimeUnder20A(), excelModel.getImpulseCurrent());
                saveData(reportModelData);
            }
        }
    }

    
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        
        LOGGER.info("所有数据解析完成!");
    }

    
    private void saveData(ChargingStationModel resistanceReportModel) {
        //调用mapper插入数据库
        charingStationServiceImpl.save(resistanceReportModel);
    }


}

知识点:

  1. 转化Json,解析[{},{},{},{}]类型的数组对象获取里面的单个内容
JSONObject jsonObject = (JSONObject) obj;
ChargingStationResistanceDataExcelModel reportModel = JSONObject.parseObject(String.valueOf((JSONObject) obj);
  1. 使用注解@Component将DemoDataListener和监听器入口交给Spring来管
@Component
public class DemoDataListener extends AnalysisEventListener {
...
}
  1. 配置好要读取的文件位置
//文件位置
    String PATH = "D:\excelTest\";

    public void excelRead() {

        // 有个很重要的点 DemoDataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去
        String fileName = PATH + "充电桩验收测试数据.xlsx";

        // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, ExcelModel.class, new DemoDataListener(charingStationServiceImpl)).sheet().doRead();

    }

一开始运行的时候报了几个错:

  1. mapper报空指针。两个可能,查了一下发现一是因为没有将DemoDataListener和监听器入口类注入Spring,导致无法找到bean,需要使用@Component。二是没有通过Spring mvc的模型调用, 只是套用了开源框架中的@Test注解运行。
  2. 读取文件失败,因为没有把文件头那栏删掉。

此文只是小菜鸡的一点点记录,有错望各位大佬指正!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/389753.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号