Excel读取并数据List/Map-POI

简介: 该工具类基于POI解析.xls格式Excel,通过反射将每行数据映射为Java对象,支持日期、数字等类型处理,可全局输出Map或List,适用于固定模板的数据导入场景,需确保列数与VO字段一致。
  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;
}

  1. 全局输出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 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 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 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要保持一致,否则反射时候代码校验不通过

目录
相关文章
|
9月前
|
NoSQL Linux Shell
2-MongoDB单机部署
本文介绍MongoDB在Windows和Linux系统中的安装启动方法,包括下载、解压、配置数据目录及启动方式(命令行或配置文件)。支持32/64位系统,推荐使用稳定版。可通过mongo shell连接,也可使用图形化工具Compass。Linux下需注意权限与防火墙设置,并可采用标准方式安全关闭服务。
249 0
|
9月前
|
存储 NoSQL 关系型数据库
MongoDB相关概念
MongoDB是一款高性能、无模式的文档型NoSQL数据库,适用于高并发、海量数据、高扩展性场景。适用于社交、游戏、物联网、物流、视频直播等应用,擅长处理数据量大、读写频繁、事务要求不高的业务。支持BSON格式,灵活存储复杂数据,提供丰富查询、索引、分片和副本集功能,实现高效读写与水平扩展,相比MySQL可大幅降低开发运维成本。
97 0
|
9月前
|
XML 存储 SQL
SpringBoot整合Logback,滚动记录+多文件
logback-spring.xml配置文件实现日志分级输出,支持控制台、文件滚动存储,按模块(如SQL、支付、任务等)分离日志,通过LogProxy获取指定名称的Logger,便于定位问题。配置灵活,适用于多环境部署。
179 0
|
9月前
|
缓存 Ubuntu Linux
Docker安装
本文介绍在CentOS系统上安装Docker的完整步骤,包括卸载旧版本、配置阿里云镜像源、安装最新或指定版本的Docker引擎,并启动服务。同时涵盖Ubuntu系统的安装方法及离线安装方式,支持配置系统服务、daemon.json参数、日志管理与命令补全,最后通过`hello-world`验证安装成功。
368 0
|
9月前
|
JSON Linux 数据格式
Registry搭建docker私仓
Docker Registry是官方提供的私有镜像仓库构建工具。通过拉取registry镜像并运行容器,可快速搭建私服。需配置daemon.json启用http支持,重启Docker后,使用tag和push命令上传镜像,通过curl验证内容,实现私有化镜像管理。
298 0
|
9月前
|
Java Maven 数据安全/隐私保护
Nexus仓库
本文介绍Nexus Repository Manager OSS在Linux环境下的安装与配置,包括JDK8安装、Nexus部署、仓库管理、用户权限设置及密码重置方法。支持通过Docker快速部署,并实现数据持久化。同时涵盖Maven、NPM、Docker等组件的私服搭建与资源上传下载配置,助力企业构建高效私有仓库体系。(239字)
770 0
|
9月前
|
Java 大数据 Apache
Excel工具-HUTOOL-输出Excel
基于Hutool与Apache POI,封装Excel写入功能,提供ExcelWriter和BigExcelWriter,支持List、Map、Bean等数据类型导出,可自定义样式、多Sheet操作,并避免内存溢出,适用于高效生成Excel文件及Web下载场景。
453 0
|
9月前
|
Apache
Excel工具-HUTOOL-读取Excel
基于Hutool和Apache POI,封装Excel读取工具,支持读取为List、Map或Bean;提供SAX模式高效解析大文件,避免内存溢出,适用于Excel 2003/2007格式,支持按行处理数据。
390 0
|
9月前
|
缓存 Java 开发工具
QLExpress使用及源码分析
QLExpress是阿里巴巴开源的轻量级规则引擎,支持通过YAML配置规则脚本,结合注解实现Java方法与表达式映射。通过别名机制、AST解析和上下文赋值,实现灵活的动态逻辑执行,适用于复杂业务规则场景。
310 0
|
9月前
|
安全 Linux Shell
Docker镜像
镜像是包含软件运行所需代码、依赖库、配置等的轻量级可执行包。Docker利用联合文件系统实现分层结构,通过bootfs和rootfs构成镜像底层,支持镜像共享与复用。容器启动时在镜像顶层添加可写容器层,所有修改仅作用于该层,保障镜像安全与高效。
206 0