前言:

在一些具体的业务实现中经常要使用Excel作为数据的来源,或者导出一些Excel。
一般我们都是使用POI(Java)/NPOI(.Net)来读取或写入相关的数据。
这个月接手别人的模块,在模块中需要频繁的导入导出Excel操作,在给那些‘测试’对接时,经常出现导入失败的情况,非常烦人。
这大概率是POI/NPOI的行数和实际导入的Excel有效行数不一样造成的

问题再现

这里以下面的一个Excel为例

这个Excel没有改格式也没有加空格,它的行数统计如下

XSSFWorkbook book = new XSSFWorkbook(new FileInputStream("src/Test.xlsx"));
//结果为8,sheet最后的一行有数据行的行数(从0开始算)
System.out.println(book.getSheetAt(0).getLastRowNum());
//结果为9,sheet实际有数据的总行数
System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());

这里随便插入一行再运行便可再次测试

XSSFWorkbook book = new XSSFWorkbook(new FileInputStream("src/Test.xlsx"));
//结果为12
System.out.println(book.getSheetAt(0).getLastRowNum());
//结果为10
System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());

1.空格造成的行数错误

导入者不仔细造成的多余空格行通常是这种错误的原因。
模拟:我在黑框处添加了空格

这次会得到

XSSFWorkbook book = new XSSFWorkbook(new FileInputStream("src/Test.xlsx"));
//15
System.out.println(book.getSheetAt(0).getLastRowNum());
//11
System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());

这样,当在程序中使用判断行数的方法时便会出现偏差,导致异常及错误
像是

  • 获取没有值的单元格的值-------------------------------空指针
  • 获取一些空格的值进入Sql参数------------------------Sql语句错误

2.格式造成的行数错误

请注意,有些情况下,导入的Excel的Sheet中存在不同的格式,并不是所有的导入都是默认的通用格式,

当我选定一片区域改成别的格式的时候,POI判断的长度也会改变

SSFWorkbook book = new XSSFWorkbook(new FileInputStream("src/Test.xlsx"));
//18
System.out.println(book.getSheetAt(0).getLastRowNum());
//19
System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());

有些时候对某些行列改变格式,也会造成POI的行数错误。
(之前在工作中就有过经历,约定以文本的格式导入Excel,结果不知道什么原因,有人用文本格式拉了几千行,
DEBUG的时候看到NPOI的获取Sheet的行数上千就非常的懵逼)

结论:
故决定不用POI/NPO提供的获取行数的API,必须自己手动计算一下,不然保不齐对接的时候一堆奇奇怪怪的导入出错

手动计算行数

POI

手动计算Sheet的长度要做到一定正确也需要一定的规则
我们一般
默认导入Excel的Sheet里的数据不要有中断的空行,即Excel的数据行从首行(一般是列名)开始,一直连续

所以我们只需要判断单元格的值是否为Null或者是空格(多个空格)且一直连续了多少行,
下面给出测试代码

