前言

代码是我师父的,代码是我师父的,代码是我师父的,如有需要拿走的时候请标注  copyright by 山人Wu  记录这篇是为了加深理解,前段时间只是当做工具类来用,才有时间好好看一下,加深理解。

背景

项目中涉及到从excel表导入,很多模块都涉及到了,从excel里面拿到的值都是字符串,运用起来比较麻烦,所以师父写了一个工具类,可以将excel得到的数据直接映射成对象。得到的excel里面的值第一行是列标题,以下是数据,大概如下图所示↓

代码

新建一个类用来接受excel里面你想要的值,将你想要接受的字段设置Annotation属性,这里的名字一定要和excel里面的列标题一样,方法是匹配[类]中的某一列的Annotation和excel里面的列标题,所以双方都可以冗余。

public class DEnterpriseForExcel {

    /**
* 企业全称
*/
@ExcelAnnotation(exportName = "FULLNAME")
private String fullname; /**
* 企业全称
*/
private String test;
}

接收类

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAnnotation {
// excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入
public String exportName(); }

添加字段名称

如果有需要特殊处理的字段,类似日期之类的,可以通过注入方法来特殊处理那一列

/**
* 反射保存
*
* @author wulin
*
*/
public class ReflectionUtils<T> {
Class<T> clazz; private ReflectionUtilsCallback callback = null; public ReflectionUtils(Class<T> clazz) {
this.clazz = clazz;
} public void setCallback(ReflectionUtilsCallback callback) {
this.callback = callback;
} // 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); public List<T> stringsToClass(List<String[]> lstData) throws Exception {
List<T> rtn = new ArrayList<T>();
int colNum = 0;
try {
/**
* 类反射得到调用方法
*/
// 得到目标目标类的所有的字段列表
Field filed[] = clazz.getDeclaredFields();
// 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
Map<String, Method> fieldmap = new HashMap<String, Method>(); // 循环读取所有字段
// 自定义Class中的所有变量 都要用 注释
for (int i = 0; i < filed.length; i++) {
Field f = filed[i];
// 得到单个字段上的Annotation ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
// 如果标识了Annotationd的话
if (exa != null) {
// 构造设置了Annotation的字段的Setter方法
String fieldname = f.getName();
String setMethodName = "set" + fieldname.substring(0, 1).toUpperCase() + fieldname.substring(1);
// 构造调用的method,
Method setMethod = clazz.getMethod(setMethodName, new Class[] { f.getType() });
// 将这个method以Annotaion的名字为key来存入。
fieldmap.put(exa.exportName(), setMethod);
}
} // 将标题的文字内容放入到一个map中。
Map<Integer, String> titlemap = new HashMap<Integer, String>();
// 第一行是标题
String[] dataTitle = lstData.get(0);
for (int i = 0; i < dataTitle.length; i++) {
String value = dataTitle[i].replace("\"", "").trim();
titlemap.put(i, value);
} // 从第2行往下是数据区
for (int nLp = 1; nLp < lstData.size(); nLp++) { // 标题下的第一行
String[] row = lstData.get(nLp);
// 行的所有列
// 得到传入类的实例
T tObject = clazz.newInstance(); int k = 0;
int nFlushCnt = 0;
// 列遍历(遍历一行的所有列)
colNum = 0;
for (String rec : row) { if (nFlushCnt >= 1000) {
System.gc();
}
colNum++; // 取得-列标题
String titleString = (String) titlemap.get(k);
// 如果[列标题]和[类]中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
if (fieldmap.containsKey(titleString)) {
// 获得 set方法
Method setMethod = (Method) fieldmap.get(titleString); if (null != callback) {
if (callback.isCallbackColumn(colNum)) {
Object objVal = callback.getCellValue(colNum, rec);
setMethod.invoke(tObject, objVal);
k = k + 1;
continue;
}
} // 得到setter方法的参数
Type[] ts = setMethod.getGenericParameterTypes();
// 获得参数类型[java.lang.String]
String xclass = ts[0].toString(); if (xclass.equals("class java.lang.String")) {
setMethod.invoke(tObject, rec == null ? null : rec.replace("\"", "")); } else if (xclass.equals("class java.lang.Integer")) { setMethod.invoke(tObject,
(rec == null || " ".equals(rec)) ? null : Integer.parseInt(rec.replace("\"", "")));
} else if (xclass.equals("class java.math.BigDecimal")) { setMethod.invoke(tObject,
(rec == null || " ".equals(rec)) ? null : new BigDecimal(rec.replace("\"", "")));
} else if (xclass.equals("int")) { int temp = Integer
.parseInt((rec == null || " ".equals(rec)) ? null : rec.replace("\"", ""));
setMethod.invoke(tObject, temp);
} else if (xclass.equals("class java.util.Date")) { setMethod.invoke(tObject,
(rec == null || 0 == rec.length()) ? null : sdf.parse(rec.replace("\"", "")));
} else if (xclass.equals("class java.lang.Short")) {
setMethod.invoke(tObject,
(rec == null || " ".equals(rec)) ? null : Short.parseShort(rec.replace("\"", "")));
} }
// 下一列
k = k + 1;
}
rtn.add(tObject); } } catch (Exception e) {
//System.out.println("colNum::" + colNum);
e.printStackTrace();
// 将异常抛出去
throw e;
} return rtn;
}
}

工具类

public interface ReflectionUtilsCallback {
public boolean isCallbackColumn(int column);
public Object getCellValue(int column, String strVal);
}

特殊处理

java反射保存的更多相关文章

  1. java 反射的应用 以及通过反射 用到的工厂模式

    java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案 ...

  2. JAVA反射实践

    Java反射机制在我的理解当中就是下面几点: 1. 对一个给定的类名(以字符串形式提供)能动态构建一个对象实例 2. 对于任意一个类,都能够知道这个类的所有属性和方法     3. 对于任意一个对象, ...

  3. [转]java反射机制

    原文地址:http://www.cnblogs.com/jqyp/archive/2012/03/29/2423112.html 一.什么是反射机制         简单的来说,反射机制指的是程序在运 ...

  4. Java反射机制的学习

    Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调 ...

  5. java反射机制浅谈

    一.Java的反射机制浅谈 最近研究java研究得很给力,主要以看博文为学习方式.以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出.受到各位指教之处,如若让小生好好感动, ...

  6. JAVA反射机制学�

    JAVA反射机制:对于随意一个类,都可以知道这个类的全部属性和方法:对于随意一个对象,都可以调用它的随意一个方法和属性:这样的动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. J ...

  7. 【设计模式】学习笔记17:代理模式之保护代理与Java反射

    本文出自   http://blog.csdn.net/shuangde800 本笔记内容: 1. Java动态代理,反射机制 2. 保护代理 3. 应用保护代理实现的约会系统 ----------- ...

  8. java 反射(reflect)总结,附对象打印工具类

    java反射机制认知 java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取类的信息以及动态调用对象的方法的 ...

  9. 再回首,Java温故知新(十一):Java反射

    最近继续回顾Java基础,进行到了Java反射这一部分,个人感觉这部分应该算是Java的高级特性了,在日常开发中使用的并不多,应用人员主要是工具构建人员,所以这次学习中以了解为主,Java反射主要应用 ...

随机推荐

  1. Spring MVC入门知识总结

    2.1.Spring Web MVC是什么 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职 ...

  2. location.href跳转不正确

    今天写这个随笔的用意是为了记录我遇到的一种情况,导致我页面无法正确跳转 location.href跳转页面其实很简单,只要附上url就可以了,但是今天我在测试一个跳转时是这么写的: location. ...

  3. 关于thinkphp 中的字段自动检查机制

    在thinkphp中有很好用的自动检查机制$_validate() 但是必须与create接收配合使用 可以很方便的帮助我们去判断 namespace Home\Model;use Think\Mod ...

  4. QuerySet创建新对象的方法和获取对象的方法

    新建一个对象的方法有以下几种: Person.objects.create(name=name,age=age) p = Person(name="WZ", age=23) p.s ...

  5. python之fabric(二):执行模式(转)

    执行模式 执行模式可以让你在多个主机上执行多个任务. 执行策略: 默认fabric是单个有序地执行方法,其行为如下: 1. 创建一系列任务,通过fab任务执行要执行的任务: 2. 根据主机列表定义,去 ...

  6. object-assign合并对象

    1. Object.assign() 对于合并对象操作, ECMAScript 6 中提供了一个函数: Object.assign(target, source); 这个方法会将所有可枚举 [1] 的 ...

  7. 关于web测试

    关于web测试1页面部分(1) 页面清单是否完整(是否已经将所需要的页面全部都列出来了)(2) 页面是否显示(在不同分辨率下页面是否存在,在不同浏览器版本中页面是是否显示)(3) 页面在窗口中的显示是 ...

  8. JDK 环境变量设置

    .net转JAVA了.记心不好,记录一下. 安装好jdk(64位)后找到我的电脑(右键)>属性>高级选项卡>环境变量>,里面有管理员的用户变量,有系统变量.我选的是系统变量.点 ...

  9. iOS响应者链和事件传递机制

    原文来自:http://www.cnblogs.com/zhw511006/p/3517248.html 响应者链(Responder Chain) 通常,一个iOS应用中,在一块屏幕上通常有很多的U ...

  10. Intel 82599 万兆网卡

    http://www.cnblogs.com/zhuyp1015/archive/2012/08/23/2653264.html http://bbs.chinaunix.net/thread-424 ...