net后缀的可以做网站吗,哪个网站可以领手工回家做,租房子58同城,在网站做电子画册文章目录 前言一、需求和效果二、难点和思路三、全部代码踩坑 前言
之前分享的 EasyExcel 批量导入并校验数据#xff0c;仅支持规则excel#xff0c;即首行表头#xff0c;下面对应数据#xff0c;无合并单元格情况。 本篇主要解决问题#xff1a;
模板excel 表头不在首… 文章目录 前言一、需求和效果二、难点和思路三、全部代码踩坑 前言
之前分享的 EasyExcel 批量导入并校验数据仅支持规则excel即首行表头下面对应数据无合并单元格情况。 本篇主要解决问题
模板excel 表头不在首行数据项有合并单元格情况
esayexcel版本2.2.7
一、需求和效果 二、难点和思路 跳过表头前的说明 设置headRowNumber指定表头位置第三行
EasyExcel.read(inputStream, EvalTemplateReq.class,listener).extraRead(CellExtraTypeEnum.MERGE).sheet().headRowNumber(3).doRead();合并单元格数据获取放入list 合并单元格的数据默认是在合并表格的左上第一个格子其他为null获取到这个格子的数据赋值给其他被合并单元格对应的字段中
3.1 开启合并单元格识别 extraRead(CellExtraTypeEnum.MERGE)开启合并单元格识别 3.2 获取合并的单元格数据 EvalExcelDataListener 重写extra方法获取到被合并的数据后续处理。extra方法在invoke方法执行先不要在意要导入的list部分字段是null后续重新赋值即可。 extra会从excel头读取所以要把前2行的数据过滤掉这里用extra.getFirstRowIndex()2判断一下 // 合并单元格private final ListCellExtra extraMergeInfoList new ArrayList();Overridepublic void extra(CellExtra extra, AnalysisContext context) {if (extra.getType() CellExtraTypeEnum.MERGE) {// 处理合并单元格的情况int firstRowIndex extra.getFirstRowIndex();if(firstRowIndex2) {extraMergeInfoList.add(extra);}}}3.3 doAfterAllAnalysed中补全list字段值 Overridepublic void doAfterAllAnalysed(AnalysisContext context) {//所有数据解析完毕执行该方法// 防止导入空的Excelif (context.readRowHolder().getRowIndex() 0) {throw new ExcelAnalysisException(当前excel无数据!);}//处理合并单元格list EasyExcelMergeUtil.explainMergeData(list, extraMergeInfoList, 3);saveData();}3.4 explainMergeData 补全字段值 根据单元格左上角标通过反射获取字段并赋值给其他被合并的单元格角标对应实体类index属性
三、全部代码
接收数据实体
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.validation.constraints.NotBlank;
import java.util.List;/*** 评估标准*/
Builder
Data
AllArgsConstructor
NoArgsConstructor
public class EvalTemplateReq {ExcelIgnoreprivate String id;/*** 评估项*/ExcelProperty(value 评估名称,index 1)NotBlank(message 评估名称不能为空)private String item;/*** 指标简称*/ExcelProperty(value 指标简称,index 2)NotBlank(message 指标简称不能为空)private String itemShortName;/*** 指标编码*/ExcelProperty(value 指标编码,index 3)NotBlank(message 指标编码不能为空)private String itemCode;/*** 指标释义*/ExcelProperty(value 指标释义,index 4)NotBlank(message 指标释义不能为空)private String itemExplain;/*** 评价要求/分数 json*/ExcelIgnoreprivate ListRequirements requirementList;/*** 系统监测类/参演部门上报类*/ExcelProperty(value 分类,index 0)NotBlank(message 分类不能为空)private String type;ExcelProperty(value 评价要求,index 5)JsonIgnoreprivate String require;ExcelProperty(value 分数,index 6)JsonIgnoreprivate Integer score;BuilderDataAllArgsConstructorNoArgsConstructorpublic static class Requirements {ExcelIgnoreprivate String id;/*** 评价内容*/NotBlank(message 评价要求不能为空)private String require;/*** 分数*/NotBlank(message 分数不能为空)private Integer score;}
}
service调用 /*** 导入评估标准*/Overridepublic String importEval(MultipartFile file) {EvalExcelDataListener listener new EvalExcelDataListener(evalTemplateDao);InputStream inputStream;try {inputStream file.getInputStream();EasyExcel.read(inputStream, EvalTemplateReq.class,listener).extraRead(CellExtraTypeEnum.MERGE).sheet().headRowNumber(3).doRead();return 全部导入成功;} catch (IOException e) {throw new BusinessCheckException(Excel 文件流读取失败);} catch (ExcelAnalysisException e) {return e.getMessage();} catch (Exception e) {throw new BusinessException(数据导入失败, e);}}合并单元格数据处理util
package com.gsafety.bg.pd.service.excel;import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.CellExtra;
import lombok.extern.slf4j.Slf4j;import java.lang.reflect.Field;
import java.util.List;Slf4j
public class EasyExcelMergeUtil {/*** 处理合并单元格* param data 解析数据* param extraMergeInfoList 合并单元格信息* param headRowNumber 起始行* return 填充好的解析数据*/public static T ListT explainMergeData(ListT data, ListCellExtra extraMergeInfoList, Integer headRowNumber) {// 循环所有合并单元格信息extraMergeInfoList.forEach(cellExtra - {int firstRowIndex cellExtra.getFirstRowIndex() - headRowNumber;int lastRowIndex cellExtra.getLastRowIndex() - headRowNumber;int firstColumnIndex cellExtra.getFirstColumnIndex();int lastColumnIndex cellExtra.getLastColumnIndex();// 获取初始值Object initValue getInitValueFromList(firstRowIndex, firstColumnIndex, data);// 设置值for (int i firstRowIndex; i lastRowIndex; i) {for (int j firstColumnIndex; j lastColumnIndex; j) {setInitValueToList(initValue, i, j, data);}}});return data;}/*** 设置合并单元格的值** param filedValue 值* param rowIndex 行* param columnIndex 列* param data 解析数据*/private static T void setInitValueToList(Object filedValue, Integer rowIndex, Integer columnIndex, ListT data) {if (rowIndex data.size()) return;T object data.get(rowIndex);for (Field field : object.getClass().getDeclaredFields()) {// 提升反射性能关闭安全检查field.setAccessible(true);ExcelProperty annotation field.getAnnotation(ExcelProperty.class);if (annotation ! null) {if (annotation.index() columnIndex) {try {field.set(object, filedValue);break;} catch (IllegalAccessException e) {log.error(设置合并单元格的值异常{}, e.getMessage());}}}}}/*** 获取合并单元格的初始值* rowIndex对应list的索引* columnIndex对应实体内的字段** param firstRowIndex 起始行* param firstColumnIndex 起始列* param data 列数据* return 初始值*/private static T Object getInitValueFromList(Integer firstRowIndex, Integer firstColumnIndex, ListT data) {Object filedValue null;T object data.get(firstRowIndex);for (Field field : object.getClass().getDeclaredFields()) {// 提升反射性能关闭安全检查field.setAccessible(true);ExcelProperty annotation field.getAnnotation(ExcelProperty.class);if (annotation ! null) {if (annotation.index() firstColumnIndex) {try {filedValue field.get(object);break;} catch (IllegalAccessException e) {log.error(设置合并单元格的初始值异常{}, e.getMessage());}}}}return filedValue;}}
easyexcel数据监听类
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.CellExtra;
import com.gsafety.bg.gsdss.common.utils.json.JsonUtil;
import com.gsafety.bg.pd.dao.EvalTemplateDao;
import com.gsafety.bg.pd.model.dto.req.EvalTemplateReq;
import com.gsafety.bg.pd.model.po.EvalTemplatePO;import java.util.*;
import java.util.stream.Collectors;public class EvalExcelDataListener extends AnalysisEventListenerEvalTemplateReq {private final Integer LIST_COUNT 19;ListEvalTemplateReq list new ArrayList(LIST_COUNT);// 合并单元格private final ListCellExtra extraMergeInfoList new ArrayList();// 由于监听器只能通过new的方式创建所以可以通过构造器传入dao层对象private final EvalTemplateDao dao;public EvalExcelDataListener(EvalTemplateDao dao) {this.dao dao;}Overridepublic void invoke(EvalTemplateReq req, AnalysisContext context) {list.add(req);if (list.size() LIST_COUNT) {throw new ExcelAnalysisException(当前excel数据量不得大于 LIST_COUNT 条);}}Overridepublic void extra(CellExtra extra, AnalysisContext context) {if (extra.getType() CellExtraTypeEnum.MERGE) {// 处理合并单元格的情况int firstRowIndex extra.getFirstRowIndex();if(firstRowIndex2) {extraMergeInfoList.add(extra);}}}Overridepublic void doAfterAllAnalysed(AnalysisContext context) {//所有数据解析完毕执行该方法// 防止导入空的Excelif (context.readRowHolder().getRowIndex() 0) {throw new ExcelAnalysisException(当前excel无数据!);}//处理合并单元格list EasyExcelMergeUtil.explainMergeData(list, extraMergeInfoList, 3);saveData();}protected void saveData() {MapString, ListEvalTemplateReq collect list.stream().collect(Collectors.groupingBy(EvalTemplateReq::getItem));ListEvalTemplatePO pos new ArrayList();collect.forEach((k, v) - {ListEvalTemplateReq.Requirements requirements v.stream().map(l - EvalTemplateReq.Requirements.builder().id(v.indexOf(l) ).require(l.getRequire()).score(l.getScore()).build()).collect(Collectors.toList());pos.add(EvalTemplatePO.builder().item(k).itemCode(collect.get(k).get(0).getItemCode()).itemExplain(collect.get(k).get(0).getItemExplain()).itemShortName(collect.get(k).get(0).getItemShortName()).type(collect.get(k).get(0).getType()).requirements(JsonUtil.of(requirements)).build());});dao.deleteAll();dao.saveAll(pos);}
}
踩坑
extra方法不生效 extraRead(CellExtraTypeEnum.MERGE)显式指定识别合并单元格数据 invoke中原校验数据因为为null导致拦截不走extra方法。 执行顺序invoke-extra-doAfterAllAnalysed指定表头位置后extra获取的第一个数据还是首行的合并单元格数据 headRowNumber(3)只是指定了读取表头的位置extra是获取整表的所有合并单元格数据根据excel模板要跳过2行获取从第三行后的合并单元格数据。if(firstRowIndex2)
参考https://blog.csdn.net/xhmico/article/details/136905419