代码实现
PropertyAnno.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.FIELD)//规定用于全局变量
@Retention(RetentionPolicy.RUNTIME)//定义为运行时注解
/**
* excel读取所用注解
* @author Administrator
*
*/
public @interface PropertyAnno { String value() default ""; }

  AnnoCreator.java

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* 注解解释工具类
* @author Administrator
*
*/
public class AnnoCreator { /**
* 注解解释方法
* @return Map<属性名(String), 注解名(String)>
*/
public static Map<String, String> annoCreator(Class<?> clazz) {
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
for (Field field : clazz.getDeclaredFields()) {
//获取属性上所有注解
Annotation[] annotations = field.getAnnotations();
//判断属性上是否存在注解
if(annotations.length < 1) {
continue;
}
//判断属性上是否存在需要注解
if(annotations[0] instanceof PropertyAnno) {
map.put(field.getName(), ((PropertyAnno)annotations[0]).value());
}
}
return map;
} }

  ReadExcel

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ReadExcel<T> { /**
* 错误信息
*/
private String errorMsg; /**
* 表格数据对象
*/
private Class<T> clazz; /**
* 改写初始化方法,将对象传入T
*/
@SuppressWarnings("unchecked")
public ReadExcel() {
@SuppressWarnings("rawtypes")
Class clazz = getClass();
while (clazz != Object.class) {
Type t = clazz.getGenericSuperclass();
if (t instanceof ParameterizedType) {
Type[] args = ((ParameterizedType) t).getActualTypeArguments();
if (args[0] instanceof Class) {
this.clazz = (Class<T>) args[0];
break;
}
}
clazz = clazz.getSuperclass();
}
} /**
* 根据文件名读取Excel文件
*
* @param filePath 文件完整路径
* @return Map<表名(sheet名,String), 表中的属性(List<T>)>
*/
public Map<String, List<T>> read(String filePath) {
Map<String, List<T>> map = null;
InputStream is = null;
try {
// 验证文件是否正确
if (!validateExcel(filePath)) {
System.out.println(errorMsg);
return null;
}
// 判断文件的类型,是2003还是2007
boolean isExcel2003 = true;
if (isExcel2007(filePath)) {
isExcel2003 = false;
}
// 创建流进行读取
File file = new File(filePath);
is = new FileInputStream(file);
// 根据版本选择创建Workbook的方式
Workbook workbook = null;
if (isExcel2003) {
workbook = new HSSFWorkbook(is);
} else {
workbook = new XSSFWorkbook(is);
}
map = readExcel(workbook);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (is != null) {
try {
// 关闭连接
is.close();
} catch (IOException e) {
is = null;
e.printStackTrace();
}
}
}
return map;
} /**
* 读取Excel表格
*/
@SuppressWarnings("deprecation")
private Map<String, List<T>> readExcel(Workbook workbook) {
Map<String, List<T>> map = Collections.synchronizedMap(new HashMap<>());
List<T> list = null;
// 获取表格数量
int numberOfSheets = workbook.getNumberOfSheets(); for (int sheetNum = 0; sheetNum < numberOfSheets; sheetNum++) {
list = new ArrayList<>();
// 获取注解
Map<String, String> creatorMap = AnnoCreator.annoCreator(clazz);
// 获取指定的Excel
Sheet sheet = workbook.getSheetAt(sheetNum);
// 获取Excel的行数
int totalRows = sheet.getPhysicalNumberOfRows();
// Excel的列数
int totalCells = 0;
if (totalRows >= 1 && sheet.getRow(0) != null) {
// 获取Excel的列数
totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
}
List<String> li = new ArrayList<>();
// 循环Excel的行
for (int r = 0; r < totalRows; r++) {
// 获取对象
T t = null;
try {
t = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
Row row = sheet.getRow(r);
if (row == null) {
continue;
}
// 遍历Excel的列
for (int c = 0; c < totalCells; c++) {
Cell cell = row.getCell(c);
String cellValue = "";
if (null != cell) {
// 判断数据的类型
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_NUMERIC: // 数字
DecimalFormat df = new DecimalFormat("0");
cellValue = df.format(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING: // 字符串
cellValue = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
cellValue = cell.getBooleanCellValue() + "";
break;
case HSSFCell.CELL_TYPE_FORMULA: // 公式
cellValue = cell.getCellFormula() + "";
break;
case HSSFCell.CELL_TYPE_BLANK: // 空值
cellValue = "";
break;
case HSSFCell.CELL_TYPE_ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
}
}
//此处可修改为自己的表格样式,例如打印第二行第二列的数据:
/* if(r == 1 && c == 1){
System.out.println(cellValue);
} */
if (r == 0) {
// 存储第一行数据(列名)
li.add(cellValue);
} else {
// 存储第一行后数据
fill(creatorMap, li.get(c), cellValue, t);
}
}
if (r != 0) {
list.add(t);
}
}
map.put(sheet.getSheetName(), list);
}
return map; } /**
* 判断是否Excel格式是否为2003
*/
private static boolean isExcel2003(String filePath) {
return filePath.matches("^.+\\.(?i)(xls)$");
} /**
* 判断是否Excel格式是否为2007
*/
private static boolean isExcel2007(String filePath) {
return filePath.matches("^.+\\.(?i)(xlsx)$");
} /**
* 验证Excel文件
*/
private boolean validateExcel(String filePath) { // 检查文件名格式是否正确
if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
System.out.println("文件名不是Excel格式");
return false;
}
// 检查文件是否存在
File file = new File(filePath);
if (file == null || !file.exists()) {
System.out.println("文件不存在");
return false;
}
return true;
} /**
* 为对象进行赋值
*
* @param map 注解map(注解=属性名)
* @param str 当前读取到的列名
* @param obj 当前读到的数据
* @param t 需要进行赋值的对象
*/
private void fill(Map<String, String> map, String str, String obj, T t) {
for (Entry<String, String> entry : map.entrySet()) {
try {
if (str.equals(entry.getValue())) {
// 为对象进行赋值
Field f = clazz.getDeclaredField(entry.getKey().trim());
f.setAccessible(true);
f.set(t, obj);
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
} }

  BasicsEntity.java

/**
* excel内容实体类(示例)
* 注意:实体类属性需定义为String类型
* @author Administrator
*
*/
public class BasicsEntity { @PropertyAnno("列名")//被注解字段与excel中列名对应
private String name;//字段名 @PropertyAnno("类型")
private String type;//字段类型 @PropertyAnno("长度")
private String length;//字段长度 @PropertyAnno("小数点长度")
private String decimal;//小数点长度 @PropertyAnno("默认值")
private String defaults;//默认值 @PropertyAnno("备注")
private String annotation;//备注 @PropertyAnno("是否为非空(Y或N)")
private String isNull;//是否为非空(Y或N) @PropertyAnno("是否为主键(Y或N)")
private String isPrincipal;//是否为主键(Y或N) @PropertyAnno("是否启用主键自增(Y或N)")
private String isProgressive;//是否启用主键自增(Y或N) @Override
public String toString() {
return "BasicsEntity [name=" + name + ", type=" + type + ", length=" + length + ", decimal=" + decimal
+ ", defaults=" + defaults + ", annotation=" + annotation + ", isNull=" + isNull + ", isPrincipal="
+ isPrincipal + ", isProgressive=" + isProgressive + "]";
}
}

  ReadTest.java

import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import com.myutils.entity.BasicsEntity;
/**
* 测试类
* @author Administrator
*/
public class ReadTest { public static void main(String[] args) {
//调用方法时必须写成以下格式,否则反射无法获取到实体类
ReadExcel<BasicsEntity> util = new ReadExcel<BasicsEntity>(){};
//调用方法,返回实体类集合
Map<String, List<BasicsEntity>> map = util.read("D:数据库文档\\测试表格.xlsx");
for (Entry<String, List<BasicsEntity>> baMap : map.entrySet()) {
System.out.println("表名:" + baMap.getKey().split("\\|")[0]);
System.out.println("表备注:" + baMap.getKey().split("\\|")[1]);
for (BasicsEntity basicsEntity : baMap.getValue()) {
System.out.println(basicsEntity.toString());
}
}
}
}

  

pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cn</groupId>
<artifactId>myExcel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.codec</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency> </dependencies>
</project>

  

测试使用表格:

JAVA读取EXCEL_自动生成实体类的更多相关文章

  1. Mybatis自动生成实体类

    Maven自动生成实体类需要的jar包 一.pom.xml中 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...

  2. Springboot mybatis generate 自动生成实体类和Mapper

    https://github.com/JasmineQian/SpringDemo_2019/tree/master/mybatis Springboot让java开发变得方便,Springboot中 ...

  3. Mybatis自动生成实体类、dao接口和mapping映射文件

    由于Mybatis是一种半自动的ORM框架,它的工作主要是配置mapping映射文件,为了减少手动书写映射文件,可以利用mybatis生成器,自动生成实体类.dao接口以及它的映射文件,然后直接拷贝到 ...

  4. .net core 中简单封装Dapper.Extensions 并使用sqlsuger自动生成实体类

    引言 由公司需要使用dapper  同时支持多数据库 又需要支持实体类 又需要支持sql 还需要支持事务 所以采用了 dapper + dapperExtensions  并配套 生成实体类小工具的方 ...

  5. 使用T4为数据库自动生成实体类

    T4 (Text Template Transformation Toolkit) 是一个基于模板的代码生成器.使用T4你可以通过写一些ASP.NET-like模板,来生成C#, T-SQL, XML ...

  6. Asp.Net Core如何根据数据库自动生成实体类

    通过引用Nuget包添加实体类 运行 Install-Package Microsoft.EntityFrameworkCore.SqlServer 运行 Install-Package Micros ...

  7. Mybatis自动生成实体类和实体映射工具

    Mybatis Mysql生成实体类 用到的Lib包: mybatis-generator-core-1.3.2.jarmysql-connector-java-5.1.30.jar 1. 创建一个文 ...

  8. serialVersionUID的作用以及如何用idea自动生成实体类的serialVersionUID

    转载:http://blog.csdn.net/liuzongl2012/article/details/45168585 serialVersionUID的作用: 通过判断实体类的serialVer ...

  9. mybatis根据表逆向自动化生成代码(自动生成实体类、mapper文件、mapper.xml文件)

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

随机推荐

  1. 新手上路之JDK11的下载、安装与PATH环境变量的配置

    目录 JDK11的下载 找到目标JDK JDK的下载 JDK11的安装 PATH环境变量的配置 为什么要配置环境变量? 配置前再检查一遍 配置变量 检查环境变量配置成功与否 细究起来,JDK11与JD ...

  2. vue中全局/按需引用element,样式都不生效

    简直是天坑啊,这个问题困扰了我一个晚上加今天一天,心里无数草泥马奔腾 被要求使用vue1.0+elementUI做一个后台管理项目,结果无论怎么操作elementUI,页面中都不显示css样式 谷歌百 ...

  3. NOIp2020游记

    Day 1 考点还是在南航,第三次去已经没有什么新鲜感了,满脑子都是NOIp能不能考好.考前奶了一波这次必考最短路,于是在试机的时候打了一遍Dij和SPFA的板子,信心满满的上场了. 考试右后方是Ki ...

  4. java并发编程实战《八》管程

    管程:并发编程的万能钥匙 为什么 Java 在 1.5 之前仅仅提供了 synchronized 关键字及 wait().notify().notifyAll() 这三个看似从天而降的方法? Java ...

  5. PyQt+moviepy音视频剪辑实战1:多个音视频合成顺序播放或同屏播放的视频文件实现详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...

  6. 第8.7节 Python类__new__方法和构造方法关系深入剖析:__new__方法执行结果对__init__的影响案例详解

    一. 引言 前面章节介绍了类中的构造方法和__new__方法,并分析了二者执行的先后顺序关系.__new__方法在__init__方法前执行,__new__方法执行后才返回实例对象,也就是说__new ...

  7. Python中自定义类未定义__lt__方法使用sort/sorted排序会怎么处理?

    在<第8.23节 Python中使用sort/sorted排序与"富比较"方法的关系分析>中介绍了排序方法sort和函数sorted在没有提供key参数的情况下默认调用 ...

  8. PyQt学习随笔:Model/View开发时从Model相关类派生自定义类需要注意的问题

    在<PyQt学习随笔:重写setData方法截获Model/View中视图数据项编辑的注意事项>介绍的方法,从Model相关类派生自定义类,通过重写setData方法以获取View中数据的 ...

  9. Xmind常用的快捷键

    1.Xmind常用的快捷键 DEL --删除 TAB--新增下一级主题 ENTER--新建同级主题 Ctrl+I--插入图片 Ctrl+f --查找.替换 空格--当前主题内容编辑 通过概要.格式.联 ...

  10. Java基础学习之数据类型、基础语法与数组(3)

    目录 1.数据类型 1.1.基本数据类型 1.2.引用数据类型 1.3.自动装箱与拆箱 2.基础语法 2.1.标识符 2.2.修饰符 2.2.1.访问控制修饰符 2.2.2.非访问控制修饰符 2.3. ...