使用EasyExcel对excel数据进行合并,

server/2024/10/11 9:19:29/

业务背景:要求同列的不同行的相同数据进行合并,部分列需要依据code进行比对然后进行合并,主要的技术栈使用EasyExcel进行合并,先把最小维度的每条数据查询出来,然后对这些数据按着合并策略进行合并。

1、先查询出所有符合要求的数据,需要把输出list放到最小单元那一层,保证每一条数据都要有数据。

public List<RiskIdentifyDatoExportToDataExcelDto> getRiskIdentifyList(UserInfo userInfo, Long id) {log.info("辨识风险导出数据,查询id:{}",id);List<RiskIdentifyDatoExportToDataExcelDto> resultList=new ArrayList<>();CtuRiskIdentify ctuRiskIdentify = ctuRiskIdentifyReadMapper.selectById(id);CtuDangerOrigin dangerOrigin = ctuDangerOriginReadMapper.selectByRiskKey(ctuRiskIdentify.getRiskKey());String dangerOriKey = dangerOrigin.getDangerOriKey();//分析对象和业态AnalysisObject analysisObject = analysisObjectReadMapper.selectById(ctuRiskIdentify.getAnalysisObjId());Business business = businessReadMapper.selectById(ctuRiskIdentify.getBusinessId());CtuAnalysisCategory analysisCategory = ctuAnalysisCategoryReadMapper.selectById(ctuRiskIdentify.getAnalysisCategoryId());//找辨识最小单元管控措施List<CtuDangerCase> ctuDangerCases = ctuDangerCaseReadMapper.selectByDangerKey(dangerOriKey);//风险等级 需评价完成后List<String> riskKeys=new ArrayList<>();riskKeys.add(ctuRiskIdentify.getRiskKey());List<AssessRiskLevelDTO> riskLevelDTOS = assessServiceHandler.queryDangerRiskLevel(riskKeys);//风险单元String riskUnitCode = ctuRiskIdentify.getRiskUnitCode();List<String> riskUnitCodes=new ArrayList<>(1);riskUnitCodes.add(riskUnitCode);List<RiskUnitLevelDto> diffLevelRiskUnitList = diffLevelRiskUnitService.getDiffLevelRiskUnit(riskUnitCodes).getData();for(CtuDangerCase dangerCase:ctuDangerCases){//查询危险致因管控措施List<CtuDangerCaseMethod> dangerCaseMethods=ctuDangerCaseMethodReadMapper.selectByCaseCode(dangerCase.getDangerCaseCode());if(!CollectionUtils.isEmpty(dangerCaseMethods)){for(CtuDangerCaseMethod dangerCaseMethod:dangerCaseMethods){RiskIdentifyDatoExportToDataExcelDto item=new RiskIdentifyDatoExportToDataExcelDto();item.setAnalysisObjId(ctuRiskIdentify.getAnalysisObjId());item.setControlMethod(dangerCaseMethod.getControlMethod());item.setDangerCaseCode(dangerCase.getDangerCaseCode());item.setDangerName(dangerOrigin.getDangerName());item.setDangerOriKey(dangerOriKey);item.setCreator(ctuRiskIdentify.getCreator());item.setControlDept(dangerCase.getOrgDep());item.setIfClock(dangerCase.getIfClock()==1?"是":"否");item.setDangerSourceCause(dangerCase.getDangerCaseName());item.setDangerSourceType(dangerOrigin.getDangerName());if(dangerCase.getIfClock()==1){DictionaryInfo dictionaryInfo = dics.get(dangerCase.getControlRate());if(Objects.isNull(dictionaryInfo)){DictionaryInfo dbDic = dictionaryInfoReadMapper.selectById(dangerCase.getControlRate());if(Objects.nonNull(dbDic)){dics.put(Ints.tryParse(dangerCase.getControlRate()),dbDic);BeanUtils.copyProperties(dbDic,dictionaryInfo);}}item.setControlRate(dictionaryInfo.getSelectValue());String startEndTime=dangerCase.getControlStartTime()+"——"+dangerCase.getControlEndTime();item.setControlStartEndTime(startEndTime);}item.setControlType(dangerCase.getControlType()==1?"人工巡查":"物联智巡");//查询危险致因管控责任人QueryWrapper<CtuControlPerson> queryWrapperPerson = new QueryWrapper<>();queryWrapperPerson.eq("case_id",dangerCaseMethod.getDangerCaseId());queryWrapperPerson.eq("case_type",1);List<CtuControlPerson> ctuControlPeoples = ctuControlPersonReadMapper.selectList(queryWrapperPerson);if(!CollectionUtils.isEmpty(ctuControlPeoples)){List<String> controlPeoples = ctuControlPeoples.stream().map(CtuControlPerson::getControlPerson).collect(Collectors.toList());item.setControlPersons(String.join(",", controlPeoples));}if(Objects.nonNull(analysisObject)){item.setAnaObjName(analysisObject.getAnaObjName());}if(Objects.nonNull(business)){item.setBusinessName(business.getBusinessName());}if(Objects.nonNull(analysisCategory)){item.setAnalysisCategoryName(analysisCategory.getAnaCategoryName());}String createTime = DateFormatUtils.format(ctuRiskIdentify.getCreateTime(), "yyyy-MM-dd HH:mm:ss");item.setCreateTime(createTime);if(!CollectionUtils.isEmpty(riskLevelDTOS)){AssessRiskLevelDTO assessRiskLevelDTO = riskLevelDTOS.get(0);item.setRiskLevel(assessRiskLevelDTO.getRiskLevel());}setRiskUnitName(diffLevelRiskUnitList,item);resultList.add(item);}}}

2、合并策略

@Slf4j
public class HierarchicalMergeStrategy implements RowWriteHandler{private final List<RiskIdentifyDatoExportToDataExcelDto> dataList;public HierarchicalMergeStrategy(List<RiskIdentifyDatoExportToDataExcelDto> dataList) {this.dataList = dataList;}@Overridepublic void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer rowIndex, Boolean isHead) {// 排除表头行if (isHead || rowIndex == 0) {return;}Sheet sheet = writeSheetHolder.getSheet();RiskIdentifyDatoExportToDataExcelDto currentData = dataList.get(rowIndex);RiskIdentifyDatoExportToDataExcelDto previousData = dataList.get(rowIndex - 1);// 对不同列的层次进行合并mergeColumns(sheet, rowIndex, currentData, previousData);}private void mergeColumns(Sheet sheet, int rowIndex, RiskIdentifyDatoExportToDataExcelDto currentData, RiskIdentifyDatoExportToDataExcelDto previousData) {//危险致因相同 合并if (StringUtils.isNotBlank(currentData.getDangerCaseCode()) && currentData.getDangerCaseCode().equals(previousData.getDangerCaseCode())) {mergeCells(sheet, rowIndex, 13,currentData.getDangerSourceCause());}//事故成因相同 合并if (StringUtils.isNotBlank(currentData.getAccidCaseCode()) && currentData.getAccidCaseCode().equals(previousData.getAccidCaseCode())) {mergeCells(sheet, rowIndex, 13,currentData.getDangerSourceCause());}// 危险源描述相同 合并if (StringUtils.isNotBlank(currentData.getDangerCaseCode()) && currentData.getDangerCaseCode().equals(previousData.getDangerCaseCode())&&currentData.getDangerOriKey().equals(previousData.getDangerOriKey())) {mergeCells(sheet, rowIndex, 12,currentData.getDangerSourceType());}//事故相同 合并if (StringUtils.isNotBlank(currentData.getAccidCaseCode()) && currentData.getAccidCaseCode().equals(previousData.getAccidCaseCode())&& currentData.getAccidentTypeCode().equals(previousData.getAccidentTypeCode())) {mergeCells(sheet, rowIndex, 12,currentData.getDangerSourceType());}//危险源合并if(StringUtils.isNotBlank(currentData.getDangerOriKey()) && currentData.getDangerOriKey().equals(previousData.getDangerOriKey())){mergeCells(sheet, rowIndex, 10,currentData.getDangerName());}//分析对象合并if(Objects.nonNull(currentData.getAnalysisObjId()) && currentData.getAnalysisObjId().equals(previousData.getAnalysisObjId())){mergeCells(sheet, rowIndex, 9,currentData.getAnaObjName());}//风险单元合并if(StringUtils.isNotBlank(currentData.getOneUnitName())&&currentData.getOneUnitName().equals(previousData.getOneUnitName())){mergeCells(sheet, rowIndex, 2,currentData.getOneUnitName());}if(StringUtils.isNotBlank(currentData.getTwoUnitName())&&currentData.getTwoUnitName().equals(previousData.getTwoUnitName())){mergeCells(sheet, rowIndex, 3,currentData.getTwoUnitName());}if(StringUtils.isNotBlank(currentData.getThreeUnitName())&&currentData.getThreeUnitName().equals(previousData.getThreeUnitName())){mergeCells(sheet, rowIndex, 4,currentData.getThreeUnitName());}if(StringUtils.isNotBlank(currentData.getFourUnitName())&&currentData.getFourUnitName().equals(previousData.getFourUnitName())){mergeCells(sheet, rowIndex, 5,currentData.getFourUnitName());}if(StringUtils.isNotBlank(currentData.getFiveUnitName())&&currentData.getFiveUnitName().equals(previousData.getFiveUnitName())){mergeCells(sheet, rowIndex, 6,currentData.getFiveUnitName());}//分析对象类型和业态if(StringUtils.isNotBlank(currentData.getAnalysisCategoryName())&&currentData.getAnalysisCategoryName().equals(previousData.getAnalysisCategoryName())){mergeCells(sheet, rowIndex, 7,currentData.getAnalysisCategoryName());}if(StringUtils.isNotBlank(currentData.getBusinessName())&&currentData.getBusinessName().equals(previousData.getBusinessName())){mergeCells(sheet, rowIndex, 8,currentData.getBusinessName());}//上报时间上报人if(StringUtils.isNotBlank(currentData.getCreator())&&currentData.getCreator().equals(previousData.getCreator())){mergeCells(sheet, rowIndex, 0,currentData.getCreator());}if(StringUtils.isNotBlank(currentData.getCreateTime())&&currentData.getCreateTime().equals(previousData.getCreateTime())){mergeCells(sheet, rowIndex, 1,currentData.getCreateTime());}//风险等级if(StringUtils.isNotBlank(currentData.getRiskLevel()) && currentData.getRiskLevel().equals(previousData.getRiskLevel())){mergeCells(sheet, rowIndex, 11,currentData.getRiskLevel());}}private void mergeCells(Sheet sheet, int rowIndex, int columnIndex, String cellStringValue) {log.info("合并单元格内容,行数:{},列数:{},单元格内容:{}",rowIndex,columnIndex,cellStringValue);// 获取之前的合并区域并继续合并// 先检查是否已经有合并的区域int mergedRegionsCount = sheet.getNumMergedRegions();if (mergedRegionsCount > 0) {// 遍历已经存在的合并区域for (int i = 0; i < mergedRegionsCount; i++) {CellRangeAddress mergedRegion = sheet.getMergedRegion(i);if (mergedRegion.getFirstColumn() == columnIndex && mergedRegion.getLastColumn() == columnIndex) {// 如果当前行已经在某个合并区域内,扩展这个合并区域if ((rowIndex >= mergedRegion.getFirstRow() && rowIndex <= mergedRegion.getLastRow()) ||(rowIndex - 1 >= mergedRegion.getFirstRow() && rowIndex - 1 <= mergedRegion.getLastRow())) {if(cellStringValue !=null && cellStringValue.equals(sheet.getRow(rowIndex-1).getCell(columnIndex).getStringCellValue())){sheet.removeMergedRegion(i);sheet.addMergedRegion(new CellRangeAddress(mergedRegion.getFirstRow(), rowIndex+1, columnIndex, columnIndex));return;}else{sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex+1, columnIndex, columnIndex));return;}}}}}// 如果没有找到现有的合并区域,则创建新的合并区域sheet.addMergedRegion(new CellRangeAddress(rowIndex, rowIndex+1, columnIndex, columnIndex));}
}


http://www.ppmy.cn/server/111072.html

相关文章

轴承知识大全,详细介绍(附3D图纸免费下载)

轴承一般由内圈、外圈、滚动体和保持架组成。对于密封轴承&#xff0c;再加上润滑剂和密封圈&#xff08;或防尘盖&#xff09;。这就是轴承的全部组成。 根据轴承使用的工作状况来选用不同类型的轴承&#xff0c;才能更好的发挥轴承的功能&#xff0c;并延长轴承的使用寿命。我…

24 - 第三方库的使用支持

---- 整理自狄泰软件唐佐林老师课程 文章目录 1. 第三方库的使用支持1.1 问题1.2 经验假设1.3 第三方库在项目中的位置 2. 第三方库的编译阶段支持3. 第三方库的链接阶段支持4. 实验 1. 第三方库的使用支持 1.1 问题 当需要使用第三方库文件时&#xff0c;编译环境中的 makef…

2. 学习环境-编辑器和静态服务器

vscode代码编辑器 Web3D开发的代码编辑器和平时web前端开发一样&#xff0c;你可以根据自己的喜好选择&#xff0c;本课程选择的代码编辑器是vscode (opens new window)。 如果不了解vscode&#xff0c;想安装和使用vscode&#xff0c;可以参考我以前发布的前端公开课HTML入门…

extern:c语言中的函数可以重复声明吗

在C语言中&#xff0c;函数可以被多次声明&#xff0c;但是有几个要点需要注意&#xff1a; 1.重复声明必须保持一致&#xff1a;函数的多次声明必须完全相同&#xff0c;包括返回类型、函数名和参数列表&#xff08;包括参数的类型和顺序&#xff09;。如果声明的任何部分不一…

读书笔记:《深入理解Java虚拟机》(6)

垃圾收集器与内存分配策略 三、经典垃圾收集器 如果说收集算法是内存回收的方法论&#xff0c;那垃圾收集器就是内存回收的实践者。《Java虚拟机规 范》中对垃圾收集器应该如何实现并没有做出任何规定&#xff0c;因此不同的厂商、不同版本的虚拟机所包含 的垃圾收集器都可能会…

shell脚本—————局域网IP扫描

#!/bin/bash #该脚本用于采集某个C类网络存活主机的MAC地址 #使用方法&#xff1a;bash 脚本名字网卡名字网段前三位.10.144.100. #ETH$(ifconfig | grep eth | awk {print $1})for ip in {1..254} do { arping -c 2 -w 1 -I $1 $2$ip| grep "reply from" > /dev/…

[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-26浅谈XILINX FIFO的基本使用

软件版本&#xff1a;VIVADO2021.1 操作系统&#xff1a;WIN10 64bit 硬件平台&#xff1a;适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA 实验平台&#xff1a;米联客-MLK-H3-CZ08-7100开发板 板卡获取平台&#xff1a;https://milianke.tmall.com/ 登录“米联客”FPGA社区 http…

Vue输入框模糊搜索的多种写法

&#xff08;1&#xff09;模板方案 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</…