/****  前言:如果你有自己常用的String处理方法,或者框架里的字符串工具,你完全可以不使用下面的流操作判断是否为空字符串
* * @param sheet          表* @param StartNum       数据开始的行号(即除去你的表头占的行数,真正的数据从哪行开始的)* @param RequireCol_index  必要数据列的列号(导入Excel中任意一个不为空列的列号即可)* @return Excel的sheet的有效行数*/
public static int GetRealRowNum(Sheet sheet,int StartNum,int RequireCol_index) {int Count = 0;//这里第一个条件可以判断单元格非空,第二个则利用流操作去判断是否其中所有的字符全是空字符或空格字符。 while(sheet.getRow(StartNum).getCell(RequireCol_index)!=null&&!ToList(sheet.getRow(StartNum).getCell(RequireCol_index).toString().toCharArray()).stream().allMatch((Character item)->{if(item.equals(' ')||item.toString().equals(""))return true;elsereturn false;})){//用Count计算有效长度StartNum++;Count++;}}catch (Exception e) {}return Count;}public  static List<Character> ToList(char[] charArray){List<Character> chars = new ArrayList<Character>(); for(int i=0;i<charArray.length;i++)chars.add(charArray[i]);return chars;}

测试一下,
还是上面那张被修改了格式的Excel

在里面随机埋了写空格,并选中一块敌法更改格式,得到的结果如下

public static void main(String[] args) throws IOException {XSSFWorkbook book = new XSSFWorkbook(new FileInputStream("src/Test.xlsx"));//28System.out.println(book.getSheetAt(0).getLastRowNum());//24System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());//8System.out.println(GetRealRowNum(book.getSheetAt(0), 1, 0));}

大多数情况下是可以用的,但实际的工作中肯定是使用字符串工具来判断是否为空格字符串或空字符串

//直接用字符串工具久非常的简单明了
while(sheet.getRow(StartNum).getCell(RequireCol_index)!=null&&!StringUtil.isBlank(sheet.getRow(StartNum).getCell(RequireCol_index).toString()))
{StartNum++;Count++;
}

结果也是上面一样。
注:(StringUtils/StringUtils有非常多的同名类,且方法也会各有不同。例子用到的是org.jsoup.internal.StringUtil)

NPOI

NPOI的使用方法也类似,

int start = 1,
count_row = 0;
try
{while (sheet.GetRow(start).GetCell(0) != null && !string.IsNullOrWhiteSpace((sheet.GetRow(start).GetCell(0).ToString())){count_row++;start++;}
}catch(Exception e)
{}
return count_row ;

如何正确计算导入Excel的行数(POI/NPOI)相关推荐

  1. R语言计算每个分组的行数并将结果添加到dataframe中实战

    R语言计算每个分组的行数并将结果添加到dataframe中实战 目录 R语言计算每个分组的行数并将结果添加到dataframe中实战 #仿真数据

  2. python一次读取10行_Python怎么读取Excel的行数和列数?

    在把数据写入Excel的过程中遇到了问题,写入的数据是for循环进去的,所以是分多次写入(每次for循环写入一次,一次有几十条数据). 但是在第二次for循环写数据时,就会覆盖掉第一次写的数据,就是后 ...

  3. python统计excel数据总行数_Python怎么读取Excel的行数和列数?

    在把数据写入Excel的过程中遇到了问题,写入的数据是for循环进去的,所以是分多次写入(每次for循环写入一次,一次有几十条数据). 但是在第二次for循环写数据时,就会覆盖掉第一次写的数据,就是后 ...

  4. 计算EXCEL的行数或列数

    如果您需要一种快捷方式来计算包含数据的行,请选择该数据第一列中的所有单元格(它可能不是列 A).只需单击列标题.Excel 窗口右下角的状态栏将提示您行数. 执行相同的操作来计算列,但这次应单击该行左 ...

  5. 用python计算Excel的行数及列数(自用)

    我自己觉得用pandans先读取表格之后去数Dataframe的行数与列数是一种比较快捷的方法 如下: import pandas as pd def count(filepath): data=pd ...

  6. excel统计行数_工程人常用的12个excel和9个wps技巧

    点击上方蓝字,记得关注我们! 搞工程的人要干的事,不只局限于在现场严格按照标准监督施工进行,还需要同时对收集到的资料进行收集整理,搞搞内业工作.然而很多人都是新上手,难免会对某些办公软件有些生涩. E ...

  7. excel统计行数_百万到亿级数据,快速统计查询

    大家好,我是dk.这是Excel神器PowerQuery实战入门系列的第3篇.往后,我会更新更多关于PQ的相关内容,有兴趣的小伙伴可以关注下. 众所周知,Excel2003版最大行数是65536行,到 ...

  8. excel统计行数_值得收藏的6个Excel函数公式(有讲解)

    收藏的Excel函数大全公式再多,几天不用也会忘记.怎么才能不忘?你需要了解公式的运行原理.小编今天不再推送一大堆函数公式,而是根据提问最多的问题,精选出6个实用的,然后详细的解释给大家. 1.计算两 ...

  9. 更改excel表格行数太多_excel表格数据行数太多-EXCEL显示太多行数据,导致文件过大,如何解决!...

    EXCEL显示太多行数据,导致文件过大,如何解决! 可以设置打印区 1.电脑打Excel表格. 2.打开Excel表格后,选中要打印的区后点入页面布局. 3.点击进入页面布局后,点击打印区域中的设置打 ...

  10. 如何将.TXT中的数据正确的导入excel表中

    将.txt中的文本:01 03 20 10 6C 19 22 10 6D 10 6B 10 6B 10 6B 10 6B 10 6A 10 6A 10 6A 10 6B 10 6B 10 6B 10 ...

最新文章

  1. 阿广自掏腰包,赠送8套鼠标键盘
  2. 530并行日:用超算更省心
  3. 一些知名的J2me优秀开源UI项目
  4. 《中国人工智能学会通讯》——6.16 基于统计的推理方法
  5. Pandas系列(十)Merge语法
  6. 同时使用SVN和Git进行版本控制
  7. 互联网日报 | 58同城签署私有化协议;支付宝将发放百亿全国通用消费券;碧桂园开天猫店上线特价商品房...
  8. 石家庄地铁站项目最终总结报告
  9. myBattery电池应用正式登陆WP8
  10. 简述完整的计算机组成部分组成部分组成,简述计算机系统的组成
  11. jieba.lcut()
  12. Windows 技术篇-安装指定版本Internet Explorer浏览器方法,IE浏览器的升级和降级
  13. Kali Linux渗透测试——WEB渗透(一)
  14. 2022年C等级考试九月二级真题E:反反复复
  15. 养车记账本小程序开发教程
  16. Java打印机如何加快打印速度_如何提升打印机打印速度
  17. 常见的USB接口种类以及区别
  18. matlab启动慢如龟爬!!终于知道咋办了。
  19. OpenCV+TensorFlow图片手写数字识别(附源码)
  20. 提供网上机票实时查询接口

热门文章

  1. VxWorks6.6开发共享库指南要点
  2. java并发编程——创建线程之Thread 和 Runnable
  3. 【读书分享】《解忧杂货店》东野圭吾
  4. ROS创建Publisher理解
  5. 双非大学计算机专业有不考408,2020河北大学计算机专业课改考408
  6. 蓝桥杯 算法训练 学做菜
  7. 搜索引擎市场份额2018.3
  8. 内网渗透靶场 Vulnstack(二)
  9. java 临时文件目录_在Java中使用临时文件/文件夹
  10. 小米平板2刷哪个系统更流畅_Windows 10版小米平板2简测:流畅度不及自家MIUI版...