Excel解析數據,反射封裝到類POI工具類

import com.test.ExcelVO;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.DateUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ParseExcelUtil {

    // 解析後存放的全局Map
    public static Map<String, DoctorForExcelVO> STATIC_MAP = new HashMap<>();

    private static String val = null;

    private static SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");

    private static DecimalFormat df = new DecimalFormat("0");

    private static HSSFWorkbook wb;

    // 文件路徑
    private final static String IMPORT_EXCEL_NAME = "D:Excel_Data.xls";

    /**
     * 列數傳入,解決列情況: X,X,,X讀取列數爲3
     **/
    private static int colNum = 20;

    // 開始行數
    private static int startRowNum = 3;

    // sheet座標
    private static int index = 1;

    /**
     * @return
     */
    public static Map<String, DoctorForExcelVO> readExcelData() {

        FileInputStream file = null;
        POIFSFileSystem ts;
        // 讀取默認清除上一次數據
        JGPT_DOCTOR_MAP.clear();
        try {
            file = new FileInputStream(DOCTOR_IMPORT_EXCEL_NAME);
            ts = new POIFSFileSystem(file);
            wb = new HSSFWorkbook(ts);
            // 獲取表
            HSSFSheet sheet = wb.getSheetAt(index);
            // 獲取行數
            int rowNum = sheet.getPhysicalNumberOfRows();
            HSSFRow row;
            for (int i = startRowNum - 1; i < rowNum; i++) {
                List<String> list = new ArrayList<>();
                // 每行
                row = sheet.getRow(i);
                // 每列
                for (int j = 0; j < colNum; j++) {
                    HSSFCell cell = row.getCell(j);
                    list.add(getXcellVal(cell));
                }
                String key = list.get(3);
                if (StringUtils.isEmpty(key)) {
                    continue;
                }
                JGPT_DOCTOR_MAP.put(key, listToModel(list, new DoctorForExcelVO()));
            }
            return JGPT_DOCTOR_MAP;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != file) {
                    file.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 類型轉換與數據解析
     *
     * @param cell
     * @return
     */
    private static String getXcellVal(HSSFCell cell) {

        if (null == cell) {
            return "";
        }
        switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    // 日期型
                    val = fmt.format(cell.getDateCellValue());
                } else {
                    // 數字型
                    val = df.format(cell.getNumericCellValue());
                }
                break;
            // 文本類型
            case HSSFCell.CELL_TYPE_STRING:
                val = cell.getStringCellValue();
                break;
            // 公式特殊處理
            case HSSFCell.CELL_TYPE_FORMULA:
                try {
                    val = String.valueOf(cell.getStringCellValue());
                } catch (IllegalStateException e) {
                    val = String.valueOf(cell.getNumericCellValue());
                }
                break;
            // 空
            case HSSFCell.CELL_TYPE_BLANK:
                val = cell.getStringCellValue();
                break;
            /** 布爾 **/
            case HSSFCell.CELL_TYPE_BOOLEAN:
                val = String.valueOf(cell.getBooleanCellValue());
                break;
            /** 錯誤 **/
            case HSSFCell.CELL_TYPE_ERROR:
                val = "ERROR..CHECK DATA";
                break;
            default:
                val = cell.getRichStringCellValue() == null ? null : cell
                        .getRichStringCellValue().toString();
        }

        return val;
    }

    /**
     * 反射填充屬性
     *
     * @param list 數據集
     * @param vo   被反射的對象
     * @return
     * @throws Exception
     */
    private static DoctorForExcelVO listToModel(List<String> list, DoctorForExcelVO vo) throws Exception {
        Field[] fields = vo.getClass().getDeclaredFields();
        if (list.size() != fields.length) {
            return null;
        }
        for (int k = 0, len = fields.length; k < len; k++) {
            // 根據屬性名稱,找尋合適的set方法
            String fieldName = fields[k].getName();
            String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase()
                    + fieldName.substring(1);
            Method method = null;
            Class<?> clazz = vo.getClass();
            try {
                method = clazz.getMethod(setMethodName, new Class[]{list.get(k).getClass()});
            } catch (SecurityException e1) {
                e1.printStackTrace();
                return null;
            } catch (NoSuchMethodException e1) {
                String newMethodName = "set" + fieldName.substring(0, 1).toLowerCase()
                        + fieldName.substring(1);
                try {
                    method = clazz.getMethod(newMethodName, new Class[]{list.get(k).getClass()});
                } catch (SecurityException e) {
                    e.printStackTrace();
                    return null;
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                    return null;
                }
            }
            if (method == null) {
                return null;
            }
            method.invoke(vo, new Object[]{list.get(k)});
        }
        return vo;
    }

反射的VO

@Data
public class DoctorForExcelVO {

    private String organ_code;
    private String organ_name;
    private String remark;
}

注意點:

1. VO一定要生成set/get方法,我這裏藉助的@Data註解實現,也可以直接手動生成

2. 我這裏Excel讀取行數,列數是寫死的,建議作爲入參介入【我這裏業務場景特殊】

3. 模板爲   *.xls

代碼是經過多次驗證的,放心使用

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