当前位置:网站首页>How to correctly calculate the number of rows imported into EXCEL (poi/npoi)

How to correctly calculate the number of rows imported into EXCEL (poi/npoi)

2022-06-23 13:43:00 Roman Sultan Mohammed

Preface :

It is often used in some specific business implementations Excel As a source of data , Or export some Excel.
We usually use it POI(Java)/NPOI(.Net) To read or write relevant data .
Take over other people's modules this month , Frequent import and export are required in the module Excel operation , For those ‘ test ’ When docking , Import failures often occur , It's very annoying .
The big probability is POI/NPOI The number of rows and the actual imported Excel The number of effective rows is different

Problem reproduction

Here is the following one Excel For example
 Please add a picture description
This Excel There is no format change or space addition , Its row count is as follows

XSSFWorkbook book = new XSSFWorkbook(new FileInputStream("src/Test.xlsx"));
// The result is 8,sheet The last row has the number of data rows ( from 0 Start counting ) 
System.out.println(book.getSheetAt(0).getLastRowNum());
// The result is 9,sheet The total number of rows with actual data  
System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());

Just insert a line here and run it to test again
 Please add a picture description

XSSFWorkbook book = new XSSFWorkbook(new FileInputStream("src/Test.xlsx"));
// The result is 12 
System.out.println(book.getSheetAt(0).getLastRowNum());
// The result is 10 
System.out.println(book.getSheetAt(0).getPhysicalNumberOfRows());

1. Wrong number of lines caused by spaces

Extra white space lines caused by careless importers are often the cause of this error .
simulation : I added a space in the black box
 Please add a picture description
This time you will get

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());

such , When the method of judging the number of lines is used in the program, there will be deviation , Cause exceptions and errors
Like

  • Get the value of a cell without a value ------------------------------- Null pointer
  • Get the value of some spaces to enter Sql Parameters ------------------------Sql sentence in wrong

2. Wrong number of lines due to format

Please note that , In some cases , Imported Excel Of Sheet There are different formats in , Not all imports are in the default common format ,
 Please add a picture description
When I select an area and change it to another format ,POI The length of judgment will also change
 Please add a picture description

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());

Sometimes you change the format for certain rows and columns , Can also cause POI Wrong number of rows for .
( I have had experience in my work before , Convention to import... In text format Excel, As a result, I don't know why , Someone pulled thousands of lines in text format ,
DEBUG I see NPOI Acquisition Sheet The number of lines is thousands, which is very silly )

Conclusion :
So I decided not to POI/NPO Of the number of rows provided API, You have to calculate it manually , Otherwise, there will be a lot of strange import errors during incomplete docking

Calculate the number of rows manually

POI

Manual calculation Sheet The length of must be correct and also need certain rules
We generally
The default import Excel Of Sheet There should be no interrupted blank lines in the data , namely Excel From the first row ( Generally, it is column name ) Start , All the time
 Please add a picture description
So we just need to determine whether the value of the cell is Null Or a space ( Multiple spaces ) And how many lines have been continuous ,
Here is the test code

/*** *  Preface : If you have your own String processing method , Or string tools in the framework , You can determine whether the string is empty without using the following stream operation  * * @param sheet  surface  * @param StartNum  The line number at the beginning of the data ( That is, remove the number of rows occupied by your header , Which line does the real data start from ) * @param RequireCol_index  The column number of the required data column ( Import Excel The column number of any non empty column in ) * @return Excel Of sheet Number of valid rows  */
public static int GetRealRowNum(Sheet sheet,int StartNum,int RequireCol_index) {
    
		int Count = 0;

		   
		    // The first condition here can judge that the cell is not empty , The second one uses stream operation to determine whether all characters are empty characters or space characters . 
			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;
					})
					)
			{
    
				// use Count Calculate effective length 
				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;
	}

Test it ,
The format of the above one has been modified Excel
 Please add a picture description
There are random spaces in it , And select a piece of enemy method to change the format , The result is as follows

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));
	
}

It can be used in most cases , But in actual work, it must be used String tool to determine whether it is a blank string or an empty string .

// Using the string tool directly is very simple and clear 
while(sheet.getRow(StartNum).getCell(RequireCol_index)!=null&&
	!StringUtil.isBlank(sheet.getRow(StartNum).getCell(RequireCol_index).toString()))
{
    
	StartNum++;Count++;
}

The result is the same as above .
notes :(StringUtils/StringUtils There are many classes with the same name , And the methods will be different . The example uses org.jsoup.internal.StringUtil)

NPOI

NPOI The method of using is similar ,

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 ;
原网站

版权声明
本文为[Roman Sultan Mohammed]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206231256554861.html

随机推荐