java读取Excel导入去除空行简单方法

 更新时间:2023年07月19日 12:06:51   作者:傻瓜傻了个瓜  
这篇文章主要给大家介绍了关于java读取Excel导入去除空行的简单方法,在日常开发中,想必都遇到过批处理的需求,文中给出了详细的示例代码,需要的朋友可以参考下

问题:

在Java读取Excel导入操作时, sheet.getLastRowNum()会统计带有格式的空白行,导致获取的最大行数不准确,数据导入失败。

解决:

在操作过程中删除存在样式的空白行

可通过将空白行(内容为空,但是存在样式)进行sheet.removeRow删除后

再调用getLastRowNum()进行行数统计,getAccuracyContextNum()方法中。

@Transactional(rollbackFor =  Exception.class)
	public Map<String,Object> importWeb(Workbook wb,String skillName,String skilltype,String office) {
		StringBuilder msg = new StringBuilder();
		Map<String, Object> reMap = new HashMap<>();
		Sheet sheet = wb.getSheetAt(0);
		Row titleRow = sheet.getRow(0);
		if (titleRow.getLastCellNum() != 3 || !"项目名称".equals(getCellValue(titleRow.getCell(0)))
				|| !"操作要点".equals(getCellValue(titleRow.getCell(1))) || !"总分".equals(getCellValue(titleRow.getCell(2)))){
			reMap.put("flag",false);
			reMap.put("msg","模板错误");
			return reMap;
		}
		//获取合并单元格信息的hashmap
		Map<String,Integer[]> mergedRegionMap = getMergedRegionMap(sheet);
		//拿到excel的最后一行的索引
//		int lastRowNum = sheet.getLastRowNum();
		sheet=getAccuracyContextNum(wb,mergedRegionMap);
		int lastRowNum=sheet.getLastRowNum();
		List<Map<String, Object>> projectNameList = new ArrayList<>();
		List<Map<String, Object>> mainPointsList = new ArrayList<>();
		//nursetrain_skill_oper表主键id
		String operId = IdGen.uuid();
		BigDecimal totalScore = new BigDecimal(0);
		//从excel的第二行索行开始,遍历到最后一行(第一行是标题,直接跳过不读取)
		for(int i = 1; i<=lastRowNum ; i++) {
			//拿到excel的行对象
			Row row = sheet.getRow(i);
			//获取excel的行中有多个列
			int cellNum = row.getLastCellNum();
			if (cellNum > 3){
				reMap.put("flag",false);
				reMap.put("msg","数据列超出标题范围");
				return reMap;
			}
			Map<String, Object> projectMap = new LinkedHashMap<>();
			Map<String, Object> mainPointsMap = new LinkedHashMap<>();
			//对每行进行列遍历,即一列一列的进行解析
			for(int j=0; j < cellNum; j++) {
				//拿到了excel的列对象
				Cell cell = row.getCell(j);
				//将列对象的行号和列号+下划线组成key去hashmap中查询,不为空说明当前的cell是合并单元列
				Integer[] firstRowNumberAndCellNumber = mergedRegionMap.get(i+"_"+j);
				//如果是合并单元列,就取合并单元格的首行和首列所在位置读数据,否则就是直接读数据
				if(firstRowNumberAndCellNumber != null) {
					Row rowTmp = sheet.getRow(firstRowNumberAndCellNumber[0]);
					Cell cellTmp = rowTmp.getCell(firstRowNumberAndCellNumber[1]);
					if (j == 0 ){
						projectMap.put("NAME", getCellValue(cellTmp));
						if(StringUtils.isEmpty(getCellValue(cellTmp))) {
							msg.append("第").append(i + 1).append("行项目名称不能为空").append("<br>");
						}
					}
					if (j == 1){
						mainPointsMap.put("NAME", getCellValue(cellTmp));
						if(StringUtils.isEmpty(getCellValue(cellTmp))) {
							msg.append("第").append(i + 1).append("行操作要点不能为空").append("<br>");
						}
					}
					if (j == 2){
						mainPointsMap.put("SCORE", getCellValue(cellTmp));
						if(StringUtils.isEmpty(getCellValue(cellTmp))) {
							msg.append("第").append(i + 1).append("行总分不能为空").append("<br>");
						}else{
							try{
								BigDecimal score = new BigDecimal(getCellValue(cellTmp)).setScale(2,RoundingMode.DOWN);
								totalScore = totalScore.add(score);
							}catch (Exception e){
								msg.append("第").append(i + 1).append("行总分只能为数字").append("<br>");
							}
						}
					}
					mainPointsMap.put("order", i);
				}else{
					if (j == 0 ){
						projectMap.put("NAME", getCellValue(cell));
						if(StringUtils.isEmpty(getCellValue(cell))) {
							msg.append("第").append(i + 1).append("行项目名称不能为空").append("<br>");
						}
					}
					if (j == 1){
						mainPointsMap.put("NAME", getCellValue(cell));
						if(StringUtils.isEmpty(getCellValue(cell))) {
							msg.append("第").append(i + 1).append("行操作要点不能为空").append("<br>");
						}
					}
					if (j == 2){
						mainPointsMap.put("SCORE", getCellValue(cell));
						if(StringUtils.isEmpty(getCellValue(cell))) {
							msg.append("第").append(i + 1).append("行总分不能为空").append("<br>");
						}else {
							try{
								BigDecimal score = new BigDecimal(String.valueOf(getCellValue(cell))).setScale(2,RoundingMode.UP);
								totalScore = totalScore.add(score);
							}catch (Exception e){
								msg.append("第").append(i + 1).append("行总分只能为数字").append("<br>");
							}
						}
					}
					mainPointsMap.put("order", i);
				}
			}
			``````
		try {
			//插入nursetrain_skill_oper表
			//插入nursetrain_skill_oper_item表
			//插入nursetrain_skill_oper_item_step表
			reMap.put("flag",true);
			reMap.put("msg","导入成功");
		}catch (Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			reMap.put("flag",false);
			reMap.put("msg","导入失败,请联系系统管理员");
		}
		return reMap;
	}
//获取准确的文件行数
	public Sheet getAccuracyContextNum(Workbook workbook,Map<String,Integer[]> mergedRegionMap) {
		// 取第一个sheet
		Sheet sheet = workbook.getSheetAt(0);
		// 删除空行
		for (int i = 0; i <= sheet.getLastRowNum(); i++) {
			Row row = sheet.getRow(i);
			int cellNum = row.getLastCellNum();
			boolean flag=false;
			for(int j=0; j < cellNum; j++) {
				Integer[] firstRowNumberAndCellNumber = mergedRegionMap.get(i+"_"+j);
				if(firstRowNumberAndCellNumber != null){
					flag=true;
				}
			}
			if (this.isRowEmpty(row) && !flag) {
			// 删除空行
			if (this.isRowEmpty(row)) {
				int lastRowNum = sheet.getLastRowNum();
				if (i >= 0 && i < lastRowNum) {
					sheet.shiftRows(i + 1, lastRowNum, -1);// 将行号为i+1一直到行号为lastRowNum的单元格全部上移一行,以便删除i行
				}
				if (i == lastRowNum) {
					if (row != null) {
						sheet.removeRow(row);
					}
				}
				i--;
			}
		}
		return sheet;
	}
	/**
	 * 判断是否有空行
	 * @param row
	 * @return
	 */
	private  boolean isRowEmpty(Row row) {
		for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
			Cell cell = row.getCell(c);
			if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK) {
				return false;
			}
		}
		return true;
	}
	//将存在合并单元格的列记录入put进hashmap并返回
	public Map<String,Integer[]> getMergedRegionMap(Sheet sheet){
		Map<String,Integer[]> result = new HashMap<String,Integer[]>();
		//获取excel中的所有合并单元格信息
		int sheetMergeCount = sheet.getNumMergedRegions();
		//遍历处理
		for (int i = 0; i < sheetMergeCount; i++) {
			//拿到每个合并单元格,开始行,结束行,开始列,结束列
			CellRangeAddress range = sheet.getMergedRegion(i);
			int firstColumn = range.getFirstColumn();
			int lastColumn = range.getLastColumn();
			int firstRow = range.getFirstRow();
			int lastRow = range.getLastRow();
			//构造一个开始行和开始列组成的数组
			Integer[] firstRowNumberAndCellNumber = new Integer[]{firstRow,firstColumn};
			//遍历,将单元格中的所有行和所有列处理成由行号和下划线和列号组成的key,然后放在hashmap中
			for(int currentRowNumber = firstRow; currentRowNumber <= lastRow; currentRowNumber++) {
				for(int currentCellNumber = firstColumn; currentCellNumber <= lastColumn; currentCellNumber ++) {
					result.put(currentRowNumber+"_"+currentCellNumber, firstRowNumberAndCellNumber);
				}
			}
		}
		return result;
	}

