標籤:style blog color 使用 sp java strong on 檔案
在POI中,我們可以通過Workbook, Sheet, Row, Cell 對象分別對應Excel檔案、工作表、行、儲存格。
在POI的使用中,我遇到了幾個非常詭異、捉摸不透的問題,現在記錄下來。
1、關於Sheet、Row、Cell的下標
一般情況下,我們讀取一個Excel表格是這樣的:
Workbook workbook = WorkbookFactory.create(file);Sheet sheet = workbook.getSheetAt(0); Row row = sheet.getRow(0);Cell cell = row.getCell(0);
在POI的API中,Sheet(工作表)、Row(行)、Cell(儲存格)都是從0開始的。
2、關於getPhysical*()、getLast*Num()方法
sheet.getPhysicalNumberOfRows(); //擷取此工作表中有效定義的行
row.getPhysicalNumberOfCells(); //擷取此行中有效儲存格數
sheet.getLastRowNum(); //擷取最後一行非NULL行的行下標
row.getLastCellNum(); //擷取最後一個非NULL儲存格的列下標,並加上1(所以雖然列是從0開始的,但是這裡得到的值是下標+1,需要注意)
getPhysical*()方法是指擷取有效定義的行數或列數,算的是一個數目。這裡的有效定義是指只要你曾經對此行或此儲存格進行過操作,無論是格式上的操作還是資料上的操作,那麼這以行或列就是有效。
我修改A2儲存格的儲存格格式為文本,那麼A2儲存格對於POI來說就是已定義的儲存格,無論之後對A2做什麼操作都不會改變這個事實。又如我對A2儲存格賦值,此時A2儲存格就是已定義的儲存格,即使我之後清除A2儲存格的值,但A2還是已定義的儲存格。
所以getPhysical*()方法可能會得到的行或儲存格可能沒有資料。
而getLast*Num()方法是擷取最後一個非NULL的行(儲存格)下標,算的是下標。它前面有可能行或儲存格有可能是NULL的,也就是不存在的。如:
NULL 1 NULL 2 3 NULL NULL 那麼getLastCellNum 擷取到的值就是5(列從1算起)
例如:表是一個4*4的Excel表格式資料
1 "" 3 4
null null null 3
null null null null
3 null 3 null
那麼sheet.getPhysicalNumberOfRows() = 3,因為雖然有4行,但是第3行全部是NULL,因此這一行是未定義的,所以只有3行。
sheet.getLastRowNum() = 3,最後以列非NULL行的行下標是第4行,即下標為3的行。
row.getPhysicalNumberOfCells() 第1行,有效儲存格數是4。第2行中,只有第4個儲存格是有效,因此有效儲存格數是1。第3行有效儲存格是0,第4行有效儲存格數是2。
row.getLastCellNum() 第1行中,值為4(下標為3,加1後值為4)。第2行,值為4。第3行,值為-1。第4行,值為3。(第3行沒有任何有效儲存格,所以返回-1)
POI 操作Excel疑痛點筆記