EasyExcel导入(含表头验证+空白行读取)

2024-05-03 14:38

本文主要是介绍EasyExcel导入(含表头验证+空白行读取),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

创建表头枚举类:

public enum InvokeHeadEnums {/*** 播种及产量数据表头*/SOWING_YIELD_HEAD("SOWING_YIELD_HEAD", Arrays.asList("市*", "县(区)*", "乡/镇*", "耕地面积(亩)", "年小麦播种面积(亩)", "小麦总产量(吨)", "单位面积产量(吨/亩)", "时间(YYYY)*"));/*** 表头所属类型*/private String headType;/*** 请求头内容*/private List<String> headInfos;InvokeHeadEnums(String headType, List<String> headInfos) {this.headType = headType;this.headInfos = headInfos;}public String getHeadType() {return headType;}public List<String> getHeadInfos() {return headInfos;}/*** 根据表头类型获取字段信息** @param headType 表头类型* @return 字段信息*/public static List<String> getHeadInfos(String headType) {if (StringUtils.isBlank(headType)) {Asserts.fail("表头类型不能为空");}for (InvokeHeadEnums enums : values()) {if (headType.equals(enums.getHeadType())) {return enums.getHeadInfos();}}return null;}}

继承AnalysisEventListener:

public class EasyExcelListener extends AnalysisEventListener<Object> {/*** 表头枚举*/private String invokeHead;/*** 是否跳过空白行 true-跳过 false-不跳过*/private boolean whetherSkipBlankLines = true;/*** 验证表头+跳过空白行** @param invokeHead 表头枚举*/public EasyExcelListener(String invokeHead) {this.invokeHead = invokeHead;}/*** 验证表头+是否跳过空白行** @param invokeHead            表头枚举* @param whetherSkipBlankLines 是否跳过空白行*/public EasyExcelListener(String invokeHead, boolean whetherSkipBlankLines) {this.whetherSkipBlankLines = whetherSkipBlankLines;this.invokeHead = invokeHead;}/*** 不验证表头*/public EasyExcelListener() {}/*** 不验证表头+是否跳过空白行** @param whetherSkipBlankLines 是否跳过空白行*/public EasyExcelListener(boolean whetherSkipBlankLines) {this.whetherSkipBlankLines = whetherSkipBlankLines;}/*** 创建list集合封装最终的数据*/List<Object> list = new ArrayList<>();/*** 读取excle内容** @param t* @param analysisContext*/@Overridepublic void invoke(Object t, AnalysisContext analysisContext) {analysisContext.readWorkbookHolder().setIgnoreEmptyRow(false);// 验证空数据if (whetherSkipBlankLines && BeanUtils.checkObjAllFieldsIsNull(t)) {return;}// 将读取到的数据输出到控制台list.add(t);}/*** 读取excel表头信息** @param headMap* @param context*/@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {// 验证表头if (StringUtils.isNotBlank(invokeHead)) {List<String> headInfos = InvokeHeadEnums.getHeadInfos(invokeHead);if (headInfos.isEmpty()) {Asserts.fail("未查询到表头对应的字段信息");}if (headInfos.size() != headMap.size()) {Asserts.fail("模板不正确");}for (Integer index : headMap.keySet()) {if (!headInfos.get(index).equals(headMap.get(index))) {Asserts.fail("模板不正确");}}}}/*** 读取完成后执行** @param analysisContext*/@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}/*** 获取表格内容** @param obj 需要转化的实体* @param <T>* @return*/public <T> List<T> getList(Class<T> obj) {String jsonObj = JSONUtil.toJsonStr(list);return JSONUtil.toList(jsonObj, obj);}@Overridepublic boolean hasNext(AnalysisContext analysisContext) {if (RowTypeEnum.EMPTY.equals(analysisContext.readRowHolder().getRowType())) {doAfterAllAnalysed(analysisContext);return true;}return super.hasNext(analysisContext);}}

获取导入行数据:

  @PostMapping("/upload")@ApiOperation("导入")public CommonResult<SowingYieldDataErrorDTO> upload(@ApiParam(name = "file", value = "file", required = true) @RequestParam(value = "file") MultipartFile file,@ApiParam(name = "verifyRepeat", value = "是否验证重复 true-验证 false-不验证", required = true) @RequestParam(value = "verifyRepeat") boolean verifyRepeat) throws IOException {String originalFilename = file.getOriginalFilename();originalFilename = originalFilename.substring(originalFilename.indexOf(CommonSymbolConstant.POINT));if (!CommonSymbolConstant.EXCEL_SUFFIX.contains(originalFilename)) {Asserts.fail("文件格式错误!");}EasyExcelListener easyExcelListener = new EasyExcelListener(InvokeHeadEnums.SOWING_YIELD_HEAD.getHeadType());EasyExcelFactory.read(file.getInputStream(), SowingYieldDataUploadReq.class, easyExcelListener).sheet(0).doRead();List<SowingYieldDataUploadReq> list = easyExcelListener.getList(SowingYieldDataUploadReq.class);if (null == list || list.size() == 0) {Asserts.fail("不能导入空白数据");}// 数据验证for (SowingYieldDataUploadReq uploadReq : list) {if (BeanUtils.checkObjAllFieldsIsNull(uploadReq)) {continue;}ValidatorUtils.validate(uploadReq);}     SowingYieldDataErrorDTO errorDTO = sowingYieldDataService.dealUploadData(list, verifyRepeat);return CommonResult.success(errorDTO);}

对象值判空工具类:

public class ObjectUtils {public static boolean checkObjAllFieldsIsNull(Object object) {if (null == object) {return true;}try {for (Field f : object.getClass().getDeclaredFields()) {f.setAccessible(true);if (f.get(object) != null && StringUtils.isNotBlank(f.get(object).toString())) {return false;}}} catch (Exception e) {log.error("判空异常",e)}return true;}
}

ValidatorUtils :可触发实体上的valida相关注解

@Component
public class ValidatorUtils {private static Validator validator;@Autowiredpublic void setValidator(Validator validator) {ValidatorUtils.validator = validator;}public static <T> void validate(T entity) {Set<ConstraintViolation<T>> validate = validator.validate(entity, Default.class);if (CollUtil.isNotEmpty(validate)) {Asserts.fail(validate.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";")));}}
}

实体举例:

@Data
@ApiModel(value = "播种及产量数据上传实体", description = "播种及产量数据")
public class SowingYieldDataUploadReq {@ApiModelProperty(value = "市名称")@ExcelProperty(value = "市", index = 0)@NotNull(message = "市不能为空")private String cityName;@ApiModelProperty(value = "县区名称")@ExcelProperty(value = "县(区)", index = 1)@NotNull(message = "县(区)不能为空")private String countiesName;@ApiModelProperty(value = "乡镇名称")@ExcelProperty(value = "乡/镇", index = 2)@NotNull(message = "乡/镇不能为空")private String villageTownName;@ApiModelProperty(value = "耕地面积(亩)")@ExcelProperty(value = "耕地面积(亩)", index = 3)@DecimalMin(value = "0", message = "耕地面积(亩)必须大于等于0")@DecimalMax(value = "9999999999.9999", message = "耕地面积(亩)必须小于等于9999999999.9999")private String agriculturalAcreage;@ApiModelProperty(value = "年小麦播种面积(亩)")@ExcelProperty(value = "年小麦播种面积(亩)", index = 4)@DecimalMin(value = "0", message = "年小麦播种面积(亩)必须大于等于0")@DecimalMax(value = "9999999999.9999", message = "年小麦播种面积(亩)必须小于等于9999999999.9999")private String annualWheatSownArea;@ApiModelProperty(value = "小麦总产量(吨)")@ExcelProperty(value = "小麦总产量(吨)", index = 5)@DecimalMin(value = "0", message = "小麦总产量(吨)必须大于等于0")@DecimalMax(value = "9999999999.9999", message = "小麦总产量(吨)必须小于等于9999999999.9999")private String totalWheatProduction;@ApiModelProperty(value = "单位面积产量(吨/亩)")@ExcelProperty(value = "单位面积产量(吨/亩)", index = 6)@DecimalMin(value = "0", message = "单位面积产量(吨/亩)必须大于等于0")@DecimalMax(value = "9999999999.9999", message = "单位面积产量(吨/亩)必须小于等于9999999999.9999")private String perUnitAreaYield;@ApiModelProperty(value = "所属年份")@ExcelProperty(value = "时间", index = 7)@NotNull(message = "时间不能为空")@PositiveOrZero(message = "时间必须大于0")@DecimalMax(value = "9999", message = "时间必须小于等于9999")private String belongYear;}

这篇关于EasyExcel导入(含表头验证+空白行读取)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/956977

相关文章

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

利用Python实现添加或读取Excel公式

《利用Python实现添加或读取Excel公式》Excel公式是数据处理的核心工具,从简单的加减运算到复杂的逻辑判断,掌握基础语法是高效工作的起点,下面我们就来看看如何使用Python进行Excel公... 目录python Excel 库安装Python 在 Excel 中添加公式/函数Python 读取

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

使用EasyExcel实现简单的Excel表格解析操作

《使用EasyExcel实现简单的Excel表格解析操作》:本文主要介绍如何使用EasyExcel完成简单的表格解析操作,同时实现了大量数据情况下数据的分次批量入库,并记录每条数据入库的状态,感兴... 目录前言固定模板及表数据格式的解析实现Excel模板内容对应的实体类实现AnalysisEventLis

Python如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常

浅析Python中的绝对导入与相对导入

《浅析Python中的绝对导入与相对导入》这篇文章主要为大家详细介绍了Python中的绝对导入与相对导入的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1 Imports快速介绍2 import语句的语法2.1 基本使用2.2 导入声明的样式3 绝对import和相对i

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进