总结

到此这篇关于java读取Excel导入去除空行的文章就介绍到这了,更多相关java导入Excel去除空行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中的异常和处理机制实例详解

    Java中的异常和处理机制实例详解

    这篇文章主要介绍了Java中的异常和处理机制,结合实例形式详细分析了Java异常与处理机制的相关概念、原理、用法及操作注意事项,需要的朋友可以参考下
    2019-05-05
  • Spring Boot高效数据聚合之道深入讲解

    Spring Boot高效数据聚合之道深入讲解

    这篇文章主要给大家介绍了关于Spring Boot高效数据聚合之道的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • SchedulingConfigurer实现动态定时,导致ApplicationRunner无效解决

    SchedulingConfigurer实现动态定时,导致ApplicationRunner无效解决

    这篇文章主要介绍了SchedulingConfigurer实现动态定时,导致ApplicationRunner无效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 解决javaBean规范导致json传参首字母大写将永远获取不到问题

    解决javaBean规范导致json传参首字母大写将永远获取不到问题

    这篇文章主要介绍了解决javaBean规范导致json传参首字母大写将永远获取不到问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java maven中如何引入自己的lib

    java maven中如何引入自己的lib

    在JavaMaven项目中引入自己的库可以简化为几个步骤:首先,确保库以JAR格式存在或打包成JAR;其次,将JAR文件放置在项目目录或安装到本地Maven仓库;最后,在pom.xml中添加依赖,这样做可以使项目更加模块化,便于管理和维护,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • Java 线程池核心参数、执行流程与实战建议全解析

    Java 线程池核心参数、执行流程与实战建议全解析

    主要介绍了 Java 线程池:核心参数、执行流程与实战建议,我将用最通俗的方式带你搞懂 Java 线程池,从构造函数开始,讲透执行机制、参数配置,再结合我在真实项目中的使用经验,总结出一套实战建议,需要的朋友可以参考下
    2025-04-04
  • Java 判断线程池所有任务是否执行完毕的操作

    Java 判断线程池所有任务是否执行完毕的操作

    这篇文章主要介绍了Java 判断线程池所有任务是否执行完毕的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Spring事务管理中关于数据库连接池详解

    Spring事务管理中关于数据库连接池详解

    事务的作用就是为了保证用户的每一个操作都是可靠的,事务中的每一步操作都必须成功执行,只要有发生异常就 回退到事务开始未进行操作的状态。事务管理是Spring框架中最为常用的功能之一,我们在使用Spring Boot开发应用时,大部分情况下也都需要使用事务
    2022-12-12
  • JAVA8获取list集合中重复的元素与获取去重数据实例

    JAVA8获取list集合中重复的元素与获取去重数据实例

    这篇文章主要给大家介绍了关于JAVA8获取list集合中重复的元素与获取去重数据的相关资料,在实际开发中经常会遇到需要找出(删除)一个list中某些元素的属性相同的元素,需要的朋友可以参考下
    2023-07-07
  • DoytoQuery中的查询映射方案详解

    DoytoQuery中的查询映射方案详解

    这篇文章主要为大家介绍了DoytoQuery中的查询映射方案详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论