Excel读取并数据List/Map-POI

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 该Java工具类通过POI解析Excel文件,利用反射将每行数据映射为VO对象,并存入全局Map。支持日期、数字等类型处理,适用于.xls格式模板,需确保VO属性与列数一致并生成set/get方法。

1. 全局输出Map

反射的VO2. 全局输出List

Java

运行代码复制代码

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;

   }



import org.apache.poi.hssf.usermodel.HSSFCell;

} 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. 模板为   *.xls4. 模板列数和VO要保持一致,否则反射时候代码校验不通过

相关文章
|
easyexcel Java Maven
使用EasyExcel实现CSV文件读写功能,
使用EasyExcel实现CSV文件读写功能,顺手使用Idea创建SpringBoot工程集成swagger3
2661 0
使用EasyExcel实现CSV文件读写功能,
|
11月前
|
关系型数据库 MySQL 数据库
什么是事务以及事务的四大特性?
事务是数据库操作的基本单元,具有ACID四大特性:原子性、一致性、隔离性、持久性。它确保数据的正确性与完整性。并发事务可能引发脏读、不可重复读、幻读等问题,数据库通过不同隔离级别(如读未提交、读已提交、可重复读、串行化)加以解决。MySQL默认使用可重复读级别,兼顾性能与数据一致性需求。
648 3
|
6月前
|
人工智能 机器人 Java
黑马最新项目
AIGC项目涵盖大模型私有化部署、聊天机器人、RAG知识库及代码提示工具;天机AI集成SpringAI与多模型工作流;云岚到家聚焦微服务与分布式架构;四方保险构建统一支付与时序数据应用;星辰WMS与Dify项目即将发布。
384 0
黑马最新项目
|
6月前
|
缓存
QLExpress使用及源码分析
本文介绍基于QLExpress的规则引擎实现方案,涵盖实体构建、接口定义与脚本编写。通过@QLAlias注解映射字段别名,结合YAML配置规则表达式,实现逻辑解耦。运行时动态解析AST语法树,支持汉化变量与上下文绑定,并提供缓存与延迟执行机制,提升性能与灵活性。
141 0
QLExpress使用及源码分析
|
6月前
|
存储 关系型数据库 MySQL
微服务原理篇(XXLJOB-幂等-MySQL)
本文介绍了XXL-JOB任务调度的优势、组成结构及热点商品缓存更新任务的实现,涵盖幂等性概念与解决方案,并深入解析了MySQL存储引擎特性、索引失效场景、回表与覆盖索引原理以及SQL调优和分库分表策略。
318 0
微服务原理篇(XXLJOB-幂等-MySQL)
|
6月前
|
人工智能 NoSQL 前端开发
面试真题
汇总多套AI与后端技术面试题,涵盖RAG、微服务、JVM、分布式锁、MySQL优化、大模型部署等核心技术点,深入考察候选人项目经验、系统设计能力及对AI工程化的理解。
332 0
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
大模型专业名词解释手册
本手册由油炸小波设计提示词、Manus创作,系统梳理大语言模型核心概念,涵盖基础原理、训练技术、优化压缩、推理应用、评估调试及伦理安全六大模块,深入浅出解析LLM关键技术术语。
674 0
|
6月前
|
人工智能 自然语言处理 API
全面认识MCP:大模型连接真实世界的“USB-C接口”
MCP(模型上下文协议)是Anthropic推出的开放标准,被誉为AI时代的“USB-C”。它统一了大模型与工具、数据源的连接方式,简化集成,提升安全与扩展性,推动AI智能体实现复杂任务自动化,正重塑全球AI应用生态。
1084 0
|
6月前
|
Arthas 存储 运维
记Arthas实现一次CPU排查与代码热更新
本文介绍使用Arthas排查Java应用CPU占用过高问题的完整流程,涵盖线程分析、阻塞定位、watch命令追踪异常、jad反编译实现热更新及火焰图分析,实现无需重启应用的高效故障排查与代码修复。
248 0
|
12月前
|
消息中间件 缓存 固态存储
说一说 Java 中的内存映射(mmap)
我是小假 期待与你的下一次相遇 ~
363 1
说一说 Java 中的内存映射(mmap)

热门文章

最新文章