zoukankan      html  css  js  c++  java
  • java基于xml配置的通用excel单表数据导入组件(四、DAO主处理类)

    package XXXXX.manage.importexcel;
    
    import java.beans.IntrospectionException;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.logging.Logger;
    
    import org.apache.commons.betwixt.io.BeanReader;
    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    import org.xml.sax.SAXException;
    
    import XXXXX.cache.UserSession;
    import xxxxxxxx.manage.importerror.BN_ImportError;
    import xxxxxxxx.manage.importerror.DAO_ImportError;
    import xxxxxxxx.supp.BN_Row;
    import xxxxxxxx.supp.DAORunner;
    import xxxxxxxx.supp.TransactionHandler;
    import xxxxxxxx.util.ObjectUtil;
    import xxxxxxxx.util.PathUtil;
    import xxxxxxxx.util.StringUtil;
    
    public class DAO_ImportExcel {
    
        private String tableImport;  //导入的临时表名
        private String tableTarget;  //导入的目标表名
        private File excelFile;      //excel数据文件
        private int rows;            //总行数
        private int columns;         //总列数
        private Map<String, BN_Column> columnMap = new HashMap();// 列序号、字段定义映射
        private String[] columnName; // excel列名
    
        private BN_ImportExcel xmlBean;
        private Map<String, BN_Column> excelColumn; // 列名称、字段定义映射
        private Map<String, BN_Column> systemColumn;// 系统内置字段定义
        
        Map<String, Object> resultMap = new HashMap<String, Object>();// 定义返回结果map
    
        private static Logger logger = Logger.getLogger(DAO_ImportExcel.class
                .getName());
    
        public DAO_ImportExcel(String tableTarget, File excelFile) {
            this.tableTarget = tableTarget;
            this.tableImport = tableTarget + "_import";  //导入临时表,固定以"_import"结尾
            this.excelFile = excelFile;
            loadXmlBean();
        }
    
        private void loadXmlBean() {
            BeanReader beanReader = new BeanReader();
            // 配置BeanReader实例
            beanReader.getXMLIntrospector().getConfiguration()
                    .setAttributesForPrimitives(false);
            beanReader.getBindingConfiguration().setMapIDs(false); // 不自动生成ID
            // 注册要转换对象的类,并指定根节点名称
            BufferedReader br = null;
            try {
                beanReader.registerBeanClass("importExcel", BN_ImportExcel.class);
                br = new BufferedReader(new InputStreamReader(
                        new FileInputStream(new File(
                                PathUtil.getPath("/WEB-INF/excel/" + tableImport + ".xml"))), "GBK"));
                // 将XML解析Java Object
                xmlBean = (BN_ImportExcel) beanReader.parse(br);
                excelColumn = xmlBean.getExcelColumn();
                systemColumn = xmlBean.getSystemColumn();
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IntrospectionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SAXException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (br != null){
                    try {
                        br.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
    
        public Map doImport() {
            Workbook workBook = null;
            try {
                workBook = new XSSFWorkbook(new FileInputStream(excelFile));
            } catch (Exception ex) {
                try {
                    workBook = new HSSFWorkbook(new FileInputStream(excelFile));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (workBook == null){
                resultMap.put("result", false);
                resultMap.put("message", "导入失败!无法加载该数据文件,请检查文件格式是否正确.");
                return resultMap;
            }
            Sheet sheet = workBook.getSheetAt(0);
            rows = sheet.getPhysicalNumberOfRows();
            columns = sheet.getRow(0).getPhysicalNumberOfCells();
            logger.info("rows=" + rows + "  columns=" + columns);
            if (rows <= 1 || columns == 0 ){
                resultMap.put("result", true);
                resultMap.put("error", false);
                resultMap.put("message", "系统没有检测到需要导入的数据内容!");
                return resultMap;
            }
            columnName = new String[columns];
            
            //执行数据操作之前的初始化脚本initSQL
            boolean initResult = runXMLSQL(xmlBean.getInitSQL());
            if (!initResult){
                resultMap.put("result", false);
                resultMap.put("message", "系统初始化失败,请检查配置文件'"+tableImport+".xm'的initSQL是否正确!");
                return resultMap;
            }
            
            // 解析第一行表头列名
            Iterator cellIterator = sheet.getRow(0).cellIterator();
            StringBuffer memo = new StringBuffer();
            while (cellIterator.hasNext()) {
                Cell cell = (Cell) cellIterator.next();
                // 读取当前单元格的值
                String cellValue = cell.getStringCellValue();
                logger.info("cell[0," + cell.getColumnIndex() + "]=" + cellValue);
                columnName[cell.getColumnIndex()] = cellValue;
                if (excelColumn.containsKey(cellValue)) {
                    columnMap.put(cell.getColumnIndex() + "",
                            (BN_Column) excelColumn.get(cellValue));
                } else {
                    memo.append("列名[").append(cellValue).append("] ");
                    logger.info("cell[0," + cell.getColumnIndex() + "]列名["
                            + cellValue + "]" + "未在xml的<excelColumn>节点内定义!无法解析导入");
                }
            }
            if (memo.length() > 0) {// 有未在xml的<excelColumn>节点内定义的列
                BN_ImportError errorBean = new BN_ImportError();
                errorBean.setOp_id(StringUtil.getUUID());
                errorBean.setOp_name(tableTarget);
                errorBean.setRow_no("1");
                errorBean.setMemo(memo.toString()+" 未在xml配置文件中定义,无法解析导入!");
                errorBean.setCreate_id(UserSession.getOpId());
                errorBean.setCreate_name(UserSession.getOpName());
                errorBean.setCreate_time(BN_Row.getNowInput());
                DAO_ImportError.doInsert(errorBean, null);
            }
    
            // 解析数据行(从第2行开始)
            for (int rowNum = 1; rowNum < rows; rowNum++) {
                cellIterator = sheet.getRow(rowNum).cellIterator();
                memo = new StringBuffer();
                BN_Row rowBean = new BN_Row();
                // 处理表格数据
                while (cellIterator.hasNext()) {
                    Cell cell = (Cell) cellIterator.next();
                    String cellValue = getCellValue(cell);
                    logger.info("cell[" + rowNum + "," + cell.getColumnIndex() + "]=" + cellValue);
                    if (columnMap.containsKey(cell.getColumnIndex() + "")) {// 列名有在xml中有定义
                        BN_Column columnBean = columnMap.get(cell.getColumnIndex() + "");
                        Object[] parseResult = parseCell(columnBean, rowNum,
                                columnName[cell.getColumnIndex()], cellValue);
                        if (parseResult[0] != null) {
                            rowBean.setColumnValue(columnBean.getColumn(), parseResult[0]);
                        } else {
                            if (parseResult[1] != null) {
                                memo.append(parseResult[1]);
                            }
                        }
                    }
                }
                if (memo.length() > 0) {// 有不符合内容格式要求的字段
                    logger.info("第["+(rowNum + 1)+"行] "+memo.toString());
                    BN_ImportError errorBean = new BN_ImportError();
                    errorBean.setOp_id(StringUtil.getUUID());
                    errorBean.setOp_name(tableTarget);
                    errorBean.setRow_no((rowNum + 1) + "");
                    errorBean.setMemo(memo.toString());
                    errorBean.setCreate_id(UserSession.getOpId());
                    errorBean.setCreate_name(UserSession.getOpName());
                    errorBean.setCreate_time(BN_Row.getNowInput());
                    DAO_ImportError.doInsert(errorBean, null);
                } else {
                    // 系统级字段
                    Iterator iterator = systemColumn.keySet().iterator();
                    while (iterator.hasNext()) {
                        String key = iterator.next().toString();
                        BN_Column sysColumnBean = systemColumn.get(key);
                        Object result = transfer(sysColumnBean.getDataType(), "",
                                sysColumnBean.getClassName(),
                                sysColumnBean.getMethod(), sysColumnBean.getParam());
                        if (result != null) {
                            rowBean.setColumnValue(sysColumnBean.getColumn(),
                                    result);
                        }
                    }
                    int result = DAORunner.insertRow(tableImport, rowBean);
                    if (result == -1){//保存临时表失败,登记错误信息
                        BN_ImportError errorBean = new BN_ImportError();
                        errorBean.setOp_id(StringUtil.getUUID());
                        errorBean.setOp_name(tableTarget);
                        errorBean.setRow_no((rowNum + 1) + "");
                        errorBean.setMemo("数据保存失败");
                        errorBean.setCreate_id(UserSession.getOpId());
                        errorBean.setCreate_name(UserSession.getOpName());
                        errorBean.setCreate_time(BN_Row.getNowInput());
                        DAO_ImportError.doInsert(errorBean, null);
                    }
                }
            }
            //计算自己导入成功的数据条数
            int dataSuccNum = DAORunner.count("select count(*) from "+tableImport+" where create_id=?", 
                    new Object[]{UserSession.getOpId()});
            //计算自己文件解析失败的数据条数,排除首行列名解析问题
            int dataFailNum = DAORunner.count("select count(*) from t_import_error where create_id=? and row_no != ?",  
                    new Object[]{UserSession.getOpId(), 1});
            int columnFailNum = DAORunner.count("select count(*) from t_import_error where create_id=? and row_no = ?",  
                    new Object[]{UserSession.getOpId(), 1});
            boolean result = DAORunner.runTransaction(new TransactionHandler() {
                public void process(Connection connections) throws SQLException {
                    //执行数据转移前的脚本 beforeSaveSQL
                    if (!ObjectUtil.isNull(xmlBean.getBeforeSaveSQL())){
                        String[] sqlArr = xmlBean.getBeforeSaveSQL().split(";");
                        for (int i = 0 ; i < sqlArr.length ; i ++){
                            DAORunner.runUpdate(sqlArr[i].replaceAll("\$\{userId}", UserSession.getOpId()),
                                    new Object[]{}, connections);
                        }
                    }
                    
                    //转移数据至tableTarget
                    DAORunner.runUpdate("insert into "+tableTarget+" select * from "+tableImport+" where create_id=?",
                            new Object[]{UserSession.getOpId()}, connections);
                    
                    //执行数据转移后的脚本 afterSaveSQL
                    if (!ObjectUtil.isNull(xmlBean.getBeforeSaveSQL())){
                        String[] sqlArr = xmlBean.getAfterSaveSQL().split(";");
                        for (int i = 0 ; i < sqlArr.length ; i ++){
                            DAORunner.runUpdate(sqlArr[i].replaceAll("\$\{userId}", UserSession.getOpId()),
                                    new Object[]{}, connections);
                        }
                    }
                }
            });
            if (result){
                resultMap.put("result", true);
                if ((dataFailNum + columnFailNum) > 0){//excel出现问题数据
                    resultMap.put("error", true);
                }
                StringBuffer message = new StringBuffer();
                message.append("已成功导入").append(dataSuccNum).append("条数据!");
                if (dataFailNum > 0){
                    message.append("有").append(dataFailNum).append("条数据因格式内容有问题无法导入!");
                }
                if (columnFailNum > 0){
                    message.append("个别列名未在xml配置文件中定义无法导入!");
                }
                resultMap.put("message", message.toString());
                return resultMap;
            }else{
                resultMap.put("result", false);
                resultMap.put("message", "数据导入失败,请重新尝试!");
            }
            return resultMap;
        }
    
        private String getCellValue(Cell cell) {
            int type = cell.getCellType();
            switch (type) {
            case Cell.CELL_TYPE_NUMERIC:// 数值、日期类型
                double d = cell.getNumericCellValue();
                if (HSSFDateUtil.isCellDateFormatted(cell)) {// 日期类型
                    Date date = HSSFDateUtil.getJavaDate(d);
                    return new SimpleDateFormat("yyyyMMdd").format(date);
                } else {// 数值类型
                    return d + "";
                }
            case Cell.CELL_TYPE_BLANK:// 空白单元格
                return null;
            case Cell.CELL_TYPE_STRING:// 字符类型
                return cell.getStringCellValue();
            case Cell.CELL_TYPE_BOOLEAN:// 布尔类型
                return cell.getBooleanCellValue() + "";
            default:
                logger.info("未处理类型["+type+"]");
                break;
            }
            return null;
        }
    
        private Object transfer(String dataType, String cellValue,
                String className, String method, String param) {
            try {
                Class[] classArr = null;
                Object[] valueArr = null;
                if (ObjectUtil.isNull(param)) {
                    classArr = new Class[] {};
                    valueArr = new Object[] {};
                } else {
                    String[] paramArr = param.split(",");
                    classArr = new Class[paramArr.length];
                    valueArr = new Object[paramArr.length];
                    for (int i = 0; i < paramArr.length; i++) {
                        if ("${self}".equals(paramArr[i])) {
                            if ("varchar".equals(dataType)
                                    || "date".equals(dataType)) {
                                classArr[i] = String.class;
                                valueArr[i] = cellValue;
                            } else if ("int".equals(param)) {
                                classArr[i] = int.class;
                                valueArr[i] = new Integer(cellValue);
                            } else if ("float".equals(param)) {
                                classArr[i] = float.class;
                                valueArr[i] = new Float(cellValue);
                            }
                        } else {
                            String typeStr = paramArr[i].split(":")[0];
                            String valueStr = paramArr[i].split(":")[1];
                            if ("varchar".equals(typeStr)) {
                                classArr[i] = String.class;
                                valueArr[i] = valueStr;
                            } else if ("int".equals(typeStr)) {
                                classArr[i] = int.class;
                                valueArr[i] = new Integer(valueStr);
                            } else if ("float".equals(typeStr)) {
                                classArr[i] = float.class;
                                valueArr[i] = new Float(valueStr);
                            }
                        }
                    }
                }
                Class tClass = Class.forName(className);
                Object classInstance = tClass.newInstance();
                Method classMethod = tClass.getMethod(method, classArr);
                Object result = classMethod.invoke(classInstance, valueArr);
                return result;
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
        private Object[] parseCell(BN_Column columnBean, int rowNum,
                String columnName, String cellValue) {
            Object[] objectArr = new Object[2];
            String dataType = columnBean.getDataType();
            int length = columnBean.getLength();
            boolean required = columnBean.isRequired();
            boolean transfer = columnBean.isTransfer();
    
            if (ObjectUtil.isNull(cellValue)) {
                if (required) {
                    objectArr[0] = null;
                    objectArr[1] = """ + columnName + ""不能为空! ";
                    return objectArr;
                } else {
                    objectArr[0] = null;
                    objectArr[1] = null;
                    return objectArr;
                }
            }
    
            if (transfer) {// 需要转换内容
                String className = columnBean.getClassName();
                String method = columnBean.getMethod();
                String param = columnBean.getParam();
                Object result = transfer(dataType, cellValue, className, method,
                        param);
                logger.info("[" + rowNum + "," + columnName + "]转换结果=" + result);
                objectArr[0] = result;
                objectArr[1] = null;
            } else {// 不需要转换内容
                    // 根据数据类型检查长度和内容是否符合字段要求
                if ("varchar".equals(dataType) || "date".equals(dataType)) {
                    if (length != 0 && cellValue.length() > length) {
                        objectArr[0] = null;
                        objectArr[1] = """ + columnName + ""内容超过最大长度" + length + "的限制! ";
                    } else {
                        objectArr[0] = cellValue;
                        objectArr[1] = null;
                    }
                } else if ("int".equals(dataType)) {
                    if (!StringUtil.isInteger(cellValue)) {
                        objectArr[0] = null;
                        objectArr[1] = """ + columnName + ""内容应为整数! ";
                    } else {
                        objectArr[0] = new Integer(cellValue);
                        objectArr[1] = null;
                    }
                } else if ("float".equals(dataType)) {
                    if (!StringUtil.isDouble(cellValue)) {
                        objectArr[0] = null;
                        objectArr[1] = """ + columnName + ""内容应为浮点数! ";
                    } else {
                        objectArr[0] = new Float(cellValue);
                        objectArr[1] = null;
                    }
                }
            }
    
            return objectArr;
        }
        
        private boolean runXMLSQL(final String sqlStr){
            if (ObjectUtil.isNull(sqlStr)){
                return true;
            }
            return DAORunner.runTransaction(new TransactionHandler() {
                public void process(Connection connections) throws SQLException {
                    String[] sqlArr = sqlStr.split(";");
                    for (int i = 0 ; i < sqlArr.length ; i ++){
                        DAORunner.runUpdate(sqlArr[i].replaceAll("\$\{userId}", UserSession.getOpId()),
                                new Object[]{}, connections);
                    }
                }
            });
        }
    
        public static void main(String[] args) throws Exception {
        }
    }
  • 相关阅读:
    UNP(2rd)第二卷源码编译
    A very hard mathematic problem
    并查集~
    N皇后问题 深搜dfs
    实践中的一点小问题
    java环境配置 HelloWorld
    精确时间计算方法
    C语言关于文件操作
    字典树应用~
    并查集应用2
  • 原文地址:https://www.cnblogs.com/101key/p/3286512.html
Copyright © 2011-2022 走看看