在SSM下使用POI解析Excel資料並實現批量匯入到資料庫
暑假實習期間,作為一名Java後臺開發的小白實習生,專案組老大分發給我的一項任務就是實現在SSM下實現Excel資料的匯入/匯出
,咱總不能手動Ctrl+C/Ctrl+V實現吧hhh,於是經過查閱資料,發現Apache的一個子專案POI可以幫助解析Office文件並實現需求。分享如下:
Apache POI是Apache軟體基金會的開源專案,POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。本例中主要使用其中的兩個包:HSSF提供讀寫Microsoft Excel XLS(2003版本)格式檔案的功能。XSSF提供讀寫Microsoft Excel OOXML XLSX(2007版本)格式檔案的功能。
1、下載POI
首先進入POI首頁:http://poi.apache.org/`,之後點選download進入下載頁。
下載一個3.16二進位制版,即編譯版,不想自己編譯,畢竟麻煩。圖中兩個下載版本的區別在於壓縮格式不同,請擇一下載。
2、解壓POI並加入專案lib中
若未參考文件,咱不知道需要哪些包匯入,so先一股腦兒匯入專案。全部解壓後如下:
測試專案架構如下:
3、設定測試環境
在本例中未編寫上傳Excel表的功能,僅在jsp頁面上點選,後臺處理器讀取特定位置的Excel檔案,然後解析,入庫。
3.1 、在MySql資料庫中建表
3.2 、建立Excel表
為了測試2003和2007兩個版本,建立不同版本的測試表:
表內容如下:
3.3、jsp頁面中設定觸發操作
3.4、生成Mapper檔案
資料庫中的資料表有新添成員people表,so重新配置下mybatis.generator然後重新生成新的mapper和pojo:
在專案中得到對應people表的mapper類和pojo類:
3.5、編寫解析入庫處理器
下面開始編寫處理器,這裡簡化處理,直接在handler中完成所有操作。更好地作法是在service層完成解析入庫的工作。
3.5.1、2003版本處理
@Autowired
PeopleMapper peopleMapper;
@RequestMapping("readXLS" )
public String readXLS() {
InputStream is = null;
HSSFWorkbook hssfWorkbook = null;
try {
// 1 開啟Excel檔案
is = new FileInputStream("d:\\excel\\people.xls");
// 2 通過POI的工作薄類解析xls檔案
hssfWorkbook = new HSSFWorkbook(is);
} catch (Exception e) {
is = null;
e.printStackTrace();
}
if (is == null)
return "failed";
// 3 建立people物件準備接收資料
People people = new People();
// 4 迴圈工作表Sheet,一個excel中可能有多個sheet
for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
if (hssfSheet == null) {
continue;
}
// 迴圈行Row,一個sheet中可以有多行
for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
// 取得當前行的資料
HSSFRow hssfRow = hssfSheet.getRow(rowNum);
if (hssfRow != null) {
// 獲取單元格物件
HSSFCell id = hssfRow.getCell(0);
HSSFCell name = hssfRow.getCell(1);
HSSFCell sex = hssfRow.getCell(2);
HSSFCell birthday = hssfRow.getCell(3);
HSSFCell workday = hssfRow.getCell(4);
// 全部先作為字串資料提取出來
String idstr = getValue(id);
String namestr = getValue(name);
String sexstr = getValue(sex);
String birthdaystr = getValue(birthday);
String workdaystr = getValue(workday);
try {
// 轉換並賦值給people
// id是long型別
people.setId(Long.parseLong(idstr));
// name是String型別
people.setName(namestr);
// sex是Boolean型別
if (sexstr.equals("男")) {
people.setSex(true);
} else if (sexstr.equals("女")) {
people.setSex(false);
}
// birthday是日期型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
people.setBirthday(sdf.parse(birthdaystr));
people.setWorkday(sdf.parse(workdaystr));
// 入庫
peopleMapper.insert(people);
} catch (Exception e) {
}
} // 結束不為空的行的處理
} // 結束迴圈處理row
} // 結束迴圈處理sheet
// 關閉EXCEL表
try {
hssfWorkbook.close();
} catch (Exception e) {
}
return "success";
}
//對應版本讀取資料的函式
private String getValue(HSSFCell hssfCell) {
if (hssfCell.getCellTypeEnum() == CellType.BOOLEAN) {
// 返回布林型別的值
return String.valueOf(hssfCell.getBooleanCellValue());
} else if (hssfCell.getCellTypeEnum() == CellType.NUMERIC) {
// 返回數值型別的值,日期型別的資料在EXCEL表中也是數值型
String cellValue = "";
if (HSSFDateUtil.isCellDateFormatted(hssfCell)) { // 判斷是日期型別
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
Date dt = HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue());// 獲取成DATE型別
cellValue = dateformat.format(dt);
} else {
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(hssfCell.getNumericCellValue());
}
return cellValue;
} else if (hssfCell.getCellTypeEnum() == CellType._NONE) {
return "";
} else if (hssfCell.getCellTypeEnum() == CellType.BLANK) {
return "";
} else if (hssfCell.getCellTypeEnum() == CellType.STRING) {
// 返回字串型別的值
return String.valueOf(hssfCell.getStringCellValue());
}
return null;
}
3.5.1、2007版本處理
@RequestMapping("readXLSX")
public String readXLSX() {
InputStream is = null;
XSSFWorkbook xssfWorkbook = null;
try {
// 1 開啟Excel檔案
is = new FileInputStream("d:\\excel\\people.xlsx");
// 2 通過POI的工作薄類解析xls檔案
xssfWorkbook = new XSSFWorkbook(is);
} catch (Exception e) {
is = null;
e.printStackTrace();
}
if (is == null)
return "failed";
// 3 建立people物件準備接收資料
People people = new People();
// 4 迴圈工作表Sheet,一個excel中可能有多個sheet
for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
if (xssfSheet == null) {
continue;
}
// 迴圈行Row,一個sheet中可以有多行
for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
// 取得當前行的資料
XSSFRow xssfRow = xssfSheet.getRow(rowNum);
if (xssfRow != null) {
// 獲取單元格物件
XSSFCell id = xssfRow.getCell(0);
XSSFCell name = xssfRow.getCell(1);
XSSFCell sex = xssfRow.getCell(2);
XSSFCell birthday = xssfRow.getCell(3);
XSSFCell workday = xssfRow.getCell(4);
// 全部先作為字串資料提取出來
String idstr = getXValue(id);
String namestr = getXValue(name);
String sexstr = getXValue(sex);
String birthdaystr = getXValue(birthday);
String workdaystr = getXValue(workday);
try {
// 轉換並賦值給people
// id是long型別
people.setId(Long.parseLong(idstr));
// name是String型別
people.setName(namestr);
// sex是Boolean型別
if (sexstr.equals("男")) {
people.setSex(true);
} else if (sexstr.equals("女")) {
people.setSex(false);
}
// birthday是日期型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
people.setBirthday(sdf.parse(birthdaystr));
people.setWorkday(sdf.parse(workdaystr));
// 入庫
peopleMapper.insert(people);
} catch (Exception e) {
}
} // 結束不為空的行的處理
} // 結束迴圈處理row
} // 結束迴圈處理sheet
// 關閉EXCEL表
try {
xssfWorkbook.close();
} catch (Exception e) {
}
return "success";
}
//對應版本讀取資料的函式
private String getXValue(XSSFCell xssfCell) {
if (xssfCell.getCellTypeEnum() == CellType.BOOLEAN) {
// 返回布林型別的值
return String.valueOf(xssfCell.getBooleanCellValue());
} else if (xssfCell.getCellTypeEnum() == CellType.NUMERIC) {
// 返回數值型別的值,日期型別的資料在EXCEL表中也是數值型
String cellValue = "";
if (HSSFDateUtil.isCellDateFormatted(xssfCell)) { // 判斷是日期型別
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
Date dt = HSSFDateUtil.getJavaDate(xssfCell.getNumericCellValue());// 獲取成DATE型別
cellValue = dateformat.format(dt);
} else {
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(xssfCell.getNumericCellValue());
}
return cellValue;
} else if (xssfCell.getCellTypeEnum() == CellType._NONE) {
return "";
} else if (xssfCell.getCellTypeEnum() == CellType.BLANK) {
return "";
} else if (xssfCell.getCellTypeEnum() == CellType.STRING) {
// 返回字串型別的值
return String.valueOf(xssfCell.getStringCellValue());
}
return null;
}
3.6、觸發操作
將專案部署到tomcat上啟動index.jsp 並觸發響應的操作,DB中的資料表有以下變化:
former:
latter:
感謝各位看官閱讀本例,若有疑問,歡迎留言討論,嘻嘻。