poi解析excel,將每一行數據注入到對應的entity實體對象對象中

賊好用的代碼,直接上遼

/**測試用的實體類**/
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章