当前位置:网站首页>如何正确计算导入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 ;
边栏推荐
- Simplify deployment with openvino model server and tensorflow serving
- Common usage of OS (picture example)
- AGCO AI frontier promotion (6.23)
- Online text entity extraction capability helps applications analyze massive text data
- How to enable the SMS function of alicloud for crmeb knowledge payment
- 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
- 怎么手写vite插件
- Hanyuan high tech USB2.0 optical transceiver USB2.0 optical fiber extender USB2.0 optical fiber transmitter USB2.0 interface to optical fiber
- 在线文本过滤小于指定长度工具
- PHP handwriting a perfect daemon
猜你喜欢

怎么手写vite插件

Lm05 former VIX (second generation product)

Can cold plate, submerged and spray liquid cooling lead the development of high-performance computing?

实战监听Eureka client的缓存更新

Architecture design methods in technical practice

Homekit supports the matter protocol. What does this imply?

618的省钱技术攻略 来啦 -体验场景 领取10元猫超卡!

在線文本過濾小於指定長度工具

Multi-Camera Detection of Social Distancing Reference Implementation
React query tutorial ④ - cache status and debugging tools
随机推荐
通过 OpenVINO Model Server和 TensorFlow Serving简化部署
同花顺网上开户安全吗,需要注意什么
R language uses the multinom function of NNET package to build a disordered multi classification logistic regression model, uses regression coefficients and their standard errors to calculate the valu
What a talented company that can turn SAP system into a chicken rib!
R language dplyr package arrange function sorts dataframe data and sorts dataframe data through multiple data columns (ascending sort by default)
Hanyuan high tech new generation green energy-saving Ethernet access industrial switch high efficiency energy-saving Gigabit Industrial Ethernet switch
How to write vite plug-ins
windows 安装 MySQL
20000 words + 30 pictures | MySQL log: what is the use of undo log, redo log and binlog?
64 channel PCM telephone optical transceiver 64 channel telephone +2-channel 100M Ethernet telephone optical transceiver 64 channel telephone PCM voice optical transceiver
In flinksql, the Kafka flow table and MySQL latitude flow table are left joined, and the association is made according to I'd. false
Go写文件的权限 WriteFile(filename, data, 0644)?
MySQL single database and table splitting using MYCAT
Architecture design methods in technical practice
First exposure! The only Alibaba cloud native security panorama behind the highest level in the whole domain
互联网技术发展内卷后的出路——iVX的诞生
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
前AMD芯片架构师吐槽,取消 K12 处理器项目是因为 AMD 怂了!
Restcloud ETL resolves shell script parameterization
Service stability governance