EasyExcel复杂excel导入

easyexcel官方都是一些简单的导入到处示例,复杂的excel文档导入,还得自己去慢慢琢磨、百度、思考、总结、学习、观察。

代码地址在文档的最后,如果你也遇到这种需求,不妨动动你的小拇指,点个关注,要是可以点个赞,那就更好咯,做人嘛,不要这么小气,不要吝啬你的赞美,哈哈。

要导入的excel格式,如下图:

第一个sheet内容:

第二个sheet内容,一对多,一个阶段对应多个任务,一个任务对应多个动作:

废话不多说,直接上代码,能看懂多少就看你自己的功力了

controller

@RestController
@RequestMapping("/sakura/easyexcel")
@Api(value = "复杂excel导入", tags = {"复杂excel导入"})
public class ProjectExcelController {@AutowiredProjectEasyExcelService projectEasyExcelService;@ApiOperation("复杂excel导入")@PostMapping(value = "/complex/upload")public CommonResult<Object> upload(@RequestParam("file") MultipartFile file){projectEasyExcelService.projectRead(file);return CommonResult.success();}
}

service

/*** 项目信息excel*/
@Transactional(rollbackFor = Exception.class)
public void projectRead(MultipartFile file) {EasyExcelListener easyExcelListener = new EasyExcelListener();ExcelReader excelReader = null;try {excelReader = EasyExcelFactory.read(file.getInputStream(), easyExcelListener).build();} catch (IOException e) {throw new YErrorException("项目信息导入出错!");}// step2. 获取各个sheet页信息List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();// step3. 获取各个Shhet页表格内容存于mapMap<Integer, List<LinkedHashMap<String, String>>> sheetInfos = new HashMap<>(sheets.size());for (ReadSheet sheet : sheets) {Integer sheetNo = sheet.getSheetNo();excelReader.read(sheet);sheetInfos.put(sheetNo, easyExcelListener.getListMap());}//保存数据到数据库saveExcelInfo(sheetInfos);
}

上面projectRead方法用到的EasyExcelListener

