POI解析.xlsx格式的Excel文件
聲明:POI版本較多,在使用前,一定要確認版本再進行使用。
目標:寫一個解析.xlsx格式Excel文件工具類
環境準備:
① poi-4.0.1:可在POI官網上直接進入下載頁面進行下載;
② JDK1.8;
③ 自行準備一個.xlsx格式Excel文件用於測試
霸氣小學三年級二班語文成績單
學號 | 姓名 | 班級 | 成績 | 是否及格 | 出生日期 | 年齡 | 性別 | 備註 |
---|---|---|---|---|---|---|---|---|
101001 | 趙的 | 三年級二班 | 93.5 | TRUE | 1990/1/1 | 29 | 男 | |
101002 | 錢有 | 三年級二班 | 86.5 | TRUE | 1990/1/2 | 29 | 男 | |
101003 | 孫有 | 三年級二班 | 79 | TRUE | 1990/1/3 | 29 | 男 | |
101004 | 李折 | 三年級二班 | 96 | TRUE | 1990/1/4 | 29 | 男 | |
101005 | 周克 | 三年級二班 | 76 | TRUE | 1990/1/5 | 29 | 男 | |
101006 | 吳睥 | 三年級二班 | 86 | TRUE | 1990/1/6 | 29 | 男 | 壞學生 |
101007 | 鄭卡拉 | 三年級二班 | 84.5 | TRUE | 1990/1/7 | 29 | 男 | |
101008 | 王紫氣 | 三年級二班 | 86.5 | TRUE | 1990/1/8 | 29 | 男 | |
101009 | 馮和 | 三年級二班 | 80.5 | TRUE | 1990/1/9 | 29 | 男 | |
101010 | 陳中 | 三年級二班 | 54 | FALSE | 1990/1/10 | 29 | 男 | 請假中 |
101011 | 褚淡 | 三年級二班 | 86.5 | TRUE | 1990/1/11 | 29 | 女 |
一、創建一個javaProject工程:test:
二、在工程中創建一個文件夾並命名爲lib,然後將poi所需jar包導入進來,如下圖所示。導入後記得將所有jar包Build Path。
本文使用的POI版本爲4.0.1,所必需的jar包有:
序號 | 架包 |
---|---|
1 | commons-collections4-4.2.jar |
2 | commons-compress-1.18.jar |
3 | poi-4.0.1.jar |
4 | poi-ooxml-4.0.1.jar |
5 | poi-ooxml-schemas-4.0.1.jar |
6 | xmlbeans-3.0.2.jar |
不同版本可能所需的jar包存在差異。
三、在工程中創建一個文件夾並命名爲resources,並將準備好的excel文件放入其中,如上圖所示。
四、創建一個工具類PoiUtil.java,代碼如下:
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class PoiUtil {
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
/**
* 獲取Excel第一個sheet頁的數據,返回二維數組,默認從第一行開始讀取
*
* @param excelPath excel文件路徑
* @return
* @throws Exception
*/
public static String[][] getExcelRows(String excelPath) throws Exception {
return getExcelRows(excelPath, 0);
}
/**
* 獲取Excel第一sheet的數據,返回二維數組
*
* @param excelPath excel文件路徑
* @param startRowIndex 從第幾行的下標開始讀取(第1行的下標爲0)
* @return
* @throws Exception
*/
public static String[][] getExcelRows(String excelPath, int startRowIndex)
throws Exception {
// 下標必須大於等於0
if (startRowIndex < 0) {
throw new Exception("無效的下標:[" + startRowIndex + "]");
}
// 指定excel文件必須存在
if (!new File(excelPath).exists()) {
throw new Exception("指定文件不存在:[" + excelPath + "]");
}
// 獲取excel文件總列數,總行數,並由這兩個數據定義一個二維數組用以存放解析出來的excel數據
int lastRowNum = 0;// 最後 一行的下標,該下標加1即爲總行數
int lastCellNum = 0;// 最後一列的下標
String[][] objList = null;
InputStream is = null;
Workbook workbook = null;
try {
// 獲取文件流
is = new FileInputStream(excelPath);
// 使用XSSFWorkbook將xlsx格式文件輸入流轉換成Workbook接口,之後就可通過該接口操作excel文件 的讀取了
workbook = new XSSFWorkbook(is);
// 獲取第一個sheet頁
Sheet sheet = workbook.getSheetAt(0);
// 最後一行的下標,從0開始
lastRowNum = sheet.getLastRowNum();
// 最後一列的下標,從0開始
if (lastRowNum != 0) {
lastCellNum = sheet.getRow(0).getLastCellNum();
} else {
// excel沒有數據
return new String[0][0];
}
objList = new String[lastRowNum-startRowIndex+1][lastCellNum+1];
// 遍歷每行
Row row = null;
for (int i = startRowIndex; i <= lastRowNum; i++) {
row = sheet.getRow(i);
// 遍歷每一列
String[] colArrays = new String[lastCellNum + 1];
for (int j = 0; j <= lastCellNum; j++) {
colArrays[j] = getCellValue(row.getCell(j));
}
objList[i - startRowIndex] = colArrays;
}
} catch (Exception e) {
throw e;
} finally {
if (workbook != null) {
workbook.close();
}
if (is != null) {
is.close();
}
}
return objList;
}
/**
* 獲取單元格的值,返回字符串類型
*
* @param cell
* @return
* @throws Exception
*/
private static String getCellValue(Cell cell) throws Exception {
if (cell == null) {
return null;
}
String cellValue = null;
// 獲取單元格類型,CellType爲枚舉類型。(在低版本時,getCellType得到的可能是整數,所以在這裏體現出版本差異)
CellType cellType = cell.getCellType();
// 根據單元格類型獲取單元格的值
if (CellType.BLANK == cellType) {
cellValue = null;
} else if (CellType.STRING == cellType) {
cellValue = cell.getStringCellValue().trim();
} else if (CellType.BOOLEAN == cellType) {
cellValue = String.valueOf(cell.getBooleanCellValue());
} else if (CellType.NUMERIC == cellType) {
// 日期類型則轉換成yyyy-MM-dd格式字符串
if (DateUtil.isCellDateFormatted(cell)) {
cellValue = sdf.format(cell.getDateCellValue());
} else {
// 數字類型先轉換成字符串類型,再獲取字符串
cell.setCellType(CellType.STRING);
cellValue = cell.getStringCellValue().trim();
}
} else {
throw new Exception("獲取單元格失敗!");
}
return cellValue;
}
在該工具類中創建一個main方法,並測試
public static void main(String[] args) throws Exception {
String[][] rows = PoiUtil.getExcelRows("resources/student.xlsx", 2);
for (int i = 0; i < rows.length; i++) {
String[] row = rows[i];
for (int j = 0; j < row.length; j++) {
System.out.print(row[j] + "\t");
}
System.out.println();
}
}
運行結果:
101001 趙的 三年級二班 93.5 true 1990-01-01 29 男 null
101002 錢有 三年級二班 86.5 true 1990-01-02 29 男 null
101003 孫有 三年級二班 79 true 1990-01-03 29 男 null
101004 李折 三年級二班 96 true 1990-01-04 29 男 null
101005 周克 三年級二班 76 true 1990-01-05 29 男 null
101006 吳睥 三年級二班 86 true 1990-01-06 29 男 壞學生
101007 鄭卡拉 三年級二班 84.5 true 1990-01-07 29 男 null
101008 王紫氣 三年級二班 86.5 true 1990-01-08 29 男 null
101009 馮和 三年級二班 80.5 true 1990-01-09 29 男 null
101010 陳中 三年級二班 54 false 1990-01-10 29 男 請假中
101011 褚淡 三年級二班 86.5 true 1990-01-11 29 女 null