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