POI文件解析 一行一说明 傻瓜式使用
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExcelTools {
/**
* 根据sheet下标获取对应的数据并跳过第一行
* @param fileAction
* @param cls
* @param fileName
* @param sheetIndex
* @param skipTop
* @return
*/
public static List readExcel(String fileAction,Class cls,String fileName[],Integer sheetIndex,Integer skipTop){
return readExcel( fileAction, cls, fileName, null,sheetIndex, skipTop);
}
/**
* 根据sheet名获取对应的数据并跳过第一行
* @param fileAction
* @param cls
* @param fileName
* @param sheetName
* @param skipTop
* @return
*/
public static List readExcel(String fileAction,Class cls,String fileName[],String sheetName,Integer skipTop){
return readExcel( fileAction, cls, fileName, sheetName,null, 1);
}
/**
*
* @param fileAction 文件路径
* @param cls model
* @param fileName model中的属性
* @param sheetName sheet名
* @param sheetIndex sheet的下标
* @param skipTop 是否跳过头信息 0是不跳过 1是跳过
* @return
*/
private static List readExcel(String fileAction,Class cls,String fileName[],String sheetName,Integer sheetIndex,Integer skipTop){
FileInputStream is = null;
// 读取Sheet中的数据
List data = new ArrayList();
try {
// 首先利用反射先获取所有的方法
Method[] methods = cls.getDeclaredMethods();
Map methodMap = new HashMap<>();
for (Method m : methods) {
// 将获取的类的方法循环存入map中 后续可以直接使用方法名取出方法
methodMap.put(m.getName().toUpperCase(),m);
}
// 开始读取excel文件
is = new FileInputStream(new File("D://新建.xlsm"));
Workbook workbook = null;
// 下方对应两种文件格式
if (fileAction.endsWith("xlsm"))
{
workbook = new XSSFWorkbook(is);//xlsm
}
else
{
workbook = new HSSFWorkbook(is);//xls
}
//
Sheet sheet = null;
if (sheetName != null){
sheet = workbook.getSheet(sheetName);
}else {
sheet = workbook.getSheetAt(sheetIndex);
}
// 获取总行数(最后一行下表)
int rowNum = sheet.getLastRowNum();
// 循环每行数据
// ! i = skipTop 是否跳过第一行(头信息)
for (int i = skipTop; i < rowNum; i++) {
// 将传来的类利用反射实例化
Object clsObj = cls.newInstance();
// 获取每行数据
Row row = sheet.getRow(i);
for (int j = 0; j < row.getLastCellNum(); j++) {
// 获取每一行的每一列数据
Cell cell = row.getCell(j);
// 反射参数 #来自河南大表哥i !>对将 excel中的数据类型转换为java中的数据类型 转换方法在下方
Object cellParseTypeValue = ExcelTools.getCellParseTypeValue(cell, workbook);
// 反射具体的某一个方法 !这个地方是根据参数穿来的属性名数组调用方法
Method tempMethod = (Method)methodMap.get("SET"+fileName[j].toUpperCase());
tempMethod.invoke(clsObj,cellParseTypeValue);
}
data.add(clsObj);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally {
try {
is.close();
}catch (Exception e){
e.printStackTrace();
}
}
return data;
}
public static Object getCellParseTypeValue(Cell cell, Workbook workbook){
if (cell == null){
return "";
}
if (cell.getCellType() == CellType.STRING){ //字符型
return cell.getRichStringCellValue().getString();
}else if (cell.getCellType() == CellType.NUMERIC){ // poi数值型 !poi数值型中包含java中的日期类型和 浮点以及整数型
if (DateUtil.isCellDateFormatted(cell)){//如果是日期型则返回日期型
return cell.getDateCellValue();
}else { //数值型
// 数值型 如何区分整数和小数
// 可以想把数值型读取成 字符型数据 看(判断)字符串中是否包含小鼠点 如果包含小数点 则是小数
HSSFDataFormatter hssfDataFormatter = new HSSFDataFormatter();
String cellValue = hssfDataFormatter.formatCellValue(cell);
if (cellValue.indexOf(".") == -1 ){
return new Integer(cellValue);
}
return new Double(cellValue);
}
}else if (cell.getCellType() == CellType.FORMULA){//公式型
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
return evaluator.evaluate(cell).getNumberValue()+"";
}else if (cell.getCellType()== CellType.BOOLEAN){//boolean型
return cell.getBooleanCellValue();
}else {
return "";
}
}
// 3.另一个版本判断excel类型所用 可百度
// CELL_TYPE_NUMERIC 数值型 0
// CELL_TYPE_STRING 字符串型 1
// CELL_TYPE_FORMULA 公式型 2
// CELL_TYPE_BLANK 空值 3
// CELL_TYPE_BOOLEAN 布尔型 4
// CELL_TYPE_ERROR 错误 5
}
调用测试 .class参数 是对应的封装类.class 数组是参数名 使用的反射后续会调用get set方法
public static void main(String[] args) throws Exception {
List list1 = ExcelTools.readExcel("D:\\新建.xlsm", ExcelEntity.class, new String[]{"name", "workId", "workMoney", "goOut"},1,0);
}
poi解析版本间有差异 如果类型转换部分爆红就看类中的最下方被注释的那一部分
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.4</version>
</dependency>
深受没注释又看不懂还懒得百度的苦 很认真的分享也给自个留个备忘