前面寫過一篇HSSF(實際上就是Poi)實現Excel導出的隨筆,正好最近也有做導入的需求,那么就索性再寫一篇Poi導入Excel的隨筆吧。
其實,poi導入Excel和Poi導出Excel在實現步驟上是大同小異的,但是做這個之前,有一個問題需要搞清楚,Excel文件的分類,Excel有2003板,后綴為.xls和2007板,后綴為.xlsx,而Poi解析這兩種文件的時候,使用的類是不同的,前者使用的是HSSFWorkBook,后者是XSSFWorkBook;
搞清楚了這個,接下來就可以開始Excel的導入操作了
第一步,將這個Excel文件讀取成為一份WorkBook(假使得到是一個文件)
WorkBook mWorkBook = null;
String fileName = file.getName();
String type = fileName.split(fileName.lastIndexOf(".")+1,fileName.length);
FileInputStream mStream = new FileInputStream(file);
mWorkBook = "xls".equals(type) ? new HSSFWorkBook(mStream) : new XSSFWorkBook(mStream);
第二步,得到對應的sheet頁,並得到行和列的數據
Sheet sheet0 = mWorkBook.getSheetAt(0);
Row row0 = sheet0.getRow(0);
int rowNum = sheet0.getLastRowNum();
int columeNum = row0.getPhysicalNumberOfCells();
得到了總的行數和列數,接下來就可使用 雙重for循環對沒個單元格的內容進行獲取;
為了避免遺忘,還是舉個例子吧,有一張記錄人信息的Excel表格,表格有3列,分別是name,age,sex
那么你可以建立一個實體類Person,擁有name,age,sex三個屬性
好了,接下來就進行數據的讀取儲存
List<Person> list = new ArrayList<>();
Person person;
for(int i = 1 ; i<rowNum ; i++){
Row row = sheet0.getRow(i);
for(int j = 0; j<columeNum ; j++){
Cell cell = row.getCell(j);
person = new Person();
swich(j){
case 1 :
person.setName(cell.getStringCellValue());
break;
case 2 :
person.setAge(cell.getNumericCellValue());
break;
case 3 :
person.setSex(cell.getStringCellValue());
}
list.add(person);
}
}
這樣完成了對Excel的解析
在這里要說一個比較蛋疼的問題,那就是Excel單元格的格式,通過上面的例子看到了,不同格式的單元格的內容的獲取,Poi提供的接口是不一樣的,數字類型的getNumericCellValue,文本類型的getStringCellValue,當然還有boolean類型和Date類型等,這么多的類型,如果使用的API不對,那么就GG了。
對於一些可以有明確的格式的單元格還好,如姓名一看就是文本類型,年齡是數字類型,這些獲取的時候可以明確的知道要用哪個,但是還有一些如日期,用起來就有點蛋疼了;
獲取你會說,日期啊,當然是文本類型了,那么我只能說錯,大錯特錯,雖然開始我也是這么以為的,但只要稍微的驗證一下就會發現,在不對單元格格式作出規定時,合法的日期格式諸如: 1月1日,2017/1/1,2017-1-1 這些,單元格內容的獲取要是用getNumericCellValue, 但是不合法的日期格式,如:13月1日,2017/13/1等,單元格內容的獲取又變為了getStringCellValue,
當然在不需要對日期的格式進行校檢的情況下,這也不是什么大問題,可以使用如下方法進行獲取
try{
cell.getNumericCellValue();
}catchh(Exception e){
cell.getStringCellValue();
}
但是如果要對日期格式進行校驗,如規定你輸入的格式需要是2017/1/1、2017/01/01類似的,上面的方法就行不通了,你會發現,你寫在Excel中的日期2017/01/01在通過getNumericCellValue之后變成了float類型的數據。這就很操蛋了,日期的格式丟失了,雖然可以使用SimpleDateFormat重新轉化為日期格式,但是,顯然這是一個新的格式,校檢這個毫無意義啊。
這就尷尬了,我暫時沒有發現什么辦法可以進行校檢,不過最后的解決辦法就是,我來提供你填寫Excel的模板,在模板中規定,你的這一列數據的數據格式為文本
CellStyle style = mWorkBook.createCellStyle();
HSSFDataFormat format = mWorkBook.createDataFormat();
style.setDataFormat(format.getFormat("@"));
sheet1.setDefaultColumeStyle(index,style);
好了,有了模板,日期的格式就被固定為了文本,這樣獲取的時候統一使用getStringCellValue(),這樣日期的格式也不會丟失了,而且,導出的模板規定了文件的類型,也可以不為到底使用XSSFWorkBook還是HSSFWorkBook作區分了;