• 借助jxl将Excel中的数据注入到Bean中


    前言

    使用了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;
    	}
    
  • 相关阅读:
    vim encoding
    window线程间通信常用的三种方法
    Python与C之间的相互调用(Python C API及Python ctypes库)
    vim中去掉每一行的^M
    现实点,不要急! [ 公司软件过程改进案例]
    理解TCP/IP协议
    Linux下C/C++帮助手册安装方法 及使用方法
    MySQL主主高可用(keepalive)
    React获取DOM元素ref属性
    一些vue组件库
  • 原文地址:https://www.cnblogs.com/FJH1994/p/6860819.html
Copyright © 2020-2023  润新知