EasyExcel复杂excel导入

EasyExcel复杂excel导入

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

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

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

第一个sheet内容:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MqfRrgNN-1660632070755)(D:\yangfan\mdpic\2022-08-16-13-58-28-image.png)]

第二个sheet内容,一对多,一个阶段对应多个任务,一个任务对应多个动作:
在这里插入图片描述

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

controller

@RestController
@RequestMapping("/sakura/easyexcel")
@Api(value = "复杂excel导入", tags = {"复杂excel导入"})
public class ProjectExcelController {
    @Autowired
    ProjectEasyExcelService 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页表格内容存于map
    Map<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;

    @Override
    public 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表头信息
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
    }

    // 读取完成后执行
    @Override
    public 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

  • 37
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
对于复杂Excel文件,你可以使用EasyExcel导入数据。EasyExcel是一个基于Java的开源库,可以用来读取、写入和处理Excel文件。 下面是一个示例代码,演示如何使用EasyExcel导入复杂Excel文件: ```java // 导入相关的包 import com.alibaba.excel.EasyExcel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; // 创建一个数据模型类,用于存储导入的数据 public class ExcelData { private String column1; private String column2; // ... 其他列 // 省略getter和setter方法 } // 创建一个监听器类,用于处理导入的数据 public class ExcelListener extends AnalysisEventListener<ExcelData> { @Override public void invoke(ExcelData data, AnalysisContext context) { // 在这里处理每一行的数据 System.out.println("读取到数据:" + data.getColumn1() + ", " + data.getColumn2()); // ... 处理其他列 } @Override public void doAfterAllAnalysed(AnalysisContext context) { // 当所有数据都解析完成后,执行此方法 } } // 主程序 public class Main { public static void main(String[] args) { String filePath = "path/to/your/excel/file.xlsx"; // 使用EasyExcel进行导入 EasyExcel.read(filePath, ExcelData.class, new ExcelListener()).sheet().doRead(); } } ``` 在上面的示例中,你需要自己定义一个数据模型类(ExcelData),用来存储导入的数据。然后创建一个监听器类(ExcelListener),通过继承AnalysisEventListener来处理每一行的数据。最后,在主程序中使用EasyExcel的read方法来读取Excel文件并进行导入,你只需要将文件路径替换成你实际的Excel文件路径即可。 希望能帮到你!如果有更多问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木一番

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值