前言

使用了Hibernate的项目中需要导入多张表的数据,但是我又不想写多次取出Excle数据放到Bean里的代码,于是写了个ExcleUtils来帮助我做这件事。

基本思路

技术上,首先肯定是要借助反射的,然后选择了jxl来操作Excle。

需要的参数上,Excle文件不能少;好像没有什么方法能够在Excel隐藏地放入对应属性名的信息(就是属性名字不会在Excle中显示出来,如果有方法能够做到,请给我留言,多谢!),于是我会需要按照Excle顺序的属性名称数组;然后我需要在Sheet页的序号以及数据从第几行开始;对于Date类型,可能需要SimpleDateFormat对象来进行转换,如果没有就使用默认的。因此这个方法应该是这样的(并且有一个重载版本):

public static <T> List<T> getDataList(File excelFile, int sheetindex,
int start, String[] props, Class<T> clazz) throws Exception {
return getDataList(excelFile, sheetindex, start, props, clazz, null);
} public static <T> List<T> getDataList(File excelFile, int sheetindex,
int start, String[] props, Class<T> clazz, SimpleDateFormat sdf) {
//TODO
}

实现

本来想把代码拆开说说自己的思路,想了想还是整块代码贴上然后写注释把(只贴相关部分的),其实都蛮简单的。

private static final Map<Class<?>, Class<?>> pwMap = new HashMap<Class<?>, Class<?>>();

	static {
pwMap.put(byte.class, Byte.class);
pwMap.put(short.class, Short.class);
pwMap.put(int.class, Integer.class);
pwMap.put(long.class, Long.class);
pwMap.put(float.class, Float.class);
pwMap.put(double.class, Double.class);
pwMap.put(boolean.class, Boolean.class);
pwMap.put(char.class, Character.class);
} private ExcelUtils() {
} /**
* <p>
* 从Excel中获取对象列
* </p>
*
* @param excelFile
* 文件
* @param sheetindex
* 第几个sheet
* @param props
* 属性名(按顺序) (如果有非基本类型需要实现valueOf方法)
* @param clazz
* 类型
* @return
* @throws Exception
* String[], Class, SimpleDateFormat)
*/
public static <T> List<T> getDataList(File excelFile, int sheetindex,
int startRow, int startCol, String[] props, Class<T> clazz)
throws Exception {
return getDataList(excelFile, sheetindex, startRow, startCol, props,
clazz, null);
} /**
*
* @param excelFile
* Excel文件
* @param sheetindex
* @param start
* @param props
* @param clazz
* @param sdf
* @return
* @throws Exception
*/
public static <T> List<T> getDataList(File excelFile, int sheetindex,
int startRow, int startCol, String[] props, Class<T> clazz,
SimpleDateFormat sdf) throws Exception {
Workbook excel = null;
try {
excel = Workbook.getWorkbook(excelFile);
Sheet sheet = excel.getSheet(sheetindex);
int n = sheet.getRows();
List<T> result = new ArrayList<T>(n);
for (int i = startRow; i < n; i++) {
Cell[] row = sheet.getRow(i);
result.add(getRowData(props, row, clazz, sdf, startCol));
}
return result;
} catch (BiffException | IOException e) {
throw new Exception("读取Excel文件出错!");
} finally {
excel.close();
}
} /**
* <p>
* 获取其中一行的数据注入到对象中
* </p>
*
* @param props
* @param row
* @param clazz
* @return
* @throws Exception
*/
public static <T> T getRowData(String[] props, Cell[] row, Class<T> clazz,
int startCol) throws Exception {
return getRowData(props, row, clazz, null, startCol);
} /**
*
* @param props
* @param row
* @param clazz
* @param sdf
* @return
* @throws Exception
*/
public static <T> T getRowData(String[] props, Cell[] row, Class<T> clazz,
SimpleDateFormat sdf, int startCol) throws Exception {
// 属性首字母大写
for (int i = 0; i < props.length; i++) {
if (props[i] == null)
continue;
StringBuilder sb = new StringBuilder(props[i]);
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
props[i] = sb.toString();
}
// 实例化一个对象
T result = clazz.newInstance();
for (int i = 0; i < props.length; i++) {
String propName = props[i];
if (propName == null) {
continue;
}
Class<?> type = getPropType(clazz, propName);
// 把getter的返回类型作为参数类型获取setter
Method setter = clazz.getMethod("set" + propName, type);
String contents = row[i + startCol].getContents(); if (contents != null) {
Object val = string2Type(contents, type, sdf);
// 执行setter
setter.invoke(result, val);
}
}
return result;
} private static final SimpleDateFormat DEFALUT_SIMPLEDATEF = new SimpleDateFormat(
"yyyy-MM-dd"); @SuppressWarnings("unchecked")
private static <T> T string2Type(String val, Class<T> clazz,
SimpleDateFormat sdf) throws Exception {
Method valueOf = null;
// 对Date和String特殊处理
if (String.class == clazz) {
return (T) val;
}
if (Date.class == clazz) {
return (T) (sdf != null ? sdf.parse(val) : DEFALUT_SIMPLEDATEF
.parse(val));
}
if (char.class == clazz || Character.class == clazz) {
Character c = val.toCharArray().length > 0 ? val.toCharArray()[0]
: (Character.class == clazz ? null : (char) 0);
return (T) c;
}
// 对基本类型做处理
Class<?> finalclazz = clazz.isPrimitive() ? pwMap.get(clazz) : clazz;
try {
valueOf = finalclazz.getMethod("valueOf", String.class);
} catch (NoSuchMethodException e) {
throw new Exception("成员类型需要有T valueOf(String)静态方法");
}
return (T) valueOf.invoke(null, val);
} private static Class<?> getPropType(Class<?> clazz, String propName)
throws NoSuchMethodException, SecurityException {
Method getter = clazz.getMethod("get" + propName);
Class<?> type = getter.getReturnType();
return type;
}

