使用了Hibernate的项目中须要导入多张表的数据,可是我又不想写屡次取出Excle数据放到Bean里的代码,因而写了个ExcleUtils来帮助我作这件事。java
技术上,首先确定是要借助反射的,而后选择了jxl来操做Excle。数组
须要的参数上,Excle文件不能少;好像没有什么方法可以在Excel隐藏地放入对应属性名的信息(就是属性名字不会在Excle中显示出来,若是有方法可以作到,请给我留言,多谢!),因而我会须要按照Excle顺序的属性名称数组;而后我须要在Sheet页的序号以及数据从第几行开始;对于Date类型,可能须要SimpleDateFormat对象来进行转换,若是没有就使用默认的。所以这个方法应该是这样的(而且有一个重载版本):ui
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 }
原本想把代码拆开说说本身的思路,想了想仍是整块代码贴上而后写注释把(只贴相关部分的),其实都蛮简单的。excel
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; }