• 项目中Excel表的导入总结


    我删减了一部分代码

    思路:

    1.通过注解获取需要导入对象的方法名的数组
    2.获取方法的返回值及返回类型
    循环excel的行,每行对应一个对象,而每个对象有对应的注解的集合,
    在注解集合的子循环中,获取所在行的每一列数据,将列数据通过注解
    与注解对应的get方法对应起来,得到get方法的返回值类型
    3.将返回值转成需要的返回值类型
    将列数据的Object类型转换成返回值类型的数据。
    4.将值set到对象中
    获取get方法对应的set方法,调用method.invoke(obj, args)(调用包
    装在当前Method对象中的方法)将值set到对象中。

    @RequiresPermissions("testterm:testTerm:edit")
        @RequestMapping(value = "import", method = RequestMethod.POST)
        public String importFile(String file, RedirectAttributes redirectAttributes) {
            if (Global.isDemoMode()) {
                addMessage(redirectAttributes, "演示模式,不允许操作!");
                return "redirect:" + adminPath + "/sys/user/list?repage";
            }
            file = ParamUtils.getParamValue("upload_path", "") + file;
            try {
                int successNum = 0;
                int failureNum = 0;
                StringBuilder failureMsg = new StringBuilder();
                ImportExcel ei = new ImportExcel(file, 1, 0);
                List<TestTerm> list = ei.getDataList(TestTerm.class);
                for (TestTerm testTerm : list) {
                    try {
                        BeanValidators.validateWithException(validator, testTerm);
                        testTermService.save(testTerm);
                        successNum++;
                    } catch (ConstraintViolationException ex) {
                        failureMsg.append("<br/>术语及定义 " + testTerm.getName() + "导入失败:");
                        List<String> messageList = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
                        for (String message : messageList) {
                            failureMsg.append(message + "; ");
                            failureNum++;
                        }
                    } catch (Exception ex) {
                        failureMsg.append("<br/>术语及定义 " + testTerm.getName() + " 导入失败:" + ex.getMessage());
                    }
                }
                if (failureNum > 0) {
                    failureMsg.insert(0, ",失败 " + failureNum + " 条术语及定义信息,导入信息如下:");
                }
                addMessage(redirectAttributes, "已成功导入 " + successNum + " 条术语及定义信息" + failureMsg);
                FileUtils.deleteFile(file);
            } catch (Exception e) {
                addMessage(redirectAttributes, "导入术语及定义!失败信息:" + e.getMessage());
                FileUtils.deleteFile(file);
            }
            return "redirect:" + adminPath + "/testterm/testTerm/list?repage";
        }
    /**
     * 导入Excel文件(支持“XLS”和“XLSX”格式)
     * @author ThinkGem
     * @version 2013-03-10
     */
    public class ImportExcel {
        
        private static Logger log = LoggerFactory.getLogger(ImportExcel.class);
                
        /**
         * 工作薄对象
         */
        private Workbook wb;
        
        /**
         * 工作表对象
         */
        private Sheet sheet;
        
        /**
         * 标题行号
         */
        private int headerNum;
        /**
         * 构造函数
         * @param path 导入文件
         * @param headerNum 标题行号,数据行号=标题行号+1
         * @param sheetIndex 工作表编号
         * @throws InvalidFormatException 
         * @throws IOException 
         */
        public ImportExcel(String fileName, int headerNum, int sheetIndex) 
                throws InvalidFormatException, IOException {
            this(new File(fileName), headerNum, sheetIndex);
        }/**
         * 构造函数
         * @param path 导入文件对象
         * @param headerNum 标题行号,数据行号=标题行号+1
         * @param sheetIndex 工作表编号
         * @throws InvalidFormatException 
         * @throws IOException 
         */
        public ImportExcel(String fileName, InputStream is, int headerNum, int sheetIndex) 
                throws InvalidFormatException, IOException {
            if (StringUtils.isBlank(fileName)){
                throw new RuntimeException("导入文档为空!");
            }else if(fileName.toLowerCase().endsWith("xls")){    
                this.wb = new HSSFWorkbook(is);    
            }else if(fileName.toLowerCase().endsWith("xlsx")){  
                this.wb = new XSSFWorkbook(is);
            }else{
                FileUtils.deleteFile(fileName);
                is.close();
                throw new RuntimeException("文档格式不正确!");
            }  
            if (this.wb.getNumberOfSheets()<sheetIndex){
                FileUtils.deleteFile(fileName);
                is.close();
                throw new RuntimeException("文档中没有工作表!");
            }
            this.sheet = this.wb.getSheetAt(sheetIndex);
            this.headerNum = headerNum;
            log.debug("Initialize success.");
        }
        
        /**
         * 获取行对象
         * @param rownum
         * @return
         */
        public Row getRow(int rownum){
            return this.sheet.getRow(rownum);
        }
    
        /**
         * 获取数据行号
         * @return
         */
        public int getDataRowNum(){
            return headerNum+1;
        }
        
        /**
         * 获取最后一个数据行号
         * @return
         */
        public int getLastDataRowNum(){
            return this.sheet.getLastRowNum()+headerNum;
        }
        
        /**
         * 获取最后一个列号
         * @return
         */
        public int getLastCellNum(){
            return this.getRow(headerNum).getLastCellNum();
        }
        
        /**
         * 获取单元格值
         * @param row 获取的行
         * @param column 获取单元格列号
         * @return 单元格值
         */
        public Object getCellValue(Row row, int column){
            Object val = "";
            try{
                Cell cell = row.getCell(column);
                if (cell != null){
                    if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
                        val = cell.getNumericCellValue();
                    }else if (cell.getCellType() == Cell.CELL_TYPE_STRING){
                        val = cell.getStringCellValue();
                    }else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA){
                        val = cell.getCellFormula();
                    }else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){
                        val = cell.getBooleanCellValue();
                    }else if (cell.getCellType() == Cell.CELL_TYPE_ERROR){
                        val = cell.getErrorCellValue();
                    }
                }
            }catch (Exception e) {
                return val;
            }
            return val;
        }
        
        /**
         * 获取导入数据列表
         * @param cls 导入对象类型
         * @param groups 导入分组
         */
        public <E> List<E> getDataList(Class<E> cls, int... groups) throws InstantiationException, IllegalAccessException{
            List<Object[]> annotationList = Lists.newArrayList();
            // Get annotation method
            Method[] ms = cls.getDeclaredMethods();
            for (Method m : ms){
                ExcelField ef = m.getAnnotation(ExcelField.class);
                if (ef != null && (ef.type()==0 || ef.type()==2)){
                    annotationList.add(new Object[]{ef, m});
                }
            }
            //log.debug("Import column count:"+annotationList.size());
            // Get excel data
            List<E> dataList = Lists.newArrayList();
            for (int i = this.getDataRowNum(); i < this.getLastDataRowNum(); i++) {
                E e = (E)cls.newInstance();
                int column = 0;
                Row row = this.getRow(i);
                StringBuilder sb = new StringBuilder();
                for (Object[] os : annotationList){
                    Object val = this.getCellValue(row, column++);
                    if (val != null){
                        // Get param type and type cast
                        Class<?> valType = Class.class;
                        if (os[1] instanceof Method){
                            Method method = ((Method)os[1]);
                            if ("get".equals(method.getName().substring(0, 3))){
                                valType = method.getReturnType();
                            }else if("set".equals(method.getName().substring(0, 3))){
                                valType = ((Method)os[1]).getParameterTypes()[0];
                            }
                        }
                        //log.debug("Import value type: ["+i+","+column+"] " + valType);
                        try {
                            if (valType == String.class){
                                String s = String.valueOf(val.toString());
                                if(StringUtils.endsWith(s, ".0")){
                                    val = StringUtils.substringBefore(s, ".0");
                                }else{
                                    val = String.valueOf(val.toString());
                                }
                            }else if (valType == Integer.class){
                                val = Double.valueOf(val.toString()).intValue();
                            }else if (valType == Long.class){
                                val = Double.valueOf(val.toString()).longValue();
                            }else if (valType == Double.class){
                                val = Double.valueOf(val.toString());
                            }else if (valType == Float.class){
                                val = Float.valueOf(val.toString());
                            }else if (valType == Date.class){
                                val = DateUtil.getJavaDate((Double)val);
                            }
                        } catch (Exception ex) {
                            log.info("Get cell value ["+i+","+column+"] error: " + ex.toString());
                            val = null;
                        }
                        // set entity value
                        if (os[1] instanceof Method){
                            String mthodName = ((Method)os[1]).getName();
                            if ("get".equals(mthodName.substring(0, 3))){
                                mthodName = "set"+StringUtils.substringAfter(mthodName, "get");
                            }
                            Reflections.invokeMethod(e, mthodName, new Class[] {valType}, new Object[] {val});
                        }
                    }
                    sb.append(val+", ");
                }
                dataList.add(e);
                log.debug("Read success: ["+i+"] "+sb.toString());
            }
            return dataList;
        }
    
    }
    /**
         * 直接调用对象方法, 无视private/protected修饰符.
         * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
         * 同时匹配方法名+参数类型,
         */
        public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
                final Object[] args) {
            Method method = getAccessibleMethod(obj, methodName, parameterTypes);
            if (method == null) {
                throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");
            }
    
            try {
                return method.invoke(obj, args);
    }
    catch (Exception e) { throw convertReflectionExceptionToUnchecked(e); } }
    /**
         * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
         * 如向上转型到Object仍无法找到, 返回null.
         * 匹配函数名+参数类型。
         * 
         * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
         */
        public static Method getAccessibleMethod(final Object obj, final String methodName,
                final Class<?>... parameterTypes) {
            Validate.notNull(obj, "object can't be null");
            Validate.notBlank(methodName, "methodName can't be blank");
    
            for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
                try {
                    Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
                    makeAccessible(method);
                    return method;
                } catch (NoSuchMethodException e) {
                    // Method不在当前类定义,继续向上转型
                    continue;// new add
                }
            }
            return null;
        }
    /**
         * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
         */
        public static void makeAccessible(Method method) {
            if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
                    && !method.isAccessible()) {
                method.setAccessible(true);
            }
        }

    invoke方法

      作用:调用包装在当前Method对象中的方法。

       原型:Object invoke(Object obj,Object...args)

       参数解释:obj:实例化后的对象

                           args:用于方法调用的参数

       返回:根据obj和args调用的方法的返回值

       抛出错误:IllegalAccessException

                          原因:Method对象强制Java语言执行控制 或 无权访问obj对象

                            IllegalArgumentException

                           原因:方法是实例化方法,而指定需要调用的对象并不是实例化后的类或接口

    getDeclaredMethod() 获取的是类自身声明的所有方法,包含public、protected和private方法。

    getMethod () 获取的是类的所有共有方法,这就包括自身的所有public方法,和从基类继承的、从接口实现的所有public方法。

  • 相关阅读:
    Android Studio 通过 git update 或者 pull 的时候出错及解决办法
    powershell2
    @SuppressWarnings注解用法
    IDEA设置虚拟机参数
    Java爬虫https网页内容报错SSLHandshakeException信任(忽略)所有SSL证书
    Quartz时间配置(周期任务)
    java 字符串转成 json 数组并且遍历
    linux 不能进入系统 Failed to load SELinux policy. Freezing
    linux安装mysql后报错启动不了Starting MySQL. ERROR! The server quit without updating PID file (/var/lib/mysql/localhost.localdomain.pid).
    警告:MySQL-server-5.6.26-1.el7.x86_64.rpm: 头V3 DSA/SHA1 Signature, 密钥 ID 5072e1f5: NOKEY
  • 原文地址:https://www.cnblogs.com/person008/p/9592485.html
Copyright © 2020-2023  润新知