@Slf4j
public class EasyExcelListener extends AnalysisEventListener<Object> {// 创建list集合封装最终的数据private List<Object> list = new ArrayList<>();// sheet页索引private int sheetNo = 0;@Overridepublic void invoke(Object t, AnalysisContext context) {// 读取excle内容int currentSheetNo = context.readSheetHolder().getSheetNo();if (currentSheetNo != sheetNo) {// 如果不根据sheet页索引更新状态重新创建list,list会反复添加前面的sheet页对象值list = new ArrayList<>();sheetNo = currentSheetNo;}list.add(t);}// 读取excel表头信息@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {}// 读取完成后执行@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}/*** 将表格转化为map集合(复杂excel读取用此方法)** @return map集合*/public List<LinkedHashMap<String, String>> getListMap() {String jsonObj = JSON.toJSONString(list);return JSON.parseArray(jsonObj, LinkedHashMap.class);}}

上面projectRead中的方法

public void saveExcelInfo(Map<Integer, List<LinkedHashMap<String, String>>> sheetInfos) {for (Integer sheetNo : sheetInfos.keySet()) {List<LinkedHashMap<String, String>> maps = sheetInfos.get(sheetNo);// 不同sheet页数据处理方式不同switch (sheetNo) {case 0:saveProject(maps);break;case 1:saveTarget(maps);break;default:break;}}
}

保存第一个sheet的项目信息,并返回全局的项目id,代码很长,简化了一部分,全部代码可以看最后github的地址


public void saveProject(List<LinkedHashMap<String, String>> maps) {ProjectManage projectManage = new ProjectManage();for (LinkedHashMap<String, String> map : maps) {if (map.containsValue("项目名称")) {String projectName = map.getOrDefault("1", "");if (StringUtils.isBlank(projectName)) {throw new YWarmingException("项目名称不能为空!");}projectManage.setProjectName(projectName);}if (map.containsValue("项目编号")) {String projectCode = map.getOrDefault("4", "");projectManage.setProjectCode(projectCode);}if (map.containsValue("合同签订时间")) {String contractSignTimeStr = map.getOrDefault("1", "");if (StringUtils.isNotBlank(contractSignTimeStr)) {Date contractSignDate = DateUtil.parse(contractSignTimeStr);Instant instant = contractSignDate.toInstant();LocalDateTime contractSignTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();projectManage.setContractSignTime(contractSignTime);}}if (map.containsValue("合同规定终验时间")) {String contractRuleFinalAcceptTimeStr = map.getOrDefault("3", "");if (StringUtils.isNotBlank(contractRuleFinalAcceptTimeStr)) {Date contractSignDate = DateUtil.parse(contractRuleFinalAcceptTimeStr);Instant instant = contractSignDate.toInstant();LocalDateTime contractRuleFinalAcceptTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();projectManage.setContractRuleFinalAcceptTime(contractRuleFinalAcceptTime);}}if (map.containsValue("开工时间")) {String startTimeStr = map.getOrDefault("5", "");if (StringUtils.isNotBlank(startTimeStr)) {Date startDate = DateUtil.parse(startTimeStr);Instant instant = startDate.toInstant();LocalDateTime startTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();projectManage.setStartTime(startTime);}}}//这里项目背景的行数,写死了,后面调整表格时,会影响这一块Map<String, String> projectBackgroudMap = maps.get(8);  String projectBackgroud = projectBackgroudMap.getOrDefault("0", "").toString();projectManage.setProjectBackgroud(projectBackgroud);projectManageService.save(projectManage);projectId = projectManage.getId();
}

保存第二个sheet的目标,将数据组装成多级嵌套的集合。有点绕,要花点时间去想想,项目赶工,瞎几把乱写了,没想到可以凑合着用。

public void saveTarget(List<LinkedHashMap<String, String>> list) {if (projectId == 0) {throw new YErrorException("请先成功导入项目!");}FirstTarget firstTarget = new FirstTarget();SecondTarget secondTarget = new SecondTarget();List<FirstTarget> firstTargetList = new ArrayList<>();List<SecondTarget> secondTargetList = new ArrayList<>();List<ThirdTarget> thirdTargetList = new ArrayList<>();for (Map<String, String> map : list) {System.err.println(map);String firstTargetName = map.getOrDefault("0", "");String firstTargetType = map.getOrDefault("1", "");String secondTargetName = map.getOrDefault("2", "");String thirdTargetName = map.getOrDefault("3", "");String thirdTargetBudget = map.getOrDefault("4", "");String positions = map.getOrDefault("5", "");if (StringUtils.isNotBlank(firstTargetName)) {//第一阶段名称不为空时,二三阶段一定不为空if (StringUtils.isNotBlank(secondTargetName)) {//第二阶段名称不为空if (secondTargetList.size() != 0) {List<SecondTarget> secondTargets = firstTarget.getSecondTargets();secondTargets.addAll(secondTargetList);}secondTarget = new SecondTarget();thirdTargetList = new ArrayList<>();firstTarget = new FirstTarget();secondTargetList = new ArrayList<>();secondTarget.setSecondTargetName(secondTargetName);ThirdTarget thirdTarget = new ThirdTarget();thirdTarget.setThirdTargetName(thirdTargetName);thirdTarget.setThirdTargetBudget(thirdTargetBudget);thirdTargetList.add(thirdTarget);secondTarget.setThirdTargets(thirdTargetList);secondTargetList.add(secondTarget);firstTarget.setSecondTargets(secondTargetList);firstTarget.setFirstTargetName(firstTargetName);firstTarget.setFirstTargetType(firstTargetType);firstTargetList.add(firstTarget);}} else {//第一阶段名称为空,且第二阶段名称不为空if (StringUtils.isNotBlank(secondTargetName)) {//去重if (secondTargetList.size() != 0) {SecondTarget st = secondTargetList.get(0);List<SecondTarget> secondTargets = firstTarget.getSecondTargets();SecondTarget secondT = secondTargets.get(0);if (!st.getSecondTargetName().equals(secondT.getSecondTargetName())) {secondTargets.addAll(secondTargetList);}}secondTarget = new SecondTarget();thirdTargetList = new ArrayList<>();secondTargetList = new ArrayList<>();secondTarget.setSecondTargetName(secondTargetName);ThirdTarget thirdTarget = new ThirdTarget();thirdTarget.setThirdTargetName(thirdTargetName);thirdTarget.setThirdTargetBudget(thirdTargetBudget);thirdTargetList.add(thirdTarget);secondTarget.setSecondTargetName(secondTargetName);secondTarget.setThirdTargets(thirdTargetList);secondTargetList.add(secondTarget);} else {//第一阶段名称为空,第二阶段名称为空,第三阶段不为空ThirdTarget thirdTarget = new ThirdTarget();thirdTarget.setThirdTargetBudget(thirdTargetBudget);thirdTarget.setThirdTargetName(thirdTargetName);thirdTargetList.add(thirdTarget);}}}// 保存最后一条数据if (secondTargetList.size() != 0) {List<SecondTarget> secondTargets = firstTarget.getSecondTargets();secondTargets.addAll(secondTargetList);}System.err.println(firstTargetList);}

还有几个实体类就不放上来了,博客太长了,看完有一点点思路,可以帮助到你,我还是很开心的,全部代码和导入的excel放下面了,可以拿去看看,参考参考。

excel地址:项目导入.xlsx

代码地址:sakura-boot-demo · GitHub

EasyExcel复杂excel导入相关推荐

  1. SpringBoot中使用Easyexcel实现Excel导入导出功能(三)

    导出的数据包含有图片 导出excel表格的数据包含有图片,这种场景比较少.通Easyexcel实现这样的需求,我认为最简便的方法就是使用前面提到的自定义转换器(com.alibaba.excel.co ...

  2. SpringBoot中使用Easyexcel实现Excel导入导出功能(一)

    目录 前言 1.常规导入 2.读取到指定的列 3.读取全部的sheet页 4.日期.数字及其他自定义格式的转换 5.表头有多行的表格读取 6.表头数据的读取 7.单元格内的备注内容读取 前言 exce ...

  3. EasyExcel实现excel导入

    文章目录 前言 一.使用步骤 1.添加依赖: 2.创建和实体类对应的用于导入导出的模板类,尽量不要直接使用实体类. 每个字段需添加@ExcelProperty注解,作为导入导出的识别的依据.注意val ...

  4. 使用POI和EasyExcel实现Excel导入和导出功能

    需求场景 开发中经常会设计到excel的处理,需求场景如下所示: 1.将用户信息导出为excel表格(导出数据) 2.将Excel表中的信息录入到数据库中(导入数据) 操作Excel目前比较流行的就是 ...

  5. POI和EasyExcel操作Excel

    POI和EasyExcel操作Excel 常用场景 1.将用户信息导出为excel表格(导出数据- ) 2.将Excel表中的信息录入到网站数据库(文件数据上传- ) 开发中经常会设计到excel的处 ...

  6. easyexcel导出和导入

    首先导jar包 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</ ...

  7. easyexcel 设置标题_EasyExcel,让 excel 导入导出更加简单

    做积极的人,而不是积极废人! 来源:jianshu.com/p/8f3defdc76d4EasyExcelGitHub上的官方说明快速开始maven仓库地址导入导出总结 EasyExcel 在做exc ...

  8. 使用EasyExcel实现Excel的导入、导出、下载模板等功能

    文章目录 导入功能 依赖 实体类 监听器 控制器 批量插入 导出功能 下载模板 实体类 控制层 业务层 参考:https://blog.csdn.net/z845910508/article/deta ...

  9. easyexcel 在 设置标题_EasyExcel,让excel导入导出更加简单

    EasyExcel 在做excel导入导出的时候,发现项目中封装的工具类及其难用,于是去gitHub上找了一些相关的框架,最终选定了EasyExcel.之前早有听闻该框架,但是一直没有去了解,这次借此 ...

最新文章

  1. pandas数据索引之loc、iloc、ix详解及实例
  2. react可视化编辑器_UE4下玩转react
  3. Leet Code OJ 102. Binary Tree Level Order Traversal [Difficulty: Easy]
  4. mysql索引优化实际例子_MySQL索引优化的实际案例分析
  5. python 列表数据类型 200221
  6. 呐,一个苹果洞赚10万美元的详细经验都在这里了~
  7. echarts 柱状图点击事件
  8. vue 鼠标点击事件_点击鼠标,利用VBA代码实现精准控制触发事件的第二方案
  9. oracle如何查找谁删除了数据_php如何删除session中数据
  10. linux里的tree 命令,Linux中tree命令起什么作用呢?
  11. 如何将小工具添加回Windows 8和10(以及为什么您不应该这样做)
  12. 【Unity】unity3d客户端网络框架
  13. matlab逻辑符号怎么打,matlab逻辑符号
  14. ios系统获取udid
  15. 沈海高速汕尾往深圳服务器维护报价,沈海高速收费
  16. Symbian手记【一】 —— Symbian命名法
  17. python查看list的shape_列表list、数组np.array等的len,size,shape操作
  18. 【金猿人物展】龙盈智达首席数据科学家王彦博:量子科技为AI大数据创新发展注入新动能...
  19. MongoDB(四)——GridFS
  20. 微信小程序-退款业务

热门文章

  1. 金蝶客户常见问题(一)
  2. 使用账号密码来操作github? NO!
  3. 潭州课堂25班:Ph201805201 tornado 项目 第二课 项目 基本功能模块和 Git 使用 (课堂笔记)...
  4. P7108 移花接木(分类讨论思维)
  5. selenium4降级为selenium3
  6. linux系统中resolv.conf文件详解
  7. vue笔记一:Vue技术栈
  8. 老年大学计算机系教学目标,天津老年大学计算机类教学大纲.doc
  9. 记来到大学双创的第一次总结
  10. .NetCore对接各大财务软件凭证API——用友系列(3)