POI实现导入多sheet表excel实现

来源:互联网 发布:java web war包下载 编辑:程序博客网 时间:2024/05/01 09:37

在项目中导入导出Excel是一件很平常的事情,采用的技术也有很多种:比如有JXL 还有POI。

下面大概介绍一下这两个开源的产品,也做一个比较:

jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是jExcelAPI。其中功能相对POI比较弱一点。但jExcelAPI对中文支持非常好,API是纯Java的, 并不依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件。 另外需要说明的是,这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。

Apache POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。目前POI已经有了Ruby版本。结构:HSSF - 提供读写Microsoft Excel XLS格式档案的功能。XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。HWPF - 提供读写Microsoft Word DOC格式档案的功能。HSLF - 提供读写Microsoft PowerPoint格式档案的功能。HDGF - 提供读Microsoft Visio格式档案的功能。HPBF - 提供读Microsoft Publisher格式档案的功能。HSMF - 提供读Microsoft Outlook格式档案的功能。

通过对比:

1.JXL遇到大数量级时处理效率不行,POI相对而言没有问题

2.JXL不支持excel2003,这是一个很大的局限性

3.3.两者都有一个缺点,无法识别某个图片在那个sheet表中,只能识别全局的图片部分格式的图片



下面介绍的采用POI做excel导入的过程及部分示例代码:

我在项目中,由于要导入的excel的sheet表较多,而且我想做到可配置化的校验,什么叫可配置化的校验:就是通过配置文件配置每个sheet表中的每列所能输入的字符类型和长度、是否为空;

比如:

编码:这个编码没有实际意义,只作为在后台处理时的判断依据;

类型:包含字符、数字(整形、Double类型)、日期等;

长度:就是输入的字符个数或者整形数大小;

是否为空:为空、不为空;


所以我采用了XML文件来配置每一个sheet表的每列对应的数据库字段(可能不是完整的对应数据库字段,需要后台对某几列做处理)

示例配置文件如下(TCompany.xml):

<?xml version="1.0" encoding="UTF-8"?><!-- 1、委托单位基本情况表 --><beans><bean name="TCompany">        <property name="comanyName" cnname="单位名称(中文)" position="1" type="String" length="200" isnull="false"></property>        <property name="companyNameEn" cnname="单位名称(英文)"  position="2" type="String" length="200" isnull="true"></property>        <property name="industryName"  cnname="所属行业" position="3" length="5" type="String" isnull="true"></property>        <property name="address"  cnname="地址" position="4" length="255" type="String" isnull="true"></property>        <property name="postalCode"  cnname="邮编" position="5" type="String" length="6" isnull="true"></property>        <property name="juridicalPerson"  cnname="法定代表人姓名" position="6" type="String" length="60" isnull="true"></property>        <property name="contactPerson"  cnname="联系人姓名" position="7" type="String" length="60" isnull="true"></property>        <property name="contactProfession"  cnname="联系人职务" position="8" type="String" length="30" isnull="false"></property>        <property name="telephone"  cnname="联系电话" position="9" type="String" length="100" isnull="false"></property>        <property name="email"  cnname="传真" position="10" type="String" length="30" isnull="false"></property>         <property name="email"  cnname="电子邮箱" position="11" type="String" length="255" isnull="false"></property>    </bean></beans>

下面主要是后台实现了, 主要是通过解析每个sheet相对应的XML文件配置就能校验输入的是否正确,并判断出那行那列输入错误,应该数据什么?

下面主要列出部分实现的方法:


1.xml对应的实体结构类:

