当前位置:网站首页>如何正确计算导入Excel的行数(POI/NPOI)
如何正确计算导入Excel的行数(POI/NPOI)
2022-06-23 12:57:00 【罗马苏丹默罕默德】
前言:
在一些具体的业务实现中经常要使用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;
else
return 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"));
//28
System.out.println(book.getSheetAt(0).getLastRowNum());
//24
System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());
//8
System.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 ;
边栏推荐
- 64 channel PCM telephone optical transceiver 64 channel telephone +2-channel 100M Ethernet telephone optical transceiver 64 channel telephone PCM voice optical transceiver
- Gradle Build Cache引发的Task缓存编译问题怎么解决
- TUIKit 音视频低代码解决方案导航页
- Overview of national parks in the United States
- Dataset之GermanCreditData:GermanCreditData数据集的简介、下载、使用方法之详细攻略
- 那些技术实战中的架构设计方法
- Online text filter less than specified length tool
- Generics, generic defects and application scenarios that 90% of people do not understand
- 20 years' Shanghai station D question Walker (two points, concise)
- Oracle中dbms_output.put_line怎么使用
猜你喜欢

"Four highs" of data midrange stability | startdt Tech Lab 18

2-optical-2-electric cascaded optical fiber transceiver Gigabit 2-optical-2-electric optical fiber transceiver Mini embedded industrial mine intrinsic safety optical fiber transceiver

Hanyuan high tech new generation green energy-saving Ethernet access industrial switch high efficiency energy-saving Gigabit Industrial Ethernet switch

CRMEB 二开短信功能教程

Simplify deployment with openvino model server and tensorflow serving

构建英特尔 DevCloud

The two 985 universities share the same president! School: true

C语言的基本数据类型及其打印输出

#yyds干货盘点# 解决剑指offer: 判断是不是平衡二叉树

Hanyuan hi tech 1-channel gigabit optical port to 4-channel Gigabit Ethernet electrical port Gigabit 1-optical 4-electric optical fiber transceiver
随机推荐
64 channel PCM telephone optical transceiver 64 channel telephone +2-channel 100M Ethernet telephone optical transceiver 64 channel telephone PCM voice optical transceiver
在线文本过滤小于指定长度工具
理解ADT与OOP
白皮书丨英特尔携手知名RISC-V工具提供商Ashling,着力扩展多平台RISC-V支持
深入剖析MobileNet和它的变种
. Net how to use log framework NLog
OpenVINOTM 2022.1中AUTO插件和自动批处理的最佳实践
What is the reason why maxcompute is sometimes particularly slow to execute SQL queries
[Yunzhou said live room] - digital security special session will be officially launched tomorrow afternoon
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
Restcloud ETL resolves shell script parameterization
How about stock online account opening and account opening process? Is it safe to open a mobile account?
Qunhui 10 Gigabit network configuration and test
First exposure! The only Alibaba cloud native security panorama behind the highest level in the whole domain
Meta said that the UK security law will "scan all private information", which risks infringing on users' privacy
Cifar announces the second stage pan Canadian AI strategy
Architecture design methods in technical practice
R language uses matchit package for propensity matching analysis (set the matching method as nearest, match the control group and case group with the closest propensity score, 1:1 ratio), and use matc
有向图D和E
Online text filter less than specified length tool