賊好用的代碼,直接上遼
/**測試用的實體類**/
public class GameScene {
public int id;
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "GameScene{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
//取出方法引用
public class Ref<T> {
public T ref;
public T getRef() {
return ref;
}
public void setRef(T ref) {
this.ref = ref;
}
}
import org.apache.poi.hssf.usermodel.*;
import org.sq.gameDemo.svr.game.scene.model.GameScene;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class PoiUtil {
public static List readExcel(File file, int sheetNum, Class clazz) throws Exception{
//1.讀取Excel文檔對象
int fieldNum = clazz.getDeclaredMethods().length;
//將class的Field的名稱<name, setName()>記錄到map中
Map<String, Method> setMethodMap = new HashMap<>();
for (Field field : clazz.getDeclaredFields()) {
String name = field.getName();
Method setMethod = clazz.getDeclaredMethod(
"set" + String.valueOf(name.charAt(0)).toUpperCase()+ field.getName().substring(1),
field.getType());
setMethodMap.put(name, setMethod);
}
ArrayList excelData = new ArrayList<>();
HSSFWorkbook hssfWorkbook = null;
try {
hssfWorkbook = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet sheet = hssfWorkbook.getSheetAt(sheetNum);
int lastRowNum = sheet.getLastRowNum();
//Ref爲了將第一行標題取出來
Ref<List> listRef = new Ref<>();
getSingleRow(sheet, 0, setMethodMap, listRef, clazz);//<1,name>
//將每一行的數據注入到class實例中並保存在list中
for(int i = 1;i < lastRowNum; i++) {
excelData.add(getSingleRow(sheet, i, setMethodMap, listRef, clazz));
}
return excelData;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 根據傳入的clazz 將每一行的數據填充到clazz.instance的實例中,然後返回
* @param sheet
* @param rowNum 取第rownum行
* @param setMethod class中所有屬性對應set屬性方法的map映射;譬如class類中 public String name; 就會有-> <name, setName()>
* @param listRef 引用,從參數取方法中的某個局部變量的引用
* @param clazz 實例類變量
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchFieldException
*/
private static Object getSingleRow(HSSFSheet sheet, int rowNum, Map<String, Method> setMethod, Ref<List> listRef, Class clazz) throws Exception {
List<Object> rowData = new ArrayList<>();
Object instance = clazz.newInstance();
HSSFRow row = sheet.getRow(rowNum);
int lastCellNum = row.getLastCellNum() & '\uffff'; //盜poi的...
if(lastCellNum < setMethod.keySet().size()) {
System.out.println("第" + rowNum + "行數據缺失");
throw new Exception("PoiUtil -> excel文件有誤");
}
boolean titleRow = (rowNum == 0 && listRef.ref == null);
for(int j = 0; j < lastCellNum; j++) {
HSSFCell cell = row.getCell(j);
Object value;
if(titleRow) {
value = getValueFromCell(cell, String.class);
rowData.add(j, value);
} else {
//實例化Class對象,並注入數據
Field declaredField = clazz.getDeclaredField(String.valueOf(listRef.ref.get(j)));
Class<?> type = declaredField.getType();
value = getValueFromCell(cell, type);
setMethod.get(listRef.ref.get(j)).invoke(instance, value);
}
}
if(titleRow) {
listRef.ref = rowData;
}
return instance;
}
/**
* 獲取單元格內容
* @param cell 單元格
* @param expectClazz 期望的單元格內容的數據類型
* --這個其實用的比較取巧了....
* @return
*/
private static Object getValueFromCell(HSSFCell cell, Class expectClazz) {
Object value = null;
String typeName = expectClazz.getTypeName();
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
value = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_NUMERIC:
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
if (date != null) {
if(typeName.equals("String")) {
value = new SimpleDateFormat("yyyy-MM-dd").format(date);
}
if(typeName.equals("Date")) {
value = date;
}
} else {
value = null;
}
} else {
Double cellValue = cell.getNumericCellValue();
value = new DecimalFormat("0").format(cellValue);
if(typeName.equals("int") || typeName.equals("Integer")) {
value = Integer.valueOf(new DecimalFormat("0").format(cellValue));
}
if(typeName.equals("double") || typeName.equals("Double")) {
value = cellValue;
}
if(typeName.equals("float") || typeName.equals("Float")) {
value = cellValue.floatValue();
}
}
break;
case HSSFCell.CELL_TYPE_FORMULA:
// 導入時如果爲公式生成的數據則無值
if (!cell.getStringCellValue().equals("")) {
value = cell.getStringCellValue();
} else {
value = cell.getNumericCellValue() + "";
}
break;
case HSSFCell.CELL_TYPE_BLANK:
break;
case HSSFCell.CELL_TYPE_ERROR:
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
value = cell.getBooleanCellValue();
break;
default:
value = null;
}
return value;
}
//-----------------------測試代碼
public static void main(String[] args) {
try {
List list = readExcel(new File("C:\\code\\sence.xls"), 0, GameScene.class);
list.forEach(sence->{
System.out.println(sence.toString());
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
結果截圖
挺好用的其實…本着開源精神,特此貢獻
|
|
|
|
author : kevins | qq : 276368974
|
|
|
|
end