借助jxl将Excel中的数据注入到Bean中的更多相关文章

  1. 使用OpenXml把Excel中的数据导出到DataSet中

    public class OpenXmlHelper { /// <summary> /// 读取Excel数据到DataSet中,默认读取所有Sheet中的数据 /// </sum ...

  2. excel文件与txt文件互转,并且把excel里的数据导入到oracle中

    一.excel文件转换成txt文件的步骤 a.首先要把excel文件转换成txt文件 1.Excel另存为中已经包含了TXT格式,所以我们可以直接将Excel表格另存为TXT格式,但是最后的效果好像不 ...

  3. sql之将一个表中的数据注入另一个表中

    sql之将一个表中的数据注入另一个表中 需求:现有两张表t1,t2,现需要将t2的数据通过XZQHBM相同对应放入t1表中 t1: t2: 思路:left join 语句: select * from ...

  4. C# 将Excel里面的数据填充到DataSet中

    /// <summary> /// 将Excel表里的数据填充到DataSet中 /// </summary> /// <param name="filenam ...

  5. C#-WinForm-ListView-表格式展示数据、如何将数据库中的数据展示到ListView中、如何对选中的项进行修改

    在展示数据库中不知道数量的数据时怎么展示最好呢?--表格 ListView - 表格形式展示数据 ListView 常用属性 HeaderStyle - "详细信息"视图中列标头的 ...

  6. 将SQLServer2005中的数据同步到Oracle中

    有时由于项目开发的需要,必须将SQLServer2005中的某些表同步到Oracle数据库中,由其他其他系统来读取这些数据.不同数据库类型之间的数据同步我们可以使用链接服务器和SQLAgent来实现. ...

  7. C# 将List中的数据导入csv文件中

    //http://www.cnblogs.com/mingmingruyuedlut/archive/2013/01/20/2849906.html C# 将List中的数据导入csv文件中   将数 ...

  8. SQL SERVER 使用BULK Insert将txt文件中的数据批量插入表中(1)

    1/首先建立数据表 CREATE TABLE BasicMsg( RecvTime FLOAT NOT NULL , --接收时间,不存在时间相同的数据 AA INT NOT NULL, --24位地 ...

  9. Sql Server中的数据类型和Mysql中的数据类型的对应关系(转)

    Sql Server中的数据类型和Mysql中的数据类型的对应关系(转):https://blog.csdn.net/lilong329329/article/details/78899477 一.S ...

随机推荐

  1. HDU 1211 EXGCD

    EXGCD的模板水题 RSA算法给你两个大素数p,q定义n=pq,F(n)=(p-1)(q-1) 找一个数e 使得(e⊥F(n)) 实际题目会给你e,p,q计算d,$de \mod F(n) = 1$ ...

  2. 几种不同程序语言的HMM版本

    几种不同程序语言的HMM版本 “纸上得来终觉浅,绝知此事要躬行”,在继续翻译<HMM学习最佳范例>之前,这里先补充几个不同程序语言实现的HMM版本,主要参考了维基百科.读者有兴趣的话可以研 ...

  3. Struts2版本更新报错:>>> ActionContextCleanUp <<< is deprecated! Please use the new filters!

    因低版本Struts2存在漏洞,更新为较新的版本.启动时,报如下警告信息: ************************************************************** ...

  4. 如何修改 winserver2008 密码策略为简单密码

    对于不在域中的计算机, 可以运行: gpedit.msc , 如下图: 对于在域中的计算机, 应该: 如不能生效, 可重启再试.

  5. 《JavaScript 实战》:实现图片幻滑动展示效果

    滑动展示效果主要用在图片或信息的滑动展示,也可以设置一下做成简单的口风琴(Accordion)效果.这个其实就是以前写的图片滑动展示效果的改进版,那是我第一篇比较受关注的文章,是时候整理一下了. 有如 ...

  6. Web 开发人员需知的 Web 缓存知识

    今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~~ 什么是Web缓存,为什么要使用它? Web ...

  7. python学习笔记(十六)之文件

    打开文件用open函数 open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=Tru ...

  8. 【BZOJ 1001】[BJOI2006]狼抓兔子(最大流)

    题目链接 最大流裸题,没什么好说吧,恰好点数多,考验网络流的效率,正好练\(Dinic\). #include <cstdio> #include <queue> #inclu ...

  9. nginx 配置代理某个路径

    location /test{ proxy_pass http://localhost:8765/test; proxy_set_header Host $http_host; } 其中红色的那句可以 ...

  10. 【bzoj4293】【PA2015】Siano

    如题,首先可以考虑相对大小是不变的. 那么先sort,之后每次在线段树上二分即可. #include<bits/stdc++.h> typedef long long ll; using ...