日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

easyexcel处理合并单元格数据

發(fā)布時(shí)間:2023/12/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 easyexcel处理合并单元格数据 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、背景

一次工作任務(wù)是要解析excel數(shù)據(jù),采用阿里的 easyexcel 工具進(jìn)行解析,由于表格有合并單元格,但是 easyexcel 讀取合并單元格只會(huì)讀取一次,導(dǎo)致下面單元格數(shù)據(jù)為空,這樣會(huì)影響有層級(jí)數(shù)據(jù)的識(shí)別,所以需要將合并單元格都填充上數(shù)據(jù)。由于我的excel列數(shù)是變化的,所以無(wú)法采用對(duì)象映射,獲取出來(lái)的數(shù)據(jù)也是 List<Map<Integer, String>> 類(lèi)型,廢話不多說(shuō)請(qǐng)看下面。

二、解決

2.0 先看一下處理結(jié)果

解析到一條數(shù)據(jù):{"0":"*應(yīng)用名稱(chēng)","1":"應(yīng)用編碼","2":"*一級(jí)菜單","3":"菜單編碼","4":"*二級(jí)菜單","5":"菜單編碼","6":"*功能菜單","7":"菜單編碼","8":"功能角色1","9":"功能角色2","10":"功能角色3"} 解析到一條數(shù)據(jù):{"0":"測(cè)試應(yīng)用11","6":"全量","8":"√","10":"√"} 解析到一條數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單1","4":"二級(jí)菜單1","6":"功能菜單1","8":"√","10":"√"} 解析到一條數(shù)據(jù):{"6":"功能菜單2","9":"√","10":"√"} 解析到一條數(shù)據(jù):{"6":"功能菜單3","10":"√"} 解析到一條數(shù)據(jù):{"4":"二級(jí)菜單2","6":"功能菜單4","8":"√","10":"√"} 解析到一條數(shù)據(jù):{"6":"功能菜單5","9":"√","10":"√"} 解析到一條數(shù)據(jù):{"2":"一級(jí)菜單2","4":"二級(jí)菜單3","6":"功能菜單6","8":"√","10":"√"} 解析到一條數(shù)據(jù):{"6":"功能菜單7","9":"√","10":"√"} 解析到一條數(shù)據(jù):{"6":"功能菜單8","9":"√","10":"√"} 解析到一條數(shù)據(jù):{"0":"測(cè)試應(yīng)用33","2":"一級(jí)菜單3","6":"全量","8":"√","10":"√"} 解析到一條數(shù)據(jù):{"2":"一級(jí)菜單4","6":"全量","10":"√"} 解析到一條數(shù)據(jù):{"2":"一級(jí)菜單5","6":"全量","9":"√","10":"√"} 解析到一條數(shù)據(jù):{"2":"一級(jí)菜單6","6":"全量","9":"√","10":"√"}處理后數(shù)據(jù):{"0":"*應(yīng)用名稱(chēng)","1":"應(yīng)用編碼","2":"*一級(jí)菜單","3":"菜單編碼","4":"*二級(jí)菜單","5":"菜單編碼","6":"*功能菜單","7":"菜單編碼","8":"功能角色1","9":"功能角色2","10":"功能角色3"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用11","6":"全量","8":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單1","4":"二級(jí)菜單1","6":"功能菜單1","8":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單1","4":"二級(jí)菜單1","6":"功能菜單2","9":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單1","4":"二級(jí)菜單1","6":"功能菜單3","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單1","4":"二級(jí)菜單2","6":"功能菜單4","8":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單1","4":"二級(jí)菜單2","6":"功能菜單5","9":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單2","4":"二級(jí)菜單3","6":"功能菜單6","8":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單2","4":"二級(jí)菜單3","6":"功能菜單7","9":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用22","2":"一級(jí)菜單2","4":"二級(jí)菜單3","6":"功能菜單8","9":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用33","2":"一級(jí)菜單3","6":"全量","8":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用33","2":"一級(jí)菜單4","6":"全量","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用33","2":"一級(jí)菜單5","6":"全量","9":"√","10":"√"} 處理后數(shù)據(jù):{"0":"測(cè)試應(yīng)用33","2":"一級(jí)菜單6","6":"全量","9":"√","10":"√"}

2.1 引入easyexcel依賴(lài)

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.5</version> </dependency>

2.1 創(chuàng)建EasyExcelListener類(lèi)

@Slf4j public class EasyExcelListener extends AnalysisEventListener<Map<Integer, String>> {/*** 數(shù)據(jù)*/List<Map<Integer, String>> dataList = new ArrayList<>();/*** 正文起始行*/private Integer headRowNumber;/*** 合并單元格*/private List<CellExtra> extraMergeInfoList = new ArrayList<>();public EasyExcelListener(Integer headRowNumber) {this.headRowNumber = headRowNumber;}@Overridepublic void invoke(Map<Integer, String> data, AnalysisContext context) {log.info("解析到一條數(shù)據(jù):{}", JSON.toJSONString(data));dataList.add(data);}/*** 讀取額外信息:合并單元格*/@Overridepublic void extra(CellExtra extra, AnalysisContext context) {log.info("讀取到了一條額外信息:{}", JSON.toJSONString(extra));switch (extra.getType()) {case MERGE: {if (extra.getRowIndex() >= headRowNumber) {extraMergeInfoList.add(extra);}break;}default: break;}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {log.info("所有數(shù)據(jù)解析完成!");}/*** 返回解析出來(lái)的List*/public List<Map<Integer, String>> getData() {return dataList;}/*** 返回解析出來(lái)的合并單元格List*/public List<CellExtra> getExtraMergeInfoList() {return extraMergeInfoList;} }

2.2 創(chuàng)建EasyExcelHelper類(lèi)

@Slf4j public class EasyExcelHelper<T> {/*** 返回解析后的List** @param: fileName 文件名* @param: clazz Excel對(duì)應(yīng)屬性名* @param: sheetNo 要解析的sheet* @param: headRowNumber 正文起始行* @return java.util.List<T> 解析后的List*/public List<Map<Integer, String>> getList(InputStream inputStream, Integer sheetNo, Integer headRowNumber) {EasyExcelListener listener = new EasyExcelListener(headRowNumber);try {EasyExcelFactory.read(inputStream, listener).excelType(ExcelTypeEnum.XLSX).extraRead(CellExtraTypeEnum.MERGE).sheet(sheetNo).headRowNumber(headRowNumber).doRead();} catch (Exception e) {log.error(e.getMessage());}List<CellExtra> extraMergeInfoList = listener.getExtraMergeInfoList();if (CollectionUtils.isEmpty(extraMergeInfoList)) {return listener.getData();}List<Map<Integer, String>> data = explainMergeData(listener.getData(), extraMergeInfoList, headRowNumber);return data;}/*** 處理合并單元格** @param data 解析數(shù)據(jù)* @param extraMergeInfoList 合并單元格信息* @param headRowNumber 起始行* @return 填充好的解析數(shù)據(jù)*/private List<Map<Integer, String>> explainMergeData(List<Map<Integer, String>> data, List<CellExtra> extraMergeInfoList, Integer headRowNumber) {//循環(huán)所有合并單元格信息extraMergeInfoList.forEach(cellExtra -> {int firstRowIndex = cellExtra.getFirstRowIndex() - headRowNumber;int firstColumnIndex = cellExtra.getFirstColumnIndex();int lastRowIndex = cellExtra.getLastRowIndex() - headRowNumber;int lastColumnIndex = cellExtra.getLastColumnIndex();// 獲取初始值String initValue = getInitValueFromList(firstRowIndex, firstColumnIndex, data);// 設(shè)置值for (int i = firstRowIndex; i <= lastRowIndex; i++) {for (int j = firstColumnIndex; j <= lastColumnIndex; j++) {setInitValueToList(initValue, i, j, data);}}});return data;}/*** 設(shè)置合并單元格的值** @param filedValue 值* @param rowIndex 行* @param columnIndex 列* @param data 解析數(shù)據(jù)*/public void setInitValueToList(String filedValue, Integer rowIndex, Integer columnIndex, List<Map<Integer, String>> data) {Map<Integer, String> object = data.get(rowIndex);object.put(columnIndex, String.valueOf(filedValue));}/*** 獲取合并單元格的初始值* rowIndex對(duì)應(yīng)list的索引* columnIndex對(duì)應(yīng)實(shí)體內(nèi)的字段** @param firstRowIndex 起始行* @param firstColumnIndex 起始列* @param data 列數(shù)據(jù)* @return 初始值*/private String getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, List<Map<Integer, String>> data) {String filedValue = null;Map<Integer, String> object = data.get(firstRowIndex);for (Map.Entry<Integer, String> entry : object.entrySet()) {if (entry.getKey().equals(firstColumnIndex)) {filedValue = entry.getValue();break;}}return filedValue;} }

2.3 測(cè)試使用

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Boolean uploadAuthTemplate(@RequestPart("file") MultipartFile file) {EasyExcelHelper<Map<Integer, String>> helper = new EasyExcelHelper<>();// 參數(shù) 文件流,sheet頁(yè)號(hào),頭行號(hào)List<Map<Integer, String>> listData = helper.getList(file.getInputStream(), 0, 1);log.info(JSON.toJSONString(listData));return true; }

三、結(jié)語(yǔ)

萬(wàn)般皆下品,唯有技術(shù)和遠(yuǎn)方。。。愿君有所收獲。。。

總結(jié)

以上是生活随笔為你收集整理的easyexcel处理合并单元格数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。