Excel读取并数据List/Map-POI

简介: Excel读取并数据List/Map-POI

1. 全局输出Map

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 "";
        }
        // 同上,如不希望截取数据,添加下面注释这行
        // 包路径import org.apache.poi.ss.usermodel.Cell;
        // cell.setCellType(Cell.CELL_TYPE_STRING);
        switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    // 日期型
                    val = fmt.format(cell.getDateCellValue());
                    // 上面如果删掉格式处理,这里统一转成String即可
                    // val = String.valueOf(cell.getDateCellValue());
                } else {
                    // 数字型
                    val = df.format(cell.getNumericCellValue());
                    // 上面如果删掉格式处理,这里统一转成String即可
                    // val = String.valueOf(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;
}

2. 全局输出List

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.List;
/**
 * @author herb
 * @version 1.0
 * @date 2020/6/9  10:01
 * @Desc 解析Excel模板
 */
public class ExcelForReturnListUtil {
    // 解析后存放的全局List
    public static List<User> OnlineDataList = new ArrayList<>();
    private static String val = null;
    // 这里的format同上,需要注意,否则会截取数据
    private static SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
    // 这里的format同上,需要注意,否则会截取数据
    private static DecimalFormat df = new DecimalFormat("0");
    private static HSSFWorkbook wb;
    // 文件路径
    private final static String IMPORT_EXCEL_NAME = "D:/DATA.xls";
    /**
     * 列数传入,解决列情况: X,X,,X读取列数为3
     **/
    private static int colNum = 16;
    // 开始行数
    private static int startRowNum = 3;
    // sheet坐标
    private static int index = 1;
    public static List<User> readExcelData() {
        FileInputStream file = null;
        POIFSFileSystem ts;
        // 读取默认清除上一次数据
        OnlineDataList.clear();
        try {
            file = new FileInputStream(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));
                }
                OnlineDataList.add(listToModel(list, new User()));
            }
            return OnlineDataList;
        } 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 "";
        }
        // 同上,如不希望截取数据,添加下面注释这行
        // 包路径import org.apache.poi.ss.usermodel.Cell;
        // cell.setCellType(Cell.CELL_TYPE_STRING);
        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 ImMedicalOnlineForUploadEntity listToModel(List<String> list, User 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;
    }

注意点:


1. VO一定要生成set/get方法,我这里借助的@Data注解实现,也可以直接手动生成


2. 我这里Excel读取行数,列数是写死的,建议作为入参介入【我这里业务场景特殊】


3. 模板为   *.xls


4. 模板列数和VO要保持一致,否则反射时候代码校验不通过

相关文章
|
26天前
|
SQL 缓存 easyexcel
面试官问10W 行级别数据的 Excel 导入如何10秒处理
面试官问10W 行级别数据的 Excel 导入如何10秒处理
52 0
|
1月前
|
安全 Java 数据库连接
jdbc解析excel文件,批量插入数据至库中
jdbc解析excel文件,批量插入数据至库中
21 0
|
1月前
|
Java API Apache
使用AOP+反射实现Excel数据的读取
使用AOP+反射实现Excel数据的读取
excel根据数据得出公式
excel根据数据得出公式
|
1月前
|
SQL 数据可视化 数据处理
使用SQL和Python处理Excel文件数据
使用SQL和Python处理Excel文件数据
54 0
|
11天前
|
索引 容器
06-python数据容器-list列表定义/list的10个常用操作/列表的遍历/使用列表取出偶数
06-python数据容器-list列表定义/list的10个常用操作/列表的遍历/使用列表取出偶数
|
19天前
使用Vant框架的组件van-pull-refresh搭配van-list和van-card完成上滑加载更多列表数据,下拉刷新当前列表数据(等同于翻页功能)
使用Vant框架的组件van-pull-refresh搭配van-list和van-card完成上滑加载更多列表数据,下拉刷新当前列表数据(等同于翻页功能)
|
1月前
|
安全 Java 数据库连接
jdbc实现批量给多个表中更新数据(解析Excel表数据插入到数据库中)
jdbc实现批量给多个表中更新数据(解析Excel表数据插入到数据库中)
154 0
|
1月前
|
存储 数据处理 Python
使用Python批量合并Excel文件的所有Sheet数据
使用Python批量合并Excel文件的所有Sheet数据
33 0
|
1月前
|
存储 数据处理 Python
使用openpyxl库从Excel文件中提取指定的数据并生成新的文件
使用openpyxl库从Excel文件中提取指定的数据并生成新的文件
29 0