/** * xml文件对象的校验bean * @author 唐辉 * */public class XlsLoadVerifyBean {private String name;  //对应字段名称private String cnName;  //对应字段所对应的中文名称private int length;  //字符长度private boolean isNull; //是否为空private String type; //字符类型private int position;  //对应的表格列public XlsLoadVerifyBean() {super();}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getLength() {return length;}      public void setLength(int length) {this.length = length;}public boolean isNull() {return isNull;}public void setNull(boolean isNull) {this.isNull = isNull;}public String getType() {return type;}public void setType(String type) {this.type = type;}public int getPosition() {return position;}public void setPosition(int position) {this.position = position;}public String getCnName() {return cnName;}public void setCnName(String cnName) {this.cnName = cnName;}}

2.同时需要注意的是:将每个xml文件的名字定义为:每个sheet表所对应的实体类名称。这样在解析的时候方便直接查找


3.下面是部分工具类方法(使用时主要是将其组装就行了):

/** * 生成消息的方法 * @param sheetNum * @param rowsnum * @param type * @return */public String markMsg(int sheetNum,int rowsnum,int type){String msg = "";if(type == 1){msg = "第" + (sheetNum+2) + "个工作表:【 " + XmlPathDef.sheetARR[sheetNum]  + "】 导入了<font color='red'>  " +  rowsnum + "</font> 条记录!" + "</br>";}else if(type == 2){msg = "第" + (sheetNum+2) + "个工作表:【 " + XmlPathDef.sheetARR[sheetNum]  + "】 第  " +  (rowsnum+1) + " 行 填写不完整,暂未导入!" + "</br>";}else if(type == 3){msg = "第" + (sheetNum+2) + "个工作表:【 " + XmlPathDef.sheetARR[sheetNum]  + "】 数据填写不完整,请重新填写后再导入!" + "</br>";} return msg;}/** * 获取 SHEET 表实际记录行数 * @param workBook * @param sheetNum * @return */public int getAllCellNumber(HSSFWorkbook workBook,int sheetNum){int rowNum = 0;//总的有效行数boolean boo = true;try {int defNum = sheetNum - XmlPathDef.START_SHEET_NUM;//定义读取sheetXML的开始点HSSFSheet sheet = workBook.getSheetAt(sheetNum); //取得工作表         int rows = sheet.getPhysicalNumberOfRows(); //获得行数         System.out.println(workBook.getSheetName(sheetNum) + " 工作表,总行数为:"+ rows + " 行.");for (int j = 3; j < rows; j++) {//行循环:默认从第三行开始解析 if(this.checkRowHasDatas(sheet,j)){                //校验某行是否有数据String verifyFiled = XmlPathDef.getNumByName(XmlPathDef.verifyFiledNum,XmlPathDef.sheetXML[defNum]);            String[] arrStr = getArrStr(verifyFiled);            if(arrStr != null){            for (int i = 0; i < arrStr.length; i++) {        //校验从第三行开始校验是否有数据 (主要是校验关键字段是否有值)            if(!this.checkRowHasDatas(sheet,j,Integer.parseInt(arrStr[i]))){                    boo = false;                    break;                    }            }    }                       if(boo){            rowNum ++;            }else{            boo = true;            } }            }} catch (Exception e) {e.getStackTrace();}System.out.println(workBook.getSheetName(sheetNum) + " 工作表,有效行数为:"+ rowNum + " 行.");return rowNum;}/** * 判断某个sheet是否有数据,根据关键字段 * @param workBook * @param sheetNum * @return */public boolean hasCellNumber(HSSFWorkbook workBook,int sheetNum){int num = 0;boolean boo = true;try {int defNum = sheetNum - XmlPathDef.START_SHEET_NUM;//定义读取sheetXML的开始点HSSFSheet sheet = workBook.getSheetAt(sheetNum); //取得工作表         int rows = sheet.getPhysicalNumberOfRows(); //获得行数         System.out.println(workBook.getSheetName(sheetNum) + " 工作表,总行数为:"+ rows + " 行.");for (int j = 3; j < rows; j++) {//行循环:默认从第三行开始解析 if(this.checkRowHasDatas(sheet,j)){                //校验某行是否有数据String verifyFiled = XmlPathDef.getNumByName(XmlPathDef.verifyFiledNum,XmlPathDef.sheetXML[defNum]);            String[] arrStr = getArrStr(verifyFiled);            if(arrStr != null){            for (int i = 0; i < arrStr.length; i++) {                        if(!this.checkRowHasDatas(sheet,j,Integer.parseInt(arrStr[i]))){                    boo = false;                    num = 1;                    break;                     }else{                     continue;                    }                    }            if(num ==1){            break;            }            }            if(num ==1){            num = 0;            break;            }}            }} catch (Exception e) {e.getStackTrace();}return boo;}/** * 判断某行是否有数据,根据关键字段 * @param workBook * @param sheetNum * @param cellNum * @return */public boolean hasCellNumber(HSSFWorkbook workBook,int sheetNum,int cellNum){boolean boo = true;try {int defNum = sheetNum - XmlPathDef.START_SHEET_NUM;//定义读取sheetXML的开始点HSSFSheet sheet = workBook.getSheetAt(sheetNum); //取得工作表         int rows = sheet.getPhysicalNumberOfRows(); //获得行数         System.out.println(workBook.getSheetName(sheetNum) + " 工作表,总行数为:"+ rows + " 行.");if(this.checkRowHasDatas(sheet,cellNum)){                //校验某行是否有数据String verifyFiled = XmlPathDef.getNumByName(XmlPathDef.verifyFiledNum,XmlPathDef.sheetXML[defNum]);            String[] arrStr = getArrStr(verifyFiled);            if(arrStr != null){            for (int i = 0; i < arrStr.length; i++) {                    if(!this.checkRowHasDatas(sheet,cellNum,Integer.parseInt(arrStr[i]))){                    boo = false;                      }                    }            }}} catch (Exception e) {e.getStackTrace();}return boo;}    /** * 获取某个sheet表未导入的总行数 * @param workBook * @param sheetNum * @return */public StringBuffer getAllCellString(StringBuffer errLog,HSSFWorkbook workBook,int sheetNum){try {int num = 0 ;int defNum = sheetNum - XmlPathDef.START_SHEET_NUM;//定义读取sheetXML的开始点HSSFSheet sheet = workBook.getSheetAt(sheetNum); //取得工作表         int rows = sheet.getPhysicalNumberOfRows(); //获得行数         System.out.println(workBook.getSheetName(sheetNum) + " 工作表,总行数为:"+ rows + " 行.");for (int j = 3; j < rows; j++) {//行循环:默认从第三行开始解析 if(this.checkRowHasDatas(sheet,j)){                //校验某行是否有数据String verifyFiled = XmlPathDef.getNumByName(XmlPathDef.verifyFiledNum,XmlPathDef.sheetXML[defNum]);            String[] arrStr = getArrStr(verifyFiled);            if(arrStr != null){            for (int i = 0; i < arrStr.length; i++) {            //校验从第三行开始校验是否有数据 (主要是校验关键字段是否有值)            if(!this.checkRowHasDatas(sheet,j,Integer.parseInt(arrStr[i]))){            num  = 1;            break;            }                  }            if(num == 1){            errLog = creatObj(errLog);                errLog.append(markMsg(sheetNum-XmlPathDef.START_SHEET_NUM, j, 2));//生成MSG消息                num = 0;            }               }            }            }} catch (Exception e) {e.getStackTrace();}return errLog;}


/**     * 通过类型获取cell的值     * @param cell     * @param vtype     * @param i     * @param j     * @param k     * @return     */public String getCellValue(HSSFCell cell,String vtype,int i,int j,int k){    String cellValue = ""; //返回值    switch (cell.getCellType()) {         case HSSFCell.CELL_TYPE_NUMERIC: // 数值型              if (HSSFDateUtil.isCellDateFormatted(cell)) {                 double cellValuenum = cell.getNumericCellValue();                //如果是date类型则 ,获取该cell的date值                 Date cellDateValue = (Date) HSSFDateUtil.getJavaDate(cellValuenum);                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                cellValue = sdf.format(cellDateValue);//             if(cellValue.indexOf(" 0:00:00") != -1){// String excelValues = cellValue.substring(0,cellValue.lastIndexOf(" 0:00:00"));//          String str_4 = cellValue.substring(0,4); //                     Matcher isNum_4 = pattern.matcher(str_4); //                     if(isNum_4.matches()){ //前4位为数字//                     if(excelValues.length() == 8){//如果为8位//          if(cellValue.substring(4,5).equals("-") && cellValue.substring(6,7).equals("-")){//          cellValue = cellValue.substring(0,5) + "0" + cellValue.substring(5,7) + "0" + cellValue.substring(7,cellValue.length());//          }//          }else if(excelValues.length() == 9){//如果为9位//          if(cellValue.substring(4,5).equals("-") && cellValue.substring(6,7).equals("-")){//          cellValue = cellValue.substring(0,5) + "0" + cellValue.substring(5,cellValue.length());//          }else if(cellValue.substring(4,5).equals("-") && cellValue.substring(7,8).equals("-")){//          cellValue = cellValue.substring(0,8) + "0" + cellValue.substring(8,cellValue.length());//          }//          }//                     }//}                              System.out.println("第:"+(j+1)+"行,第:"+(k+1)+"列值:" + cellValue+ "");              }else{//纯数字              Number cellValueNum = cell.getNumericCellValue();              if(vtype.equals("String") || vtype.equals("Integer") || vtype.equals("double")){             if(cellValueNum.toString().indexOf("E") != -1){             DecimalFormat decl = new DecimalFormat("###");                 cellValue  = decl.format(cellValueNum);                 }else{                 if(vtype.equals("Integer")){                 cellValue = cellValueNum.toString().substring(0,cellValueNum.toString().lastIndexOf("."));                 }else if(vtype.equals("double")){                 cellValue = cellValueNum.toString();                 }else if(vtype.equals("String")){                 cellValue = cellValueNum.toString();                 }                 }             }                  System.out.println("第:"+(j+1)+"行,第:"+(k+1)+"列值:"+cellValue+"");              }             break;         /* 此行表示单元格的内容为string类型 */         case HSSFCell.CELL_TYPE_STRING: // 字符串型         cellValue = cell.getRichStringCellValue().toString();             System.out.println("第:"+(j+1)+"行,第:"+(k+1)+"列值:"+cellValue+"");             break;         case HSSFCell.CELL_TYPE_FORMULA://公式型             //读公式计算值         cellValue = String.valueOf(cell.getNumericCellValue());              if(cellValue.equals("NaN")){//如果获取的数据值为非法值,则转换为获取字符串              cellValue = cell.getRichStringCellValue().toString();              }              //cell.getCellFormula();读公式              System.out.println("第:"+(j+1)+"行,第:"+(k+1)+"列值:"+cellValue+"");              break;         case HSSFCell.CELL_TYPE_BOOLEAN://布尔          cellValue = " " + cell.getBooleanCellValue();              System.out.println("第:"+(j+1)+"行,第:"+(k+1)+"列值:"+cellValue+"");              break;         /* 此行表示该单元格值为空 */         case HSSFCell.CELL_TYPE_BLANK: // 空值         cellValue = "";             break;         case HSSFCell.CELL_TYPE_ERROR: // 故障         cellValue = "";             System.out.println("第"+(j+1)+"行,第:"+(k+1)+"列值:"+cellValue+"");             break;         default:         cellValue = cell.getRichStringCellValue().toString();             System.out.println("第"+(j+1)+"行,第:"+(k+1)+"列值:"+cellValue+"");         }    return cellValue;    }


/**     * 校验某个SHEET表 某一行 某一列 是否有数据     * @param sheet     * @param row 行号     * @param col 列号(从1开始)     * @return     */    public boolean checkRowHasDatas(HSSFSheet sheet,int row,int col){    boolean boo = false;        HSSFRow cols = sheet.getRow(row);//从默认第三行开始解析         if (cols != null) {             int cells = cols.getLastCellNum();//获得列数             //System.out.println("该SHEET表总列数: " + cells);            if(col > cells){            boo = false;            System.out.println("指定的列号大于总列数: " + col + " 总列数为:" + cells);            }            HSSFCell cell = cols.getCell(col);             String cellValue = "";            switch (cell.getCellType()) {             case HSSFCell.CELL_TYPE_NUMERIC: // 数值型                  if (HSSFDateUtil.isCellDateFormatted(cell)) {                      //如果是date类型则 ,获取该cell的date值                  cellValue = HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString(); //                         cellValue = cell.getDateCellValue().toString();                  }else{//纯数字                  cellValue = String.valueOf(cell.getNumericCellValue());                  }                 break;             /* 此行表示单元格的内容为string类型 */             case HSSFCell.CELL_TYPE_STRING: // 字符串型             cellValue = cell.getRichStringCellValue().toString();                 break;             case HSSFCell.CELL_TYPE_FORMULA://公式型                 //读公式计算值             cellValue = String.valueOf(cell.getNumericCellValue());                  if(cellValue.equals("NaN")){//如果获取的数据值为非法值,则转换为获取字符串                  cellValue = cell.getRichStringCellValue().toString();                  }                  //cell.getCellFormula();读公式                  break;             case HSSFCell.CELL_TYPE_BOOLEAN://布尔              cellValue = " " + cell.getBooleanCellValue();                   break;             /* 此行表示该单元格值为空 */             case HSSFCell.CELL_TYPE_BLANK: // 空值             cellValue = "";                 break;             case HSSFCell.CELL_TYPE_ERROR: // 故障             cellValue = "";                 break;             default:             cellValue = cell.getRichStringCellValue().toString();             }                        //如果每列的值都为空 就不导入            if (CommonUtils.isNotNull(cellValue)) {             if(!cellValue.equals(XmlPathDef.END_MARK)){            boo = true;                }else{                    boo = false;                }            }         }    return boo;    }    

/**     * 校验某行是否有数据     * 检验规则:只要有一列有数据就说明该行有数据     * @param sheet     * @param row 行号     * @return     */    public boolean checkRowHasDatas(HSSFSheet sheet,int row){     boolean boo = false;     HSSFRow cols = sheet.getRow(row);//从默认第三行开始解析          if (cols != null) {             int cells = cols.getLastCellNum();//获得列数             for (int k = 1; k < cells; k++) { // 列循环。默认从 1 开始 序号不解析                HSSFCell cell = cols.getCell(k);                 String cellValue = "";                switch (cell.getCellType()) {                 case HSSFCell.CELL_TYPE_NUMERIC: // 数值型                      if (HSSFDateUtil.isCellDateFormatted(cell)) {                          //如果是date类型则 ,获取该cell的date值                      cellValue = HSSFDateUtil.getJavaDate(cell.getNumericCellValue()).toString(); //                         cellValue = cell.getDateCellValue().toString();                      }else{//纯数字                      cellValue = String.valueOf(cell.getNumericCellValue());                      }                     break;                 /* 此行表示单元格的内容为string类型 */                 case HSSFCell.CELL_TYPE_STRING: // 字符串型                 cellValue = cell.getRichStringCellValue().toString();                     break;                 case HSSFCell.CELL_TYPE_FORMULA://公式型                     //读公式计算值                 cellValue = String.valueOf(cell.getNumericCellValue());                      if(cellValue.equals("NaN")){//如果获取的数据值为非法值,则转换为获取字符串                      cellValue = cell.getRichStringCellValue().toString();                      }                      //cell.getCellFormula();读公式                      break;                 case HSSFCell.CELL_TYPE_BOOLEAN://布尔                  cellValue = " " + cell.getBooleanCellValue();                       break;                 /* 此行表示该单元格值为空 */                 case HSSFCell.CELL_TYPE_BLANK: // 空值                 cellValue = "";                     break;                 case HSSFCell.CELL_TYPE_ERROR: // 故障                 cellValue = "";                     break;                 default:                 cellValue = cell.getRichStringCellValue().toString();                 }                                //如果每列的值都为空 就不导入                if (CommonUtils.isNotNull(cellValue)) {                 if(!cellValue.equals(XmlPathDef.END_MARK)){                boo = true;                break;                    }else{                     continue;                    }                }              }           }    return boo;    }    

 /**     * 校验SHEET表顺序是否正确     * @param workbook     * @return     */public StringBuffer checkSheetOrders(StringBuffer errLog,HSSFWorkbook workbook) throws Exception{        for (int i = XmlPathDef.START_SHEET_NUM; i < workbook.getNumberOfSheets(); i++){        if(i <= 20){        HSSFSheet sheet = workbook.getSheetAt(i);            String sheetName = sheet.getSheetName();            System.out.println("现在执行的表为:"+ sheetName);            if(CommonUtils.isNotNull(sheetName)){             if(!sheetName.equals(XmlPathDef.sheetARR[i-XmlPathDef.START_SHEET_NUM])){             if(errLog == null){             errLog = new StringBuffer().append("请确认:</br>");                  }             errLog.append("第" + i+ "个工作表是否为:【" + XmlPathDef.sheetARR[i-XmlPathDef.START_SHEET_NUM] + "】</br>");             }            }else{            creatObj(errLog);            errLog.append("该文件没有可以导入的表!</br>");            }        }}        return errLog;}

/** * 对比两个同类型的List<Object>返回差异List<Object>集合 * 处理规则:只要是关键字相同 就不管 不同则需要修改 * @param newModel 新对象list * @param oldModel 旧对象list * @param fieldNames[] 要比较的属性字段数组 * @param keyFieldName 主键属性字段 * @return  List<Object> */private List getModiflyList(List newModelList, List oldModelList, String[] fieldNames,String keyFieldName){    List list = null;    int fileNameLen = 0;    List oldModL = null;    //两个list对象都不能为空    if(newModelList != null && newModelList.size() > 0 && oldModelList != null     && oldModelList.size() > 0 && fieldNames != null && fieldNames.length > 0                  && CommonUtils.isNotNull(keyFieldName)){    for (Object newModel : newModelList) {  try {   if(oldModL == null){  oldModL = new ArrayList();  }  oldModL.addAll(oldModelList);   for (int i = 0; i < fieldNames.length; i++) { fileNameLen ++; //新的对象 Class cn = newModel.getClass();// 获得newModel的对象的Class实例 String fieldName = fieldNames[i];//取得要替换的对象属性字段 String getFieldMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);// get方法的名称 Method getMethodn =cn.getMethod(getFieldMethodName,new Class[] {}); Object valuen = getMethodn.invoke(newModel, new Object[] {}); // 调用newModel对象的get方法获得该属性的值 if(CommonUtils.isNotNull(valuen)){    Iterator it = oldModL.iterator();    while(it.hasNext()){ Object oldModel = it.next(); //旧的对象 Class co = oldModel.getClass();// 获得oldModel的对象的Class实例 Method getMethodo = co.getMethod(getFieldMethodName, new Class[]{}); Object valueo = getMethodo.invoke(oldModel, new Object[]{}); // 调用oldModel对象的get方法获得该属性的值  //如果两个对象的值不相同  if(!CommonUtils.isNotNull(valueo)){ //判断比较:如果对象值不为空   it.remove();    }else if(!valuen.equals(valueo)){    it.remove();  } }    //如果是计数器相等if(fileNameLen == fieldNames.length){if(oldModL != null && oldModL.size() > 0){if(list == null){list = new ArrayList<Object>();         }Object oldModE = oldModL.get(0);Class coe = oldModE.getClass();// 获得oldModel的对象的Class实例String getKeyMethodName = "get" + keyFieldName.substring(0, 1).toUpperCase() + keyFieldName.substring(1);// get方法的名称Method getFieldMethod = coe.getMethod(getKeyMethodName, new Class[]{});Object keyValue = getFieldMethod.invoke(oldModE, new Object[]{}); // 调用oldModel对象的get方法获得该属性的值String setKeyMethodName = "set" + keyFieldName.substring(0, 1).toUpperCase() + keyFieldName.substring(1);// set方法的名称//获取主键的Field TypeClass keyFieldType =null;Field[] fields = coe.getDeclaredFields(); // 获得copy对象的所有属性for(int j = 0; j < fields.length; j++) {// 把每一个属性进行赋值    Field field = fields[j];     String fieldName1 = field.getName(); // 获得属性名称    if(fieldName1.equals(keyFieldName)){    keyFieldType = field.getType();    }  }Method setMethod = coe.getMethod(setKeyMethodName, new Class[] {keyFieldType});// 获得set方法的实例setMethod.invoke(newModel, new Object[] {keyValue}); // 调用生成对象的set方法进行赋值list.add(newModel); }else{if(list == null){list = new ArrayList<Object>();    } list.add(newModel);}//重置计数器    fileNameLen = 0;    oldModL = null;    }    }   }} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}    }else{    list = newModelList;    }        return list;    } 

/** * @description: 由一个值对象转换成另外一个值对象 * @param srcObj:原值对象 * @param destObj:目标值对象 * @return * @throws Exception: */public static boolean obj2Obj(Object srcObj, Object destObj) {try {Class srcClassType = srcObj.getClass();Class destClassType = destObj.getClass();Field fields[] = destClassType.getDeclaredFields();for (int i = 0; i < fields.length; i++) {Field field = fields[i];String fieldName = field.getName();String firstLetter = fieldName.substring(0, 1).toUpperCase();String getMethodName = "get" + firstLetter + fieldName.substring(1);String setMethodName = "set" + firstLetter + fieldName.substring(1);System.out.println("getMethodName:----------   "  + getMethodName);if(CommonUtils.isNotNull(getMethodName) && !getMethodName.equals("getTAssetIases")&& !getMethodName.equals("getTProjEvtTypes")&& !getMethodName.equals("getTIasNodes")&& !getMethodName.equals("getTPeIases")){Method getMethod = srcClassType.getMethod(getMethodName,new Class[] {});Method setMethod = destClassType.getMethod(setMethodName,new Class[] { field.getType() });Object value = getMethod.invoke(srcObj, new Object[] {});setMethod.invoke(destObj, new Object[] { value });}}} catch (Exception e) {logger.error("数据拷贝错误!或者是实体不一致导致的");e.getStackTrace();}return true;}

**     * 解析XML文件,以Map<Integer, XlsLoadVerifyBean>对象的方式返回     * @param xmlPath     * @param beanName     * @return     * @throws Exception     */public  Map<Integer, XlsLoadVerifyBean> readXml(String xmlPath, String beanName) throws Exception{SAXReader saxReader = new SAXReader(); //使用SAXReader方式读取XML文件Map<Integer, XlsLoadVerifyBean> map = new HashMap<Integer, XlsLoadVerifyBean>();        //加载数据库XML配置文件,得到Document对象        Document document;try {File file = new File(xmlPath);   document = saxReader.read(file);Element root = document.getRootElement();//获得根节点        Iterator iterator = root.elementIterator();while(iterator.hasNext()){ Element element = (Element) iterator.next();         if(element.attributeValue("name") != null){         Iterator property = element.elementIterator();         while(property.hasNext()){         Element elementPro = (Element) property.next();         XlsLoadVerifyBean xlsLoadVerifyBean = new XlsLoadVerifyBean();         xlsLoadVerifyBean.setName(elementPro.attributeValue("name"));         xlsLoadVerifyBean.setLength(Integer.valueOf((elementPro.attributeValue("length") == null || elementPro.attributeValue("length") == "") ? "0" : elementPro.attributeValue("length")));         xlsLoadVerifyBean.setNull(Boolean.valueOf((elementPro.attributeValue("isnull") == null || elementPro.attributeValue("isnull") == "") ? "true" : elementPro.attributeValue("isnull")));                      xlsLoadVerifyBean.setType(elementPro.attributeValue("type"));         xlsLoadVerifyBean.setCnName(elementPro.attributeValue("cnname"));         map.put(Integer.valueOf(elementPro.attributeValue("position")), xlsLoadVerifyBean);         }         }}} catch (DocumentException e) {e.printStackTrace();} return map; }

/** *  根据XML文件配置的规则进行校验(字符校验) * @param xlsLoadVerifyBean * @param rowNum * @param colNum * @param excelValue * @param sheetName * @param n * @return */public StringBuffer verifyBean(StringBuffer errLog,XlsLoadVerifyBean xlsLoadVerifyBean, int j, int k, String excelValue,String sheetName,int n,String cnName){ //校验是否可以为空if(!CommonUtils.isNotNull(cnName)){if(!xlsLoadVerifyBean.isNull()){//如果定义的字段不可以为空  errLog = creatObj(errLog);          errLog.append("第" + n + "个工作表:【" + sheetName +"】 中,第:" + (j+1) + "行、第:"+ (k+1) + "列所对应的:  [" + cnName + "]  不允许为空;该行暂未导入!</br>");       }}    if(xlsLoadVerifyBean.getLength() > 0){           if(excelValue.length() > xlsLoadVerifyBean.getLength()){              errLog = creatObj(errLog);            errLog.append("第" + n + "个工作表:【" + sheetName +"】 中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 超过系统规定字符长度,现值为:" + excelValue + ",该行暂未导入!</br>");           }           }       if(xlsLoadVerifyBean.getType().equals("Integer")){    Pattern pattern = Pattern.compile("[0-9]*");               Matcher isNum = pattern.matcher(excelValue);                if( !isNum.matches() ) {               errLog = creatObj(errLog);                errLog.append("第" + n + "个工作表:【" + sheetName +"】 中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 必须为数字类型,现值为:" + excelValue + ",该行暂未导入!</br>");              }       }else if(xlsLoadVerifyBean.getType().equals("date")){        if(CommonUtils.isNotNull(excelValue) && excelValue.indexOf("-") != -1 && excelValue.indexOf(".") == -1){    Pattern pattern = Pattern.compile("[0-9]*");     String str_4 = excelValue.substring(0,4);                 Matcher isNum_4 = pattern.matcher(str_4);     if(excelValue.length() < 8 || !isNum_4.matches()){    errLog = creatObj(errLog);                    errLog.append("第" + n + "个工作表:【" + sheetName +"】 中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 日期输入错误,必须为:' yyyy-MM-dd '格式,现值为:" + excelValue + ",该行暂未导入!</br>");       }else{    if(excelValue.length() >= 10){    String str_1 = excelValue.substring(4,5);     String str_2 = excelValue.substring(5,6);     String str_3 = excelValue.substring(6,7);     String str_5 = excelValue.substring(7,8);    String str_6 = excelValue.substring(8,9);     String str_7 = excelValue.substring(9,10);        if((pattern.matcher(str_2).matches() && Integer.parseInt(str_2) > 1 )||     !str_1.equals("-") ||!str_5.equals("-") ||    (Integer.parseInt(str_2) == 1 && Integer.parseInt(str_3) > 2) ||    (pattern.matcher(str_6).matches() && Integer.parseInt(str_6) > 4 )||     !pattern.matcher(str_2).matches()|| !pattern.matcher(str_3).matches() ||     !pattern.matcher(str_6).matches() || !pattern.matcher(str_7).matches() ||    (pattern.matcher(str_6).matches() && Integer.parseInt(str_6) == 3 && pattern.matcher(str_7).matches() && Integer.parseInt(str_7) > 1) ||    (pattern.matcher(str_6).matches() && Integer.parseInt(str_6) > 3)){    errLog = creatObj(errLog);    errLog.append("第" + n + "个工作表:【" + sheetName +"】 中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 日期输入错误,必须为:' yyyy-MM-dd '格式,现值为:" + excelValue + ",该行暂未导入!</br>");       }    }else{    errLog = creatObj(errLog);        errLog.append("第" + n + "个工作表:【" + sheetName +"】 中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 日期输入错误,必须为:' yyyy-MM-dd '格式,现值为:" + excelValue + ",该行暂未导入!</br>");    }//    else if(excelValue.length() == 9){//    String str_8 = excelValue.substring(6,7); //    String str_9 = excelValue.substring(8,9); //    if((pattern.matcher(str_8).matches() && Integer.parseInt(str_8) == 3 && pattern.matcher(str_9).matches() && Integer.parseInt(str_9) > 1)){//    errLog += "第 【" + (n+1) + "】个工作表:" + sheetName +"中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 日期输入错误,请修改后重新导入</br>";   //    }    }    }else{    errLog = creatObj(errLog);    errLog.append("第" + n + "个工作表:【" + sheetName +"】 中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 日期输入错误,必须为:' yyyy-MM-dd '格式,现值为:" + excelValue + ",该行暂未导入!</br>");    }//    Pattern pattern = Pattern.compile("[1-9][0-9]{3}\\-([1-9]|1[0-2])\\-([1-9]|1[0-9]|2[0-9]|3[0-1])");   //            Matcher isNum = pattern.matcher(excelValue);    //            if( !isNum.matches() ) {   //                errLog += "第 【" + (n+1) + "】个工作表:" + sheetName +"中,第" + (j+1) + "行,第" + (k+1) + "列所对应的:  [" + cnName + "] 必须为日期类型,请修改后重新导入</br>";   //            }       }    return errLog;   }   

/** * 取得计算方法名 * @param projectId * @return * @throws Exception  */public String getCalcMethodId(Long projectId) throws Exception{String methodName = "";TCalcMethod calcMethod = calcMethodService.findAssetCMByProject(projectId);if(calcMethod != null){methodName = calcMethod.getMethodName();}return methodName;}

4.调用校验的总方法:

/**     * 保存2、3个 SHEET 表     * @param errLog     * @param okLog     * @param workBook     * @return     */public Map<String,Object> save234Wb(StringBuffer errLog,StringBuffer okLog,HSSFWorkbook workBook,Long projectId){    Map<String,Object> map = null;    List<TEvtSysInfo> evtSysInfolist = null;    List<TNode> nodelist = null;    //定义跳出循环的变量    int bknum = 0;    int rowsnum = 0;    String verifyFiled = "";    String[] arrStr = null;    //根节点值TNode nodeRoot0 = null;    //获取所对应的二维数组        String[][] nodeArr = null;               //---------定义实体类型开始-----------------------        //TCompany company = null; //1       TEvtSysInfo evtSysInfo2 = null;//2       //---------定义实体类型结束-----------------------            try{    for(int i1 = XmlPathDef.START_SHEET_NUM; i1 <= 10; i1++) {    if(i1 == 2 || i1 == 3 || i1 == 4 || i1 == 10){        if(!hasCellNumber(workBook, i1)){        bknum = 1;        errLog = getAllCellString(errLog, workBook, i1);        }    }    }    if(bknum == 0){       for(int i = XmlPathDef.START_SHEET_NUM; i <= 4; i++) { //默认从第2个sheet表开始解析       int cellAllNum = getAllCellNumber(workBook, i);//获取该SHEET表的有效总行数       System.out.println(" "+i+" ***************要解析的工作表名称为:"+workBook.getSheetName(i)+"  ************</font><br>");           int defNum = i-XmlPathDef.START_SHEET_NUM;//定义读取sheetXML的开始点           String xmlPath = xmlPathDef.getXmlBasePath(XmlPathDef.sheetXML[defNum]);//取得工作表对象的XML定义文件的路径           Map<Integer, XlsLoadVerifyBean> xmlMap = readXml(xmlPath, XmlPathDef.sheetXML[defNum]); //从配置文件中读取XLS文件中的参数位置配置            HSSFSheet sheet = workBook.getSheetAt(i); //取得工作表             sheet.getMargin(HSSFSheet.TopMargin); //回到sheet表最顶端开始解析            //装载查询条件            Map mapParam = new HashMap();mapParam.put(CommonConstant.PROJECTMANAGE_PROJECTID, projectId);mapParam.put(CommonConstant.INFOMANAGER_PARENTNODEID, "");       ///////////////////////        ///////////////////////                        for (int j = 3; j < 3+cellAllNum; j++) {//行循环:默认从第三行开始解析             //如果是第一个sheet表,默认只导入第一条记录,后面的不导入            if(XmlPathDef.sheetXML[defNum].equals("TEvtSysInfo")){             if(j>3){            continue;             }else{             cellAllNum = 1;             }            }            rowsnum++;//统计执行的总行数,用作判断           //---------定义实体类型开始-----------------------            //TCompany company = null; //1           TEvtSysInfo evtSysInfo = null;//2           TNode node = null;//3           //---------定义实体类型结束-----------------------                     ///////////////////////         ///////////////////////                //开始解析取值,并做保存                   HSSFRow row = sheet.getRow(j);                    if (row != null) {                          int cells = row.getLastCellNum(); //获得总列数                          for (int k = 1; k < cells; k++) { //列循环: 默认从 1开始 (第0列序号不解析)                           HSSFCell cell = row.getCell(k);                            ///////////////////////                            if (cell != null) {                                //校验是否正确             if(xmlMap.get(k) != null){//循环 校验XML中定义的字段校验规则             XlsLoadVerifyBean xlsBean = (XlsLoadVerifyBean)xmlMap.get(k);             String name = xlsBean.getName();             String cnName = xlsBean.getCnName();             String type = xlsBean.getType();//字符类型             String cellValue = getCellValue(cell, type, i, j, k);                                      //如果解析的字段不是 "填表注意事项:否则不解析了                                    if(!cellValue.equals(XmlPathDef.END_MARK)){                                                                //校验Excel中取得的值的符合性         errLog = verifyBean(errLog,xlsBean, j, k, cellValue,workBook.getSheetName(i),i,cnName);                  //如果校验失败,则循环,继续(说明本行有问题)         if(CommonUtils.isNotNull(errLog)){         bknum = 1;         break;         }else{         //开始给对象赋值,如果值不为空,则放入对象中      if(CommonUtils.isNotNull(cellValue)){      if(CommonUtils.isNotNull(workBook.getSheetName(i))){                     if(workBook.getSheetName(i).equals(XmlPathDef.sheetARR[defNum])){           if(defNum==0){//如果是:2 被评估系统基本情况表           if(evtSysInfo ==null){                     evtSysInfo = new TEvtSysInfo();                    //----------放置 TProject参数 开始----------           TProject project = new TProject();           project.setProjectId(projectId);           evtSysInfo.setTProject(project);           //----------放置 TProject参数 结束----------                   }                   BeanUtils.setProperty(evtSysInfo, name, cellValue);                   System.out.println(".......放入evtSysInfo对象中第:" + k +"次,值为:"+  cellValue);           }else if(defNum==1){//如果是:2 节点表           if(node ==null){                           node = new TNode();                                                    //----------放置 TProject参数 开始----------           TProject project = new TProject();           project.setProjectId(projectId);           node.setTProject(project);           //----------放置 TProject参数 结束----------                      }                  BeanUtils.setProperty(node, name, cellValue);                  System.out.println(".......放入node对象中第:" + k +"次,值为:"+  cellValue);                 }                }            }                     }            }                                  }      }                                if(bknum == 1){                                break;                                }         }         if(bknum == 1){                            break;                            }                    if(k+1 == cells){           //如果循环完一行,则往list中放一次数据   if(defNum==0){   //2、信息系统基本情况表       if(evtSysInfo != null){    if(evtSysInfolist == null){    evtSysInfolist =new ArrayList<TEvtSysInfo>();        }    evtSysInfolist.add(evtSysInfo);                       }        //如果总行数和执行的行数相等,则说明是最后一次循环     if(rowsnum == cellAllNum){    //执行数据库操作List<TEvtSysInfo> listOld = systemInfoDao.findTheObByProjectId(projectId);//获取需要校验的关键字段数组    verifyFiled = XmlPathDef.getNumByName(XmlPathDef.verifyFileds,XmlPathDef.sheetXML[defNum]);        arrStr = getArrStr(verifyFiled);        List<TEvtSysInfo> modiflyList = getModiflyList(evtSysInfolist, listOld, arrStr,XmlPathDef.getNumByName(XmlPathDef.keyFieldNames,XmlPathDef.sheetXML[defNum]));        if(modiflyList != null && modiflyList.size() > 0){         for(TEvtSysInfo evtSysInfos:modiflyList){    String systemId = evtSysInfos.getSystemId();     if (!CommonUtils.isNotNull(systemId)) {      systemId = this.getSystemId();     evtSysInfos.setSystemId(systemId);    }//保存systemInfoDao.getSession().merge(evtSysInfos);    }    }        evtSysInfo2 = systemInfoDao.findTheObBy(mapParam);    okLog = creatObj(okLog);    okLog.append(markMsg(i-XmlPathDef.START_SHEET_NUM, cellAllNum, 1));//生成MSG消息    rowsnum = 0;    }           }else if(defNum==1){//如果是:节点信息表              if(node != null){    if(nodelist == null){    nodelist =new ArrayList<TNode>();        }    nodelist.add(node);                       }        //如果总行数和执行的行数相等,则说明是最后一次循环    if(cellAllNum == rowsnum){    //执行数据库操作List<TNode> listOld = nodeInfoDao.findByConditions(mapParam);//获取需要校验的关键字段数组    verifyFiled = XmlPathDef.getNumByName(XmlPathDef.verifyFileds,XmlPathDef.sheetXML[defNum]);        arrStr = getArrStr(verifyFiled);        List<TNode> modiflyList = getModiflyList(nodelist, listOld, arrStr,XmlPathDef.getNumByName(XmlPathDef.keyFieldNames,XmlPathDef.sheetXML[defNum]));    if(modiflyList != null && modiflyList.size() > 0){           for(TNode nodes:modiflyList){    nodeRoot0 = nodeInfoDao.findTheNode(mapParam);    if(!CommonUtils.isNotNull(nodeRoot0)){    if(listOld == null || listOld.size() == 0){       TNode nodeRoots = new TNode();       nodeRoots.setNodeId(this.getNodeId(CommonConstant.task_default));       //----------放置 TProject参数 开始----------TProject projectRoot = new TProject();projectRoot.setProjectId(projectId);nodeRoots.setTProject(projectRoot);nodeRoots.setTProject(projectRoot);//----------放置 TProject参数 结束----------nodeRoots.setName("root"); //保存 nodeInfoDao.getSession().merge(nodeRoots); nodeRoot0 = nodeInfoDao.findTheNode(mapParam);       }else{        nodeRoot0 = nodeInfoDao.findTheNode(mapParam);       }    }     //然后再做保存     String nodeId = nodes.getNodeId();     if (!CommonUtils.isNotNull(nodeId)) {      nodeId = this.getNodeId(CommonConstant.task_default);     nodes.setNodeId(nodeId);    }     nodes.setTNode(nodeRoot0);//父节点//保存nodeInfoDao.getSession().merge(nodes);    }    }nodeArr = get2ArrFromList(nodeInfoDao.findByConditions(mapParam),node);okLog = creatObj(okLog);okLog.append(markMsg(i-XmlPathDef.START_SHEET_NUM, cellAllNum, 1));//生成MSG消息rowsnum = 0;     }          }              }         }                  }             }          }    }   } catch (Exception ex) {        ex.printStackTrace();    }    if(CommonUtils.isNotNull(errLog)){   if(map == null){   map = new HashMap<String,Object>();   }   map.put("errLog",errLog);   }   if(CommonUtils.isNotNull(okLog)){   if(map == null){   map = new HashMap<String,Object>();   }   map.put("okLog",okLog);   }   return map;  }


原创粉丝点击