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

代码是经过多次验证的,放心使用

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