动态!!超详细完善的Excel动态导入Mysql,支持导入不同表,集成后只需配置就可以实现动态导入excel到数据库

说明简介:当你项目中集成以下功能,我们便可以避免因为excel导入到数据库功能编写过多的代码。
我们只需按照要求少量的在数据库编写配置信息。实现接口便可以完成导入,无需再写导入相关代码。
1、复用性强,适用于多场景。
2、支持多sheet导入到多表
3、支持合并单元格读取
4、支持空单元格
5、支持单元格输入now()字符串导入数据库为当前时间LocaldateTime.now()
6、支持对每个字段编写检验规则,通过才会导入到数据库
7、包含日志表,方便查询
8、会生成临时表,以供参考

文章较长,请耐心看完。希望对你有所帮助

1、环境

gradle

    //数据导出excel
    compile 'org.apache.poi:poi:4.1.2'
    compile 'org.apache.poi:poi-ooxml:4.1.2'
    compile 'org.apache.poi:poi-ooxml-schemas:4.1.2'
    //mybatis-plus
    compile group: 'com.baomidou', name: 'mybatis-plus-boot-starter', version: '3.4.1'
    compile group: 'com.baomidou', name: 'mybatis-plus-generator', version: '3.4.1'
    // https://mvnrepository.com/artifact/org.freemarker/freemarker
    implementation group: 'org.freemarker', name: 'freemarker', version: '2.3.30'
// https://mvnrepository.com/artifact/com.aventstack/extentreports
    implementation group: 'com.aventstack', name: 'extentreports', version: '5.0.1'

Maven

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>
<!--mybatis-plus-->
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
<dependency>
    <groupId>com.aventstack</groupId>
    <artifactId>extentreports</artifactId>
    <version>5.0.1</version>
</dependency>

2、需要用到的mysql表

导入数据存储日志信息表[pub_imp_excel_jd_log]

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for pub_imp_excel_jd_log
-- ----------------------------
DROP TABLE IF EXISTS `pub_imp_excel_jd_log`;
CREATE TABLE `pub_imp_excel_jd_log`  (
  `id` bigint(18) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `menu_id` bigint(18) NULL DEFAULT NULL COMMENT '操作菜单ID',
  `pc_num` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '批次UUID',
  `jd_state` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '进度名称,大批量异步上传,每完成一个阶段,更新此名称,便于用户了解导入进度',
  `state` int(11) NULL DEFAULT NULL COMMENT '有效性状态,1表示有效,9表示已撤销',
  `start_time` datetime NULL DEFAULT NULL COMMENT '导入开始时间',
  `end_time` datetime NULL DEFAULT NULL COMMENT '导入截止时间',
  `oper_uid` bigint(18) NULL DEFAULT NULL COMMENT '操作用户',
  `source_file_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '上传数据表文件名称,便于用户识别',
  `problemnum` int(11) NULL DEFAULT NULL COMMENT '校验不通过记录数',
  `souce_file_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '导入文件上传后在服务器上的存储路径(不展示,用于开发人员检索核对)',
  `tmp_table_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成临时表名称',
  `md5code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '文件的MD5码(判断文件重复,则不需要导入)',
  `total_row` int(11) NULL DEFAULT NULL COMMENT '导入记录总数(总行数)',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 151 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '批量导入日志信息表(提供导入日志查询功能)' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

表信息[pub_imp_excel_model]

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for pub_imp_excel_model
-- ----------------------------
DROP TABLE IF EXISTS `pub_imp_excel_model`;
CREATE TABLE `pub_imp_excel_model`  (
  `id` bigint(13) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `oper_uid` bigint(13) NULL DEFAULT NULL COMMENT '操作人员ID,通用型操作人员id为0',
  `menu_id` bigint(13) NULL DEFAULT NULL COMMENT '菜单ID,导入按钮菜单ID,一表多sheet情况menu_id相同',
  `state` int(3) NULL DEFAULT 1 COMMENT '状态,1表示有效,9表示无效',
  `sheet_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'sheet表名,空表示循环读取(多sheet循环读取)',
  `model_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '导入模板名称,便于识别',
  `ind` int(3) NULL DEFAULT NULL COMMENT '显示顺序号',
  `service_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '导入实现类名称',
  `fixed_col` int(1) NULL DEFAULT 1 COMMENT '是否固定列(1表示系统预置列字段对应关系,0表示由用户选择列对应关系)',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '批量导入配置信息表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

Excel表字段信息(与表信息为一对多关系)[pub_imp_excel_modelcol]

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for pub_imp_excel_modelcol
-- ----------------------------
DROP TABLE IF EXISTS `pub_imp_excel_modelcol`;
CREATE TABLE `pub_imp_excel_modelcol`  (
  `id` bigint(13) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `model_id` bigint(13) NULL DEFAULT NULL COMMENT '菜单设置ID,与pub_imp_excel_model相关联',
  `col_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '列字段编码(数据库字段)',
  `excel_column` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'Excel列名(临时表字段名),不指定列名,',
  `state` int(3) NULL DEFAULT 1 COMMENT '状态,1表示有效,9表示无效',
  `validate_zz` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '数据验证正则表达式(),由valid数学表达式组合生成。复合涉及公式部分由AviatorEvaluator解析,参照导出ExcelWriteUtil.convertDataToRow表达式。',
  `validate_tip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '1' COMMENT '数据验证不通过提示信息。',
  `is_req` int(1) NOT NULL DEFAULT 0 COMMENT '是否必填项。1表示必填,0表示非必填。必填项为空或为null,则提示此项为必填项。',
  `ind` int(10) NULL DEFAULT NULL COMMENT '显示顺序号',
  `col_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '正式库字段名',
  `field_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '字段类型及长度(用于创建临时表),如varchar(100)',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 36 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '批量导入数据字段对应配置信息表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

保存校验不通过的字段信息日志[pub_imp_excel_valid_log]

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for pub_imp_excel_valid_log
-- ----------------------------
DROP TABLE IF EXISTS `pub_imp_excel_valid_log`;
CREATE TABLE `pub_imp_excel_valid_log`  (
  `id` bigint(18) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `col_id` bigint(18) NULL DEFAULT NULL COMMENT '列ID',
  `valid_tip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '校验提示语',
  `jdlog_id` bigint(18) NULL DEFAULT NULL COMMENT '导入ID,与pub_imp_excel_jd_log相关联',
  `row_id` bigint(13) NULL DEFAULT NULL COMMENT '行序号',
  `sheet_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'sheet名称',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 15436 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '批量导入数据校验日志信息表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

校验规则表[pub_imp_excel_valid_rule]

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for pub_imp_excel_valid_rule
-- ----------------------------
DROP TABLE IF EXISTS `pub_imp_excel_valid_rule`;
CREATE TABLE `pub_imp_excel_valid_rule`  (
  `id` bigint(18) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `state` int(1) NULL DEFAULT NULL COMMENT '状态,1表示有效,9表示无效',
  `valid_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '校验正则表达式',
  `valid_tip` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '校验提示信息',
  `valid_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '校验规则代码',
  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '校验规则名称(便于识别作用)',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '批量导入数据校验规则信息表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

3、需要配置表实例

[pub_imp_excel_model]表配置实例

在这里插入图片描述

[pub_imp_excel_modelcol]表配置实例

在这里插入图片描述

[pub_imp_excel_valid_rule]表配置实例

在这里插入图片描述

4、使用mybatis-plus生成表对应的java代码

在PubImpExcelModelMapper.xml编写的动态sql如下,负责创建临时表,保存数据到临时表

<update id="createTable">
        create table ${tableName}
        (
        id int(11) comment '用于存储excel的rowindex',
        valid_res int default 1 null comment 'int(1)类型,1表示校验通过,2表示校验不通过',
        valid_tip varchar(3000) null comment '校验提示信息',
        <foreach collection="list" index="index" item="item" separator="," close="">
            ${item.excelColumn} ${item.fieldType} null comment '动态生成字段'
        </foreach>

        );
    </update>
    <insert id="saveData">
        insert into ${tableName} values

        <foreach collection="list" index="index" item="items" separator="," open="" close="">
            <!--        (1,'test', -->
            <foreach collection="items" index="i" item="item" separator="," open="(" close=")">
                <choose>
                    <when test="item=='null'">
                        NULL
                    </when>
                    <otherwise>
                        '${item}'
                    </otherwise>
                </choose>
            </foreach>
        </foreach>
    </insert>

对应的mapper层写两个接口方法


    void createTable(String tableName, List<PubImpExcelModelcol> list);

    Integer saveData(String tableName,List<List<String>> list);

PubImpExcelValidRuleMapper.xml的动态sql如下。查询库里的校验规则

<select id="getRuleByIds" resultType="java.util.Map">
        SELECT
        *
        FROM
        pub_imp_excel_valid_rule
        WHERE
        valid_code IN
        <foreach collection="list" index="i" item="item" separator="," open="(" close=")">
            #{
    
    item}
        </foreach>
        and state =1
    </select>

mapper对应的方法

List<Map<String, Object>> getRuleByIds(List<String> ids);

5、使用到的工具类

ReadExcelUtil

主要ReadExcelUtil负责校验查验excel字段数据

package com.xjt.excel.util;



import com.googlecode.aviator.AviatorEvaluator;
import com.xjt.excel.entity.PubImpExcelModelcol;
import com.xjt.excel.entity.PubImpExcelValidLog;
import com.xjt.excel.service.impl.PubImpExcelValidLogServiceImpl;
import com.xjt.excel.service.impl.PubImpExcelValidRuleServiceImpl;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author liuchj
 * @version 1.0
 */
public class ReadExcelUtil {
    
    

    //总行数
    private static int totalRows = 0;
    //总条数
    private static int totalCells = 0;
    //错误信息接收器
    private static String errorMsg;
    //构造方法
    public ReadExcelUtil(){
    
    }




    public static PubImpExcelValidLogServiceImpl pubImpExcelValidLogService;


    public static PubImpExcelValidRuleServiceImpl pubImpExcelValidRuleService;

    public static void  setPubImpExcelValidLogServiceImpl(PubImpExcelValidLogServiceImpl pubImpExcelValidLogServices){
    
    
        pubImpExcelValidLogService = pubImpExcelValidLogServices;
    }

    public static void  setPubImpExcelValidRuleServiceImpl(PubImpExcelValidRuleServiceImpl pubImpExcelValidRuleServices){
    
    
        pubImpExcelValidRuleService = pubImpExcelValidRuleServices;
    }
    //获取总行数
    public int getTotalRows()  {
    
     return totalRows;}
    //获取总列数
    public int getTotalCells() {
    
      return totalCells;}
    //获取错误信息
    public String getErrorInfo() {
    
     return errorMsg; }
    /**
     * 读EXCEL文件,获取信息集合
     * @return
     */
    public static Map<String,Object> getExcelInfo(String mFile, List<PubImpExcelModelcol> ModelcolList,Long pubImpExcelJdLogId,Map<Integer,String> res,int sheetIndex) throws Exception {
    
    
        String fileName = new File(mFile).getName();//获取文件名
        if (!validateExcel(fileName)) {
    
    // 验证文件名是否合格
            return null;
        }
        boolean isExcel2003 = true;// 根据文件名判断文件是2003版本还是2007版本
        if (isExcel2007(fileName)) {
    
    
            isExcel2003 = false;
        }
        return createExcel(new FileInputStream(mFile), isExcel2003,ModelcolList,pubImpExcelJdLogId,res,sheetIndex);
    }


    /**
     * 根据excel里面的内容读取客户信息
     * @param is 输入流
     * @param isExcel2003 excel是2003还是2007版本
     * @return
     * @throws IOException
     */
    public static Map<String,Object> createExcel(InputStream is, boolean isExcel2003,List<PubImpExcelModelcol> ModelcolList,Long pubImpExcelJdLogId,Map<Integer,String> res,int sheetIndex) throws Exception {
    
    
        Workbook wb = null;
        if (isExcel2003) {
    
    // 当excel是2003时,创建excel2003
            wb = new HSSFWorkbook(is);
        } else {
    
    // 当excel是2007时,创建excel2007
            wb = new XSSFWorkbook(is);
        }
        return readExcelValue(wb,ModelcolList,pubImpExcelJdLogId,res,sheetIndex);
    }
//    public static Map<Integer,String> readExcelhead(String filePath) throws IOException {
    
    

    /**
     * 读取表头信息
     * @param file
     * @return
     * @throws Exception
     */
    public static Map<Integer,String> readExcelhead(MultipartFile file,int sheetIndex) throws Exception {
    
    

//        FileInputStream in = new FileInputStream(new File(filePath));
        FileInputStream in = (FileInputStream) file.getInputStream();
        Workbook wb = null;
//        if (isExcel2003(filePath)){
    
    
//        String name = file.getName();

        if (isExcel2003(file.getOriginalFilename())){
    
    
            wb = new HSSFWorkbook(in);
        }else {
    
    
            wb = new XSSFWorkbook(in);
        }
        Map<Integer, String> map = new HashMap<>();
        Sheet sheet = wb.getSheetAt(0);
        int headCol=0;
        if (sheet.getRow(headCol) != null && sheet.getPhysicalNumberOfRows()>1){
    
    
            while (isMergedRegion(sheet, headCol, 0)){
    
    
                headCol++;
            }
        }
        int colSum = sheet.getRow(headCol).getPhysicalNumberOfCells();
        for (int i = 0; i < colSum; i++) {
    
    
            Cell cell = sheet.getRow(headCol).getCell(i);
            if (null != cell) {
    
    
                cell.setCellType(CellType.STRING);
                String stringCellValue = cell.getStringCellValue();
                map.put(i, stringCellValue);
            }
        }
        return map;
    }


    /**
     * 读取Excel里面数据的信息
     * @param wb
     * @return
     */
    private static Map<String,Object> readExcelValue(Workbook wb,List<PubImpExcelModelcol> ModelcolList,Long pubImpExcelJdLogId,Map<Integer,String> res,int sheetIndex) throws Exception {
    
    
        Map<String,Object> map = new HashMap<>();
        // 得到第一个shell
        Sheet sheet = wb.getSheetAt(sheetIndex);
        String sheetName = sheet.getSheetName();
        //存储表头所在行的下一行
        int headCol=0;
        if (sheet.getRow(headCol) != null && sheet.getPhysicalNumberOfRows()>1){
    
    
            while (isMergedRegion(sheet, headCol, 0)){
    
    
                headCol++;
            }
        }
        // 得到Excel的行数
        totalRows = sheet.getPhysicalNumberOfRows();
        // 得到Excel的列数(前提是有行数)
        if (totalRows > 1 && sheet.getRow(0) != null) {
    
    
            totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
            if (totalCells==1){
    
    
                totalCells = sheet.getRow(1).getPhysicalNumberOfCells();
            }
        }
        List<PubImpExcelValidLog> impExcelValidLogList = new ArrayList<>();
//        Map<Integer,List<String>> map = new HashMap<Integer,List<String>>();
        List<List<String>> lists = new ArrayList<List<String>>();
        // 循环Excel行数,从headCol开始遍历数据
        int fail = 0;
        for (int r = headCol+1; r < totalRows; r++) {
    
    
            Row row = sheet.getRow(r);
            if (row == null){
    
    
                continue;
            }
            // 循环Excel的列
            List<String> list = new ArrayList<>();

            int validRes = 1;
            String validTip = "";
            list.add((r+1)+"");   //行号
            list.add(validRes+"");
            list.add(validTip);
            for (int c = 0; c < totalCells; c++) {
    
    
//                if (c==0 && row.getCell(c)==null){
    
    
//                    System.out.println("跳出当前循环体");
//                    break;
//                }
                String validateZz = ModelcolList.get(c).getValidateZz();            //数据校验正则表达式
//                String validateTip = ModelcolList.get(c).getValidateTip();//数据校验提示信息
                Cell cell = row.getCell(c);
                Integer isReq = ModelcolList.get(c).getIsReq();
                if (isReq==1 && (cell==null || getCellValue(cell).equals(""))){
    
    
                    if (validTip.equals("")){
    
    
                        validTip = "("+c+")"+res.get(c)+":该单元格为必填项";
                    }else {
    
    
                        validTip = validTip+"。"+"("+c+")"+res.get(c)+":该单元格为必填项";
                    }
                    validRes = 2;
                }
                if (null != cell) {
    
    
                    CellType cellType = cell.getCellType();
                    if (isMergedRegion(sheet, r, c)){
    
    
                        String mergedRegionValue = getMergedRegionValue(sheet, r, c);
                        list.add(mergedRegionValue);
                    }else {
    
    
                        if (cell.getCellType() != CellType.STRING && org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell))
                        {
    
    
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

                            Date date = DateUtil.getJavaDate(cell.getNumericCellValue());
                            String value = sdf.format(date);
                            List<String> ids = StrUtil.subString(validateZz, "[", "]");
                            List<Map<String, Object>> ruleByIds = pubImpExcelValidRuleService.getRuleByIds(ids);
//                            boolean matches = Pattern.matches(validateZz, value);
                            for (int i = 0; i < ruleByIds.size(); i++) {
    
    
                                String valid_expression = ruleByIds.get(i).get("valid_expression").toString();
                                boolean matchess = value.matches(valid_expression);
                                if (!matchess){
    
    
                                    if (validTip.equals("")){
    
    
                                        validTip = "("+c+")"+res.get(c)+":" +ruleByIds.get(i).get("valid_tip").toString();
                                    }else {
    
    
                                        validTip = validTip+"。"+"("+c+")"+res.get(c)+":"+ruleByIds.get(i).get("valid_tip").toString();
                                    }
//                                    validTip =validTip+ ruleByIds.get(i).get("valid_tip").toString();
                                }
                                String bool = String.valueOf(matchess);
                                String regex =  "["+ruleByIds.get(i).get("valid_code").toString()+"]";
                                validateZz = validateZz.replace(regex, bool);
                            }
//                            boolean matches = Pattern.matches(validateZz, stringCellValue);
                            boolean matches2 = (boolean) AviatorEvaluator.execute(validateZz);
                            if (validRes == 1){
    
    
                                validRes = matches2?1:2;
                            }
                            list.add(value);

                            if (!matches2){
    
    
                                Long R = (long) r;
                                Long C = (long) c;
                                impExcelValidLogList.add(new PubImpExcelValidLog(C, validTip, pubImpExcelJdLogId, R, sheetName));
                            }
                        }else {
    
    
//                            if(cell.getCellType()  == CellType.NUMERIC){
    
    
                            String stringCellValue = getCellValue(cell);
//                            validateZz.replaceAll()
                            List<String> ids = StrUtil.subString(validateZz, "[", "]");
                            List<Map<String, Object>> ruleByIds = pubImpExcelValidRuleService.getRuleByIds(ids);
//                            AviatorEvaluator.execute()
                            for (int i = 0; i < ruleByIds.size(); i++) {
    
    
                                String valid_expression = ruleByIds.get(i).get("valid_expression").toString();
                                boolean matches = stringCellValue.matches(valid_expression);
                                if (!matches){
    
    
                                    if (validTip.equals("")){
    
    
                                        validTip = "("+c+")"+res.get(c)+":" +ruleByIds.get(i).get("valid_tip").toString();
                                    }else {
    
    
                                        validTip = validTip+"。"+"("+c+")"+res.get(c)+":"+ruleByIds.get(i).get("valid_tip").toString();
                                    }
//                                    validTip =validTip+ ruleByIds.get(i).get("valid_tip").toString();
                                }
                                String bool = String.valueOf(matches);
                                String regex =  "["+ruleByIds.get(i).get("valid_code").toString()+"]";
                                validateZz = validateZz.replace(regex, bool);
                            }
//                            boolean matches = Pattern.matches(validateZz, stringCellValue);
                            boolean matches = (boolean) AviatorEvaluator.execute(validateZz);
                            if (validRes == 1){
    
    
                                validRes = matches?1:2;
                            }
//                            validTip = matches?validTip+","+validateTip:validTip;
//                            if (!matches){
    
    
//                                if (validTip.equals("")){
    
    
//                                    validTip = validateTip;
//                                }else {
    
    
//                                    validTip = validTip+","+validateTip;
//                                }
//                                validTip = validTip;
//                            }
                            if (stringCellValue.equals("now()")){
    
    
                                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                list.add(LocalDateTime.now().format(df));
                            }else {
    
    
                                list.add(stringCellValue);
                            }

                            if (!matches){
    
    
                                Long R = (long) r;
                                Long C = (long) c;
                                impExcelValidLogList.add(new PubImpExcelValidLog(C, validTip, pubImpExcelJdLogId, R, sheetName));
                            }
//                            }
                        }
                    }


//                        if (stringCellValue.contains("\n") || stringCellValue.contains("\t") || stringCellValue.contains(" "))
//                        {
    
    
//                            throw  new RuntimeException("单元格不能包含特殊字符,包括空格换行");
//                        }
                }else {
    
    
                    list.add("null");
                }
            }
            String rowString = "";
            for (int i = 0; i < list.size(); i++) {
    
    
                rowString+=list.get(i);
            }
            boolean flag = !rowString.equals("");
            String valid = String.valueOf(validRes);
            list.set(1, valid);
            if (valid.equals("1")){
    
    
                list.set(2, "通过");
            }else {
    
    
                list.set(2, validTip);
            }
            if (list.size()>3 && flag){
    
    
                lists.add(list);
            }
            if (validRes == 2){
    
    
                fail++;
            }
        }
        if (impExcelValidLogList.size()>1){
    
    
            pubImpExcelValidLogService.saveBatch(impExcelValidLogList);
        }
        map.put("list", lists);
        map.put("fail", fail);
        return map;
    }
    /**
     * 验证EXCEL文件
     *
     * @param filePath
     * @return
     */
    public static boolean validateExcel(String filePath) {
    
    
        if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))) {
    
    
            errorMsg = "文件名不是excel格式";
            return false;
        }
        return true;
    }
    // @描述:是否是2003的excel,返回true是2003
    public static boolean isExcel2003(String filePath)  {
    
    
        return filePath.matches("^.+\\.(?i)(xls)$");
    }
    //@描述:是否是2007的excel,返回true是2007
    public static boolean isExcel2007(String filePath)  {
    
    
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }

    /**
     * 获取合并单元格的值
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    public static String getMergedRegionValue(Sheet sheet ,int row , int column){
    
    
        int sheetMergeCount = sheet.getNumMergedRegions();

        for(int i = 0 ; i < sheetMergeCount ; i++){
    
    
            CellRangeAddress ca = sheet.getMergedRegion(i);
            int firstColumn = ca.getFirstColumn();
            int lastColumn = ca.getLastColumn();
            int firstRow = ca.getFirstRow();
            int lastRow = ca.getLastRow();

            if(row >= firstRow && row <= lastRow){
    
    

                if(column >= firstColumn && column <= lastColumn){
    
    
                    Row fRow = sheet.getRow(firstRow);
                    Cell fCell = fRow.getCell(firstColumn);

                    return getCellValue(fCell) ;
                }
            }
        }

        return null ;
    }

    /**
     * 判断指定的单元格是否是合并单元格
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    public static boolean isMergedRegion(Sheet sheet , int row , int column){
    
    
        int sheetMergeCount = sheet.getNumMergedRegions();

        for(int i = 0 ; i < sheetMergeCount ; i++ ){
    
    
            CellRangeAddress ca = sheet.getMergedRegion(i);
            int firstColumn = ca.getFirstColumn();
            int lastColumn = ca.getLastColumn();
            int firstRow = ca.getFirstRow();
            int lastRow = ca.getLastRow();

            if(row >= firstRow && row <= lastRow){
    
    
                if(column >= firstColumn && column <= lastColumn){
    
    

                    return true ;
                }
            }
        }

        return false ;
    }

    /**
     * 获取单元格的值
     * @param cell
     * @return
     */
    public static String getCellValue(Cell cell){
    
    

        if(cell == null) return "";

        if(cell.getCellType() == CellType.STRING){
    
    

            return cell.getStringCellValue();

        }else if(cell.getCellType() == CellType.BOOLEAN){
    
    

            return String.valueOf(cell.getBooleanCellValue());

        }else if(cell.getCellType() == CellType.FORMULA){
    
    

            return cell.getCellFormula() ;

        }else if(cell.getCellType() == CellType.NUMERIC){
    
    

//            return cell.getStringCellValue();
            return String.valueOf(cell.getNumericCellValue());

        }

        return "";
    }
}

MD5File

package com.xjt.excel.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5File {
    
    
	private final static char[] hexDigits = {
    
    
		'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
	};
	 protected static MessageDigest messagedigest = null;  
	    static {
    
      
	        try {
    
      
	            messagedigest = MessageDigest.getInstance("MD5");  
	        } catch (NoSuchAlgorithmException e) {
    
      
	            e.printStackTrace();  
	        }  
	    }
	public static String byteArrayToHexString(byte[] b)
	{
    
    
		StringBuffer resultSb = new StringBuffer();
		for (int i=0;i<b.length;i++)
		{
    
    
			resultSb.append(byteToHexString(b[i]));
		}
		return resultSb.toString();
	}

	private static Object byteToHexString(byte b) 
	{
    
    
		int n=b;
		if (n<0)
			n = 256 + n;
		int d1 = n/16;
		int d2 = n%16;
		
		return hexDigits[d1] + hexDigits[d2];
	}
	
	public static String compile(String origin)
	{
    
    
		String resultString = null;
		
		MessageDigest md;
		try 
		{
    
    
			resultString = origin;
			md = MessageDigest.getInstance("MD5");
			resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
		} 
		catch (NoSuchAlgorithmException e) 
		{
    
    
			e.printStackTrace();
		}
		return resultString;
	}
	
	 public static String getFileMD5String(File file) throws IOException {
    
      
	        InputStream fis;  
	        fis = new FileInputStream(file);  
	        byte[] buffer = new byte[1024];  
	        int numRead = 0;  
	        while ((numRead = fis.read(buffer)) > 0) {
    
      
	            messagedigest.update(buffer, 0, numRead);  
	        }  
	        fis.close();  
	        return bufferToHex(messagedigest.digest());  
	    } 
	 public static String getFileMD5String(String filePath,String fileName) throws IOException {
    
      
	        InputStream fis;  
	        fis = new FileInputStream(new File(filePath, fileName));  
	        byte[] buffer = new byte[1024];  
	        int numRead = 0;  
	        while ((numRead = fis.read(buffer)) > 0) {
    
      
	            messagedigest.update(buffer, 0, numRead);  
	        }  
	        fis.close();  
	        return bufferToHex(messagedigest.digest());  
	    }
	 
	 private static String bufferToHex(byte[] bytes) {
    
    
	        return bufferToHex(bytes, 0, bytes.length);  
	    }  
	  
	    private static String bufferToHex(byte[] bytes, int m, int n) {
    
    
	        StringBuffer stringbuffer = new StringBuffer(2 * n);  
	        int k = m + n;  
	        for (int l = m; l < k; l++) {
    
      
	            appendHexPair(bytes[l], stringbuffer);  
	        }  
	        return stringbuffer.toString();  
	    }  
	  
	    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
    
      
	        char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换  
	        // 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同  
	        char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换  
	        stringbuffer.append(c0);  
	        stringbuffer.append(c1);  
	    }  
	    public static void main(String[] args) throws IOException {
    
      
	        /*File file = new File("E:/test/crm_account_YYYY_MM_DD.txt");  
	        String md5 = getFileMD5String(file);  
	        System.out.println("md5:" + md5);  */
	    	System.out.println("1f*111".matches("^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[#@!~%^&*])[A-Za-z\\d#@!~%^&*]{6,20}$"));
	    }
}

FileUtil

package com.xjt.excel.util;
/*
import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncodingAttributes;
import it.sauronsoftware.jave.MultimediaInfo;
import it.sauronsoftware.jave.MyFFMPEGLocator;
import it.sauronsoftware.jave.VideoAttributes;*/

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.charset.StandardCharsets;
import java.util.*;
/*
import com.gaf.web.servlet.SystemConfig;
import com.gaf.web.util.DateUtil;
import com.gaf.wqsm.pub.action.SafeUtil;
import com.jxxc.util.docToJPG.JOD4DocToPDF;*/

/*******************************************************************************
 * 文件操作类
 * 
 * @author Administrator
 * 
 */
public class FileUtil {
    
    

	private static final Logger log = LoggerFactory.getLogger(FileUtil.class);


	public static File multipartFileToFile(MultipartFile file) throws Exception {
    
    

		File toFile = null;
		if (file.equals("") || file.getSize() <= 0) {
    
    
			file = null;
		} else {
    
    
			InputStream ins = null;
			ins = file.getInputStream();
			toFile = new File(file.getOriginalFilename());
			inputStreamToFile(ins, toFile);
			ins.close();
		}
		return toFile;
	}
	private static void inputStreamToFile(InputStream ins, File file) {
    
    
		try {
    
    
			OutputStream os = new FileOutputStream(file);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
    
    
				os.write(buffer, 0, bytesRead);
			}
			os.close();
			ins.close();
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}


	/**
	 * 向文件中追加内容
	 * 
	 * @param content
	 *            文件内容
	 * @param filePath
	 *            文件路径
	 * @param append
	 *            是否追加内容,true表示追加内容,false为否,不追加内容
	 */
	public static void writeFile(String content, String filePath, boolean append)
			throws Exception {
    
    
		// FileOutputStream out = null;
		RandomAccessFile out = null;
		FileLock flout = null;
		FileChannel fcout = null;
		try {
    
    
			if (content.length() <= 0) {
    
    
				if (!append) {
    
    
					File fil = new File(filePath);
					fil.delete();
					fil.createNewFile();
				}
				return;
			}
			File file = new File(filePath);
			file.mkdirs();
			if (!(file.exists())) {
    
    
				file.createNewFile();
			} else {
    
    
				if (!append) {
    
    // 追加内容,则
					file.delete();
					file.createNewFile();
				}
			}
			// 对该文件加锁
			out = new RandomAccessFile(file, "rw");
			fcout = out.getChannel();
			// 设置超时时长
			int timeOut = 60;
			Boolean getLock = false;
			while (timeOut > 0) {
    
    
				try {
    
    
					timeOut = timeOut - 1;
					flout = fcout.tryLock();
					getLock = true;
					break;
				} catch (Exception e) {
    
    
					log.error("有其他线程正在操作该文件,等待1秒!");
					Thread.sleep(1000);
				}
			}
			// out = new FileOutputStream(file, append);
			byte[] b = content.getBytes(StandardCharsets.UTF_8);
			if (getLock) {
    
    
				out.seek(out.length());// 向文件结尾追加内容
				out.write(b);
			}
			if (flout != null) {
    
    
				flout.release();
			}
			fcout.close();
			out.close();
			out = null;
		} catch (Exception e) {
    
    
			// TODO: handle exception
			e.printStackTrace();
			if (flout != null) {
    
    
				flout.release();
			}
			if (fcout != null) {
    
    
				fcout.close();
			}
			if (out != null) {
    
    
				out.close();
			}

		}
	}


	/**
	 * 向文件中追加内容
	 * 
	 * @param content
	 *            文件内容
	 * @param filePath
	 *            文件路径
	 * @param append
	 *            是否追加内容,true表示追加内容,false为否,不追加内容
	 */
	public static void writeFile(String content, String filePath,
			boolean append, int timeOut) throws Exception {
    
    
		// FileOutputStream out = null;
		RandomAccessFile out = null;
		FileLock flout = null;
		FileChannel fcout = null;
		String rootPath = null;//SystemConfig.getParamPath("fileUtilPath");
		try {
    
    
			File file = new File(rootPath, filePath);
			File pFile = file.getParentFile();
			pFile.mkdirs();
			if (!(file.exists())) {
    
    
				file.createNewFile();
			} else {
    
    
				if (!append) {
    
    // 追加内容,则
					file.delete();
					file.createNewFile();
				}
			}
			if (content.trim().length() <= 0) {
    
    
				return;
			}
			// 对该文件加锁
			out = new RandomAccessFile(file, "rw");
			fcout = out.getChannel();
			// 设置超时时长
			timeOut = (timeOut == 0 ? 1 : timeOut);
			Boolean getLock = false;
			while (timeOut > 0) {
    
    
				try {
    
    
					timeOut = timeOut - 1;
					flout = fcout.tryLock();
					getLock = true;
					break;
				} catch (Exception e) {
    
    
					log.error("有其他线程正在操作该文件,等待1秒!");
					Thread.sleep(1000);
				}
			}
			// out = new FileOutputStream(file, append);
			// byte[] b = content.getBytes("UTF-8");
			if (getLock) {
    
    
				out.seek(out.length());// 向文件结尾追加内容
				out.writeUTF(new String(content.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
			}
			if (flout != null) {
    
    
				flout.release();
			}
			fcout.close();
			out.close();
			out = null;
		} catch (Exception e) {
    
    
			// TODO: handle exception
			e.printStackTrace();
			if (flout != null) {
    
    
				flout.release();
			}
			if (fcout != null) {
    
    
				fcout.close();
			}
			if (out != null) {
    
    
				out.close();
			}

		}
	}


	/**
	 * 拷贝文件到指定目录
	 * 
	 * @param srcPath
	 *            源文件路径
	 * @param destPath
	 *            目标文件路径
	 * @return true:拷贝成功 false:拷贝失败
	 */
	public static boolean copyFile(String srcPath, String destPath)
			throws Exception {
    
    
		FileInputStream is = null;
		FileOutputStream os = null;
		try {
    
    
			File dest = new File(destPath);
			dest.mkdirs();
			dest.delete();
			File fl = new File(srcPath);
			int length = (int) fl.length();
			is = new FileInputStream(srcPath);
			os = new FileOutputStream(destPath);
			byte[] b = new byte[length];
			is.read(b);
			os.write(b);
			is.close();
			os.close();
			return true;
		} catch (Exception e) {
    
    
			if (null != is) {
    
    
				is.close();
			}
			if (null != os) {
    
    
				os.close();
			}
			return false;
		}
	}

	
	/**
	 * 将一个大文件切割成若干个小文件的
	 * 
	 * @param curfile
	 *            文本文件路径
	 * @return 返回文件内容
	 */
	public static void curFile(String curfile) {
    
    
		File f = new File(curfile);
		try {
    
    
			if (!f.exists())
				throw new Exception();
			FileReader cf = new FileReader(curfile);
			BufferedReader is = new BufferedReader(cf);
			StringBuffer filecontent = new StringBuffer();
			int i=0;
			int j=0;
			String str = is.readLine();
			while (str != null) {
    
    
				i++;
				filecontent.append(str);
				str = is.readLine();
				if (str != null)
					filecontent.append("\n");
				if(i%1000==0){
    
    
					filecontent.append("commit;\n");
				}
				if(i>100000){
    
    
					j++;
					String dfPath=f.getAbsolutePath().replace(".", "")+"/"+j+f.getName();				
					filecontent.append("commit;\n");
					writeFile(filecontent.toString().replace("`tb_family_members`", "tb_family_members"), dfPath, false);
					i=0;
					filecontent=null;
					filecontent=new StringBuffer();
					
				}
			}
			
			if(i>0 && i<=100000){
    
    
				j++;
				String dfPath=f.getAbsolutePath().replace(".", "")+"/"+j+f.getName();				
				filecontent.append("commit;\n");
				writeFile(filecontent.toString().replace("`tb_family_members`", "tb_family_members"), dfPath, false);
				filecontent=null;				
			}
			
			is.close();
			cf.close();
			return;
		} catch (Exception e) {
    
    
			System.err.println("不能读属性文件: " + curfile + " \n" + e.getMessage());
			return;
		}
	}
	

}

FileUtils

package com.xjt.excel.util;

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.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;


public class FileUtils {
    
    
	private final static String excel2003L = ".xls"; // 2003- 版本的excel
	private final static String excel2007U = ".xlsx"; // 2007+ 版本的excel
	
	
	/**
	 * 从数据列表中读取数据,并将数据读入列表中
	 * 
	 * @return
	 */
	


	/**
	 * 描述:根据文件后缀,自适应上传文件的版本
	 * 
	 * @param inStr
	 *            ,fileName
	 * @return
	 * @throws Exception
	 */
	public Workbook getWorkbook(InputStream inStr, String fileName)
			throws Exception {
    
    
		Workbook wb = null;
		String fileType = fileName.substring(fileName.lastIndexOf("."));
		System.out.println(fileType);

		if (excel2003L.equals(fileType)) {
    
    
			System.out.println("2003");
			wb = new HSSFWorkbook(inStr); // 2003-
		} else if (excel2007U.equals(fileType) || ".xlsm".equals(fileType)) {
    
    
			System.out.println("2007");
			wb = new XSSFWorkbook(inStr); // 2007+
		} else {
    
    
			throw new Exception("解析的文件格式有误!");
		}
		return wb;
	}

	public Map JXEXCEL(InputStream inModel, String fileNamemModel,
			String tableName, String QDICTTYPE, int mergeLine) throws Exception {
    
    
		System.out.println(mergeLine);
		System.out.println("临时表名为"+tableName);
		String pcId = getUUID();
		System.out.println(pcId);
		// List<String> listTop = new ArrayList<String>();
		List<HashMap> listTop = new ArrayList<HashMap>();
		List<HashMap> listUnder = new ArrayList<HashMap>();
		Map map = new HashMap<String, String>();
		Workbook workModel = this.getWorkbook(inModel, fileNamemModel); // 创建模板工作空间
		if (null == workModel) {
    
    
			throw new Exception("创建Excel工作薄为空!");
		}
		Sheet sheet = null;
		sheet = workModel.getSheetAt(0); // 读取第一个页签
		Map<String, String> mapUnder; // 里面每一条数据组装成一个map
		Map<String, String> topMap;
		Map<String, String> MergedRegionsMap;
	
		int count = 1;
		int topCount = 1;
		String resultSql;
		
		int lastRowLine=0;
		int firstRowLine=0;
		int rowNum=0;

		int rangeNum=0;
		

		MergedRegionsMap=getMergedRegionValue(sheet);
		

		   int sheetMergeCount = sheet.getNumMergedRegions();   
		   
		  if(sheetMergeCount>0){
    
    
			  lastRowLine=15365782; //标识
	       for (int i =0; i < sheetMergeCount; i++) {
    
       
	             CellRangeAddress range = sheet.getMergedRegion(i);   
	            /* int firstColumn = range.getFirstColumn(); 
	             int lastColumn = range.getLastColumn();   
	             int firstRow = range.getFirstRow();   */
	             int lastRow = range.getLastRow();  
	             int firstRow = range.getFirstRow();
	             if(rangeNum==0&&firstRow<=mergeLine){
    
    
	            lastRowLine=lastRow;
	            firstRowLine=firstRow;
	            rangeNum++;
	             }
	             if(lastRow>lastRowLine&&firstRow<=mergeLine){
    
    
	            	 lastRowLine=lastRow;
	            	 firstRowLine=firstRow;
	            	 
	             }
	             
	                 } 
		  }
	       
	       
	       
		System.out.println("lastRowLine="+lastRowLine);
		System.out.println("firstRow="+firstRowLine);
		

		
	
		
		if(sheetMergeCount>0&&lastRowLine!=15365782){
    
     //说明有合并单元格 并且 是起始行为5以下的格子
			
			rowNum=lastRowLine+1;
		}
	
		
		
		
		System.out.println("一共"+sheet.getLastRowNum());
		Row row=null;
		int topAllNum = 0; // 表头大小
	//	for (Row row : sheet) {
    
    
			for (; rowNum <= sheet.getLastRowNum(); rowNum++) {
    
    
				 row = sheet.getRow(rowNum);
				 
				 
				 
					// 如果当前行没有数据,跳出循环
				 if(row==null){
    
    
					 
					 continue; 
				 }
				 
					if (!judgeRowIsNull(row, row.getLastCellNum())) {
    
    
						System.out.println(rowNum+"行为空");
						continue;
					}
			
	
			if (count == 1) {
    
     // 读取页签
            System.out.println("表头在"+rowNum);
				for (Cell cell3 : row) {
    
    

					if (getCellValue(cell3).toString().length() != 0) {
    
    
						topMap = new HashMap<String, String>();

						topMap.put("topIndex", "A" + topCount);
						topMap.put("topTip", (String) getCellValue(cell3));
						// topMap.put("topTip","1");
						topCount++;
						listTop.add((HashMap) topMap);
					}
				}
				topAllNum = listTop.size(); // 记录表头的列数
				count++;
				continue;
			}
			
			
			if (!judgeRowIsNull(row,topAllNum)) {
    
    
				System.out.println(rowNum+"行为空");
				continue;
			}

		
           System.out.println("第"+rowNum);
			
			
			//MergedRegionsMap
			int count11 = 1;
			String excelValue=""; 
			String keyName=""; //rowNum
			mapUnder = new HashMap<String, String>();

			resultSql = "insert into " + tableName + "  SELECT "; // 先做占位符
			for (int i = 1; i <= topAllNum; i++) {
    
    
				
				if(!MergedRegionsMap.isEmpty()){
    
    
					keyName=rowNum+"-"+(i-1);
					
					if(MergedRegionsMap.containsKey(keyName)){
    
    
						excelValue=MergedRegionsMap.get(keyName);
						MergedRegionsMap.remove(keyName);
					}
					else{
    
    
						excelValue=(String) getCellValue(row.getCell(i - 1));
					}
				}else{
    
    
				
					excelValue=(String) getCellValue(row.getCell(i - 1));
				}
				
				

				if (count11 != topAllNum) {
    
    
					resultSql = resultSql + "'"
							+ excelValue + "',";
				} else {
    
    

					resultSql = resultSql + "'"
							+ excelValue
							+ "' from dual";
				}

				mapUnder.put("QSQL", resultSql);
				mapUnder.put("QDICTTYPE", QDICTTYPE); // 类别ID
				mapUnder.put("QPCID", pcId);
				count11++;

			}

			listUnder.add((HashMap) mapUnder);
		}

		System.out.println("表头长度=" + listTop.size());
		inModel.close();
		map.put("topFlag", listTop);
		map.put("Under", listUnder);
		map.put("num", listTop.size());
		map.put("pcId", pcId);

		return map;
	}

	/**
	 * 描述:对表格中数值进行格式化
	 * 
	 * @param cell
	 * @return
	 */
	public static Object getCellValue(Cell cell) {
    
    
		Object value = null;
		DecimalFormat df = new DecimalFormat("0"); // 格式化number String字符
		SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd"); // 日期格式化
		DecimalFormat df2 = new DecimalFormat("0.00"); // 格式化数字
		if (cell != null) {
    
    
			switch (cell.getCellType()) {
    
    
				case STRING:
				value = cell.getStringCellValue().toString()
						.replaceAll("'", "").replace("\"", "").trim();
				

				break;

				case _NONE:
					break;
				case NUMERIC:

				if (HSSFDateUtil.isCellDateFormatted(cell)
						||cell.getCellStyle().getDataFormat()==28||cell.getCellStyle().getDataFormat()==31) {
    
    
					System.out.println("是日期类型");
					value = sdf.format(cell.getDateCellValue());

				} 
				
				
				
				else {
    
    
					try{
    
    
					value = df.format(cell.getNumericCellValue())+"";
				}catch(Exception e){
    
    
					
					value="";
				}
				
				}
				
				break;

				case BOOLEAN:
				value = cell.getBooleanCellValue();

				break;

				case FORMULA:
					break;
				case BLANK:
				value = "";

				break;

				case ERROR:
					break;
				default:  //只剩下表达式类型和未知类型
			//	value = "";
				
				
				try{
    
    
				value=cell.getStringCellValue().toString().replaceAll("'", "").replace("\"", "").trim();
				
				
				}
				catch(Exception e){
    
    
				
					try{
    
    
					value=df.format(cell.getNumericCellValue());
					}catch(Exception ee){
    
    
						value=""; //未知类型数据
						
					}
				}
				System.out.println("进来了3" );
				break;
			}

			return value;
		} else {
    
    

			return "";

		}
	}

	public static String diG(String str) {
    
    
		if (str.endsWith("0")) {
    
    
			str = str.substring(0, str.length() - 2);
			System.out.println("截取后" + str);
			return diG(str);
		} else {
    
    
			return str;
		}

	}

	// 生成32位的随机数
	public static String getUUID() {
    
    
		UUID uuid = UUID.randomUUID();

		return uuid.toString().replace("-", "");

	}

	public boolean judgeRowIsNull(Row row, int num) {
    
    

	
		boolean flag = false;
		if(row!=null){
    
    
		for (int i = 0; i <= num - 1; i++) {
    
    

			if (getCellValue(row.getCell(i)).toString().trim().length() != 0) {
    
    
				flag = true;
			
				//getCellValue(row.getCell(i))
				
				break;

			}

		}
		}

		return flag;

	}
	
	
	
	
	
	
	
	/**
     * 获取合并单元格的值
     * 
     * @param sheet
     * @return
     */
    public static Map<String, String> getMergedRegionValue(Sheet sheet) {
    
    
    	System.out.println("进来了");
        int sheetMergeCount = sheet.getNumMergedRegions();
        String tmp="";
        String key="";
        Map<String, String> map = new HashMap<String, String>(); //用于存放合并值
        for (int i = 0; i < sheetMergeCount; i++) {
    
    
            CellRangeAddress ca = sheet.getMergedRegion(i);
            int firstColumn = ca.getFirstColumn();
            int lastColumn = ca.getLastColumn();
            int firstRow = ca.getFirstRow();
            int lastRow = ca.getLastRow();
            System.out.println(firstRow+" "+lastRow+" ");
            System.out.println(firstColumn+" "+lastColumn+" ");
      
 
         
            Row fRow = sheet.getRow(firstRow);
            
            if(fRow!=null){
    
    
            
            Cell fCell = fRow.getCell(firstColumn);
           
            tmp=(String) getCellValue(fCell);
          
            
            
            for(int ii=firstRow;ii<=lastRow;ii++){
    
    
            	
            	for(int j=firstColumn;j<=lastColumn;j++){
    
    
                	
            		key=ii+"-"+j;
            		
            		map.put(key,tmp);

                }
            	
            	
            	
            	
            }
        }
            
        }
        return map;
    }

}

DateUtil

/*     */ package com.xjt.excel.util;
/*     */ 
/*     */

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/*     */
/*     */ public class DateUtil extends DateUtils
/*     */ {
    
    
/*     */   public static boolean isDateBefore(Date standDate, Date trueDate)
/*     */   {
    
    
/*  13 */     return trueDate.before(standDate);
/*     */   }
/*     */ 
/*     */   public static boolean isDateBefore(String standDate, String trueDate)
/*     */     throws Exception
/*     */   {
    
    
/*  19 */     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/*  20 */     return sdf.parse(standDate).before(sdf.parse(trueDate));
/*     */   }
/*     */ 
/*     */   public static String getYear()
/*     */   {
    
    
/*  25 */     Calendar cld = Calendar.getInstance();
/*  26 */     return String.valueOf(cld.get(1));
/*     */   }
/*     */ 
/*     */   public static String getMonth()
/*     */   {
    
    
/*  31 */     Calendar cld = Calendar.getInstance();
/*  32 */     return String.valueOf(cld.get(2) + 1);
/*     */   }
/*     */ 
/*     */   public static String getDay()
/*     */   {
    
    
/*  37 */     Calendar cld = Calendar.getInstance();
/*  38 */     return String.valueOf(cld.get(5));
/*     */   }
/*     */ 
/*     */   public static String getWeek()
/*     */   {
    
    
/*  43 */     Calendar cld = Calendar.getInstance();
/*  44 */     return String.valueOf(cld.get(7));
/*     */   }
/*     */ 
/*     */   public static String getNow() {
    
    
/*  48 */     return getYear() + "-" + getMonth() + "-" + getDay();
/*     */   }
/*     */ 
/*     */   //public static Date getToday()
/*     */   //{
    
    
/*  53 */     //return truncate(new Date(), 5);
/*     */   //}
/*     */ 
/*     */   public static Date getTodayEnd()
/*     */   {
    
    
/*  58 */     return getDayEnd(new Date());
/*     */   }
/*     */ 
/*     */   public static int getTomorrowWeekDay()
/*     */   {
    
    
/*  63 */     Calendar cal = Calendar.getInstance();
/*  64 */     cal.set(1, cal.get(1));
/*  65 */     cal.set(2, cal.get(2));
/*  66 */     cal.set(5, cal.get(5) + 1);
/*  67 */     return cal.get(7);
/*     */   }
/*     */ 
/*     */   public static boolean checkDateString(String dateString)
/*     */   {
    
    
/*  73 */     if (dateString.length() != 10)
/*  74 */       return false;
/*     */     try
/*     */     {
    
    
/*  77 */       return (string2Date(dateString, "yyyy-MM-dd") != null); } catch (Exception localException) {
    
    
/*     */     }
/*  79 */     return false;
/*     */   }
/*     */ 
/*     */   public static boolean checkDateTimeString(String dateTimeString)
/*     */   {
    
    
/*  85 */     if (dateTimeString.length() != 19)
/*  86 */       return false;
/*     */     try
/*     */     {
    
    
/*  89 */       return (string2Date(dateTimeString, "yyyy-MM-dd HH:mm:ss") != null); } catch (Exception localException) {
    
    
/*     */     }
/*  91 */     return false;
/*     */   }
/*     */ 
/*     */   public static boolean checkTimeString(String timeString)
/*     */   {
    
    
/*  97 */     if (timeString.length() != 8)
/*  98 */       return false;
/*     */     try
/*     */     {
    
    
/* 101 */       return (string2Date(timeString, "HH:mm:ss") != null); } catch (Exception localException) {
    
    
/*     */     }
/* 103 */     return false;
/*     */   }
/*     */ 
/*     */   public static Date getMonthEnd(int year, int month)
/*     */     throws Exception
/*     */   {
    
    
/*     */     Date date;
/* 110 */     StringBuffer sb = new StringBuffer(10);
/*     */ 
/* 112 */     if (month < 12) {
    
    
/* 113 */       sb.append(year);
/* 114 */       sb.append("-");
/* 115 */       sb.append(month + 1);
/* 116 */       sb.append("-1");
/* 117 */       date = string2Date(sb.toString(), "yyyy-MM-dd");
/*     */     } else {
    
    
/* 119 */       sb.append((year + 1));
/* 120 */       sb.append("-1-1");
/* 121 */       date = string2Date(sb.toString(), "yyyy-MM-dd");
/*     */     }
/* 123 */     date.setTime(date.getTime() - 3885736610104344577L);
/* 124 */     return date;
/*     */   }
/*     */ 
/*     */   public static Date getMonthEnd(Date when)
/*     */     throws Exception
/*     */   {
    
    
/* 130 */     Assert.notNull(when, "date must not be null !");
/* 131 */     Calendar calendar = Calendar.getInstance();
/* 132 */     calendar.setTime(when);
/* 133 */     int year = calendar.get(1);
/* 134 */     int month = calendar.get(2) + 1;
/* 135 */     return getMonthEnd(year, month);
/*     */   }
/*     */ 
/*     */   public static Date getDayEnd(Date when)
/*     */   {
    
    
/* 140 */     //Date date = truncate(when, 5);
/* 141 */     //date = addDays(date, 1);
/* 142 */     //date.setTime(date.getTime() - 3885736610104344577L);
/* 143 */     return null;//date;
/*     */   }
/*     */ 
/*     */   public static Date getDay(Date when)
/*     */   {
    
    
/* 148 */     //Date date = truncate(when, 5);
/* 149 */     //date = addDays(date, -1);
/* 150 */     //date.setTime(date.getTime() + 3885736610104344577L);
/* 151 */     return null;//date;
/*     */   }
/*     */ 
/*     */   public static Date add(Date when, int field, int amount)
/*     */   {
    
    
/* 156 */     Calendar calendar = Calendar.getInstance();
/* 157 */     calendar.setTime(when);
/* 158 */     calendar.add(field, amount);             
/* 159 */     return calendar.getTime();
/*     */   }
/*     */ 
/*     */   public static Date addDays(Date when, int amount)
/*     */   {
    
    
/* 164 */     return add(when, 6, amount);
/*     */   }
/*     */ 
/*     */   public static Date addMonths(Date when, int amount)
/*     */   {
    
    
/* 169 */     return add(when, 2, amount);
/*     */   }
/*     */ 
/*     */   public static String getFileNameByDate()
/*     */   {
    
    
/* 174 */     return new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date());
/*     */   }
/*     */ 
/*     */   public static long getDateMarginDay(Date beginDate, Date endDate)
/*     */   {
    
    
/* 179 */     return ((endDate.getTime() - beginDate.getTime()) / 86400000L);
/*     */   }
/*     */ 
/*     */   public static long getDateMarginMinute(Date beginDate, Date endDate)
/*     */   {
    
    
/* 184 */     return ((endDate.getTime() - beginDate.getTime()) / 60000L);
/*     */   }
/*     */ 
/*     */   public static long getDateMarginMillisecond(Date beginDate, Date endDate)
/*     */   {
    
    
/* 189 */     return (endDate.getTime() - beginDate.getTime());
/*     */   }
/*     */ 
/*     */   public static String getDateMarginString(Date beginDate, Date endDate)
/*     */   {
    
    
/* 194 */     if (beginDate.after(endDate)) {
    
    
/* 195 */       return "";
/*     */     }
/*     */ 
/* 198 */     String message = "";
/* 199 */     long ss = endDate.getTime() - beginDate.getTime();
/* 200 */     long datenum = 3885739376063283200L;
/* 201 */     long hournum = 3885739376063283200L;
/* 202 */     long minnum = 3885739376063283200L;
/* 203 */     long ssnum = 3885739376063283200L;
/* 204 */     datenum = ss / 86400000L;
/* 205 */     ss -= datenum * 1000L * 60L * 60L * 24L;
/* 206 */     hournum = ss / 3600000L;
/* 207 */     ss -= hournum * 1000L * 60L * 60L;
/* 208 */     minnum = ss / 60000L;
/* 209 */     ss -= minnum * 1000L * 60L;
/* 210 */     ssnum = ss / 1000L;
/* 211 */     if (datenum != 3885739994538573824L) message = message + datenum + "天";
/* 212 */     if (hournum != 3885739994538573824L) message = message + hournum + "小时";
/* 213 */     if (minnum != 3885739994538573824L) message = message + minnum + "分";
/* 214 */     if (ssnum != 3885739994538573824L) message = message + ssnum + "秒";
/* 215 */     return message;
/*     */   }
/*     */ 
/*     */   public static boolean isWithinDate(Date startDate, Date endDate)
/*     */   {
    
    
/* 220 */     if (getDateMarginMillisecond(startDate, new Date()) >= 3885739994538573824L)
/*     */     {
    
    
/* 222 */       return (getDateMarginMillisecond(endDate, new Date()) >= 3885736249327091712L);
/*     */     }
/*     */ 
/* 225 */     return false;
/*     */   }
/*     */ 
/*     */   public static String getCurrentDateTimeStr(String aMask)
/*     */   {
    
    
/* 230 */     SimpleDateFormat df = new SimpleDateFormat(aMask);
/* 231 */     Calendar cal = Calendar.getInstance(TimeZone.getDefault());
/* 232 */     return df.format(cal.getTime());
/*     */   }
/*     */ 
/*     */   public static Date getCurrentDateTime()
/*     */   {
    
    
/* 237 */     Calendar cal = Calendar.getInstance(TimeZone.getDefault());
/* 238 */     return cal.getTime();
/*     */   }
/*     */ 
/*     */   public static String getForwardHourOfTheDateTime(String strDate, String aMask)
/*     */     throws Exception
/*     */   {
    
    
/* 244 */     if ((strDate == null) || ("".equals(strDate))) {
    
    
/* 245 */       throw new Exception("传入的日期为空!");
/*     */     }
/* 247 */     if (strDate.length() < 13) {
    
    
/* 248 */       throw new Exception("传入的日期格式不正确!");
/*     */     }
/* 250 */     String year = strDate.substring(0, 4);
/* 251 */     String month = strDate.substring(5, 7);
/* 252 */     String day = strDate.substring(8, 10);
/* 253 */     String hour = strDate.substring(11, 13);
/*     */ 
/* 255 */     SimpleDateFormat df = new SimpleDateFormat(aMask);
/*     */ 
/* 257 */     Calendar cal = Calendar.getInstance();
/* 258 */     cal.set(1, Integer.parseInt(year));
/* 259 */     cal.set(2, Integer.parseInt(month) - 1);
/* 260 */     cal.set(5, Integer.parseInt(day));
/* 261 */     cal.set(11, Integer.parseInt(hour) - 1);
/* 262 */     return df.format(cal.getTime());
/*     */   }
/*     */ 
/*     */   public static String getForwardDayOfTheDateTime(String strDate, String aMask)
/*     */     throws Exception
/*     */   {
    
    
/* 268 */     if ((strDate == null) || ("".equals(strDate))) {
    
    
/* 269 */       throw new Exception("传入的日期为空!");
/*     */     }
/* 271 */     if (strDate.length() < 10) {
    
    
/* 272 */       throw new Exception("传入的日期格式不正确!");
/*     */     }
/* 274 */     String year = strDate.substring(0, 4);
/* 275 */     String month = strDate.substring(5, 7);
/* 276 */     String day = strDate.substring(8, 10);
/*     */ 
/* 278 */     SimpleDateFormat df = new SimpleDateFormat(aMask);
/*     */ 
/* 280 */     Calendar cal = Calendar.getInstance();
/* 281 */     cal.set(1, Integer.parseInt(year));
/* 282 */     cal.set(2, Integer.parseInt(month) - 1);
/* 283 */     cal.set(5, Integer.parseInt(day) - 1);
/* 284 */     return df.format(cal.getTime());
/*     */   }
/*     */ 
/*     */   public static String getForwardMonthOfTheDateTime(String strDate, String aMask)
/*     */     throws Exception
/*     */   {
    
    
/* 290 */     if ((strDate == null) || ("".equals(strDate))) {
    
    
/* 291 */       throw new Exception("传入的日期为空!");
/*     */     }
/* 293 */     if (strDate.length() < 10) {
    
    
/* 294 */       throw new Exception("传入的日期格式不正确!");
/*     */     }
/* 296 */     String year = strDate.substring(0, 4);
/* 297 */     String month = strDate.substring(5, 7);
/* 298 */     String day = strDate.substring(8, 10);
/*     */ 
/* 300 */     SimpleDateFormat df = new SimpleDateFormat(aMask);
/*     */ 
/* 302 */     Calendar cal = Calendar.getInstance();
/* 303 */     cal.set(1, Integer.parseInt(year));
/* 304 */     cal.set(2, Integer.parseInt(month) - 2);
/* 305 */     cal.set(5, Integer.parseInt(day));
/* 306 */     return df.format(cal.getTime());
/*     */   }
/*     */ 
/*     */   public static String getForwardYearOfTheDateTime(String strDate, String aMask)
/*     */     throws Exception
/*     */   {
    
    
/* 312 */     if ((strDate == null) || ("".equals(strDate))) {
    
    
/* 313 */       throw new Exception("传入的日期为空!");
/*     */     }
/* 315 */     if (strDate.length() < 10) {
    
    
/* 316 */       throw new Exception("传入的日期格式不正确!");
/*     */     }
/* 318 */     String year = strDate.substring(0, 4);
/* 319 */     String month = strDate.substring(5, 7);
/* 320 */     String day = strDate.substring(8, 10);
/*     */ 
/* 322 */     SimpleDateFormat df = new SimpleDateFormat(aMask);
/*     */ 
/* 324 */     Calendar cal = Calendar.getInstance();
/* 325 */     cal.set(1, Integer.parseInt(year) - 1);
/* 326 */     cal.set(2, Integer.parseInt(month) - 1);
/* 327 */     cal.set(5, Integer.parseInt(day));
/* 328 */     return df.format(cal.getTime());
/*     */   }
/*     */ 
/*     */   public static String date2String(Date aDate, String aMask)
/*     */     throws Exception
/*     */   {
    
    
/* 334 */     SimpleDateFormat df = null;
/* 335 */     String returnValue = "";
/* 336 */     if (aDate == null)
/* 337 */       throw new Exception("传入的日期为空!");
/* 338 */     df = new SimpleDateFormat(aMask);
/* 339 */     returnValue = df.format(aDate);
/* 340 */     return returnValue;
/*     */   }
/*     */ 
/*     */   public static Date string2Date(String strDate, String aMask)
/*     */     throws Exception
/*     */   {
    
    
/* 346 */     SimpleDateFormat df = null;
/* 347 */     Date date = null;
/* 348 */     df = new SimpleDateFormat(aMask);
/*     */     try
/*     */     {
    
    
/* 351 */       date = df.parse(strDate);
/*     */     } catch (Exception pe) {
    
    
/* 353 */       throw new Exception("转换日期格式失败!");
/*     */     }
/* 355 */     return date;
/*     */   }
/*     */ 
/*     */   public static String formatDate(String strDate, String oldMask, String newMask)
/*     */     throws Exception
/*     */   {
    
    
/* 361 */     Date dateTime = string2Date(strDate, oldMask);
/* 362 */     return date2String(dateTime, newMask);
/*     */   }
/*     */ }

StrUtil

package com.xjt.excel.util;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

public class StrUtil {
    
    
    public static List<String> split(String str, String dimli){
    
    
        List<String> res=new ArrayList<>();
        for (String s:str.split(dimli)){
    
    
            res.add(s);
        }
        return  res;
    }

    public static Boolean isNotEmpty(String str){
    
    
        return (str!=null && !"".equals(str) && !"null".equals(str.toLowerCase()));
    }

    public static String clearNull(Object str){
    
    
        if(isNotEmpty(String.valueOf(str))){
    
    
           return String.valueOf(str);
        }else{
    
    
            return "";
        }
    }

    public static Integer toInteger(Object str){
    
    
        String s=clearNull(str);
        if("".equalsIgnoreCase(s)){
    
    
            return 0;
        }
        if(!isNum(s)){
    
    
            return 0;
        }
        return Integer.valueOf(s);
    }

    public static Double toDouble(Object str){
    
    
        String s=clearNull(str);
        if("".equalsIgnoreCase(s)){
    
    
            return 0.00;
        }
        if(!isDouble(s)){
    
    
            return 0.00;
        }
        return Double.valueOf(s);
    }

    public static Long toLong(Object str){
    
    
        String s=clearNull(str);
        if("".equalsIgnoreCase(s)){
    
    
            return Long.valueOf(0);
        }
        if(!isNum(s)){
    
    
            return Long.valueOf(0);
        }
        return Long.valueOf(s);
    }

    // 判断是否为正整数
    public static boolean isNum(String value) {
    
    
        if (isNotEmpty(value)) {
    
    
            Pattern pattern = Pattern.compile("[0-9]*");
            return pattern.matcher(value).matches();
        } else {
    
    
            return false;
        }
    }

    // 判断字符串是否都是数字
    public static boolean isDouble(String value) {
    
    
        if (isNotEmpty(value)) {
    
    
            Pattern pattern = Pattern.compile("[0-9]+(.[0-9]+)?");
            return pattern.matcher(value).matches();
        } else {
    
    
            return false;
        }
    }

    /**
     * 截取字符串str中指定字符 strStart、strEnd之间的多个字符串数组
     *
     * @return      字符串数组
     */
    public static List<String> subString(String str, String strStart, String strEnd) {
    
    

        List<String> res = new LinkedList<>();
        /* 找出指定的2个字符在 该字符串里面的 位置 */
        while (str.contains("]")){
    
    
            int strStartIndex = str.indexOf(strStart);
            int strEndIndex = str.indexOf(strEnd);

            /* index 为负数 即表示该字符串中 没有该字符 */
            if (strStartIndex < 0) {
    
    
                return null;
            }
            if (strEndIndex < 0) {
    
    
                return null;
            }
            /* 开始截取 */
            String substring = str.substring(strStartIndex, strEndIndex).substring(strStart.length());
            res.add(substring);
            str = str.substring(strEndIndex+1);
        }
        return res;
    }

}

SpringContextUtil

package com.xjt.excel.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

/**
 * 全局变量
 * @author 赵亚辉
 *
 */
@Configuration
public class SpringContextUtil implements ApplicationContextAware {
    
    

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
        SpringContextUtil.applicationContext = applicationContext;
    }

    public static ApplicationContext getCtx() {
    
    
        return SpringContextUtil.applicationContext;
    }

    public static <T> T getBean(Class<T> t) {
    
    
        return SpringContextUtil.applicationContext.getBean(t);
    }

    public static Object getBean(String beanName) {
    
    
        return SpringContextUtil.applicationContext.getBean(beanName);
    }


}

BaseControllerUtil

package com.xjt.excel.util;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.PrintWriter;
import java.util.*;

public class BaseControllerUtil implements Controller {
    
    


    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    
        return null;
    }


    public static void renderResult(HttpServletResponse response, Object obj){
    
    
        PrintWriter out = null;
        try {
    
    
            String jsonArray = JSONObject.toJSONString(obj);
            response.setContentType(
                    "text/html;charset=utf-8");
            out = response.getWriter();
            out.println(jsonArray);
            out.flush();
            out.close();
            return;
        } catch (Exception e) {
    
    
            // TODO: handle exception
            e.printStackTrace();
            if (out != null) {
    
    
                out.flush();
                out.close();
            }
        }
    }
}

6、接口与实现代码

首先我们需要一个连接数据库的mapper
对用的mapper接口

Integer SavaData(String savetableName,String tableName, List excelColumnList, List colCodeList);

将临时表内的数据导入到正式库

    <insert id="SavaData">
        insert into ${savetableName}
        <foreach collection="colCodeList" item="item" index="index" open="(" separator="," close=")">
            ${item}
        </foreach>
        select
        <foreach collection="excelColumnList" item="items" index="index" open="" separator="," close="">
            ${items}
        </foreach>
        from
        ${tableName}
        where valid_res = 1
    </insert>

需要实现的接口

package com.xjt.excel.service;

import java.util.List;

/**
 * @author xu
 * @Description
 * @createTime 2021年05月13日 13:39:00
 */
public interface IImpExcelService {
    
    
    Integer importExcelToDb(String tableName, List excelColumnList,List colCodeList);
}

实现类

实现类我们只需要实现接口,并重写一个方法。
方法内调用以上写的mapper接口

@Service
public class UserServiceImpl implements  IImpExcelService {
    
    
	//需要注入之前写的mapper层对象调用SaveData方法连接数据库
    @Override
    public Integer importExcelToDb(String tableName, List excelColumnList, List colCodeList) {
    
    
        return SavaData("user",tableName, excelColumnList, colCodeList);
        //第一个('user')参数为需要导入正式库的表名
    }
}

8、上传excel到数据库接口

   @RequestMapping(value = "/huint/uploads",method = RequestMethod.POST)
    @ResponseBody
    public void importExcel(@RequestParam("file") MultipartFile file, Long menuId, HttpServletResponse response) {
    
    
        Map<String, Object> message = new HashMap<>();
        if (file.isEmpty()){
    
    
            message.put("code", 400);
            message.put("msg", "文件为空");
            BaseControllerUtil.renderResult(response, message);
            return;
        }
        long startData = System.currentTimeMillis();
// 判断文件是否为空
        LocalDateTime startTime = LocalDateTime.now();
        String path = importExcelFile;
        ReadExcelUtil.setPubImpExcelValidLogServiceImpl(pubImpExcelValidLogService);
        ReadExcelUtil.setPubImpExcelValidRuleServiceImpl(pubImpExcelValidRuleService);
        String originalFilename = file.getOriginalFilename();
        String fileMD5String;
        try {
    
    
            fileMD5String = MD5File.getFileMD5String(FileUtil.multipartFileToFile(file));
            QueryWrapper<PubImpExcelJdLog> qw = new QueryWrapper<>();
            qw.eq("state", 1);
            qw.eq("jd_state", "从临时表插入数据到正式表完成");
            qw.eq("md5code", fileMD5String);
            PubImpExcelJdLog one = pubImpExcelJdLogService.getOne(qw);
            if (one!=null){
    
    
                message.put("code", 408);
                message.put("msg", "当前表已存在");
                BaseControllerUtil.renderResult(response, message);
                return;
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
            message.put("code", 416);
            message.put("msg", "表数据异常");
            BaseControllerUtil.renderResult(response, message);
            return;
        }
        if (!ReadExcelUtil.validateExcel(originalFilename)){
    
                //判断是不是excel文件
            message.put("code", 403);
            message.put("msg", "不是excel文件");
            BaseControllerUtil.renderResult(response, message);
            return;
        }
        assert originalFilename != null;
        String[] split = originalFilename.split("\\.");
        String suffix = split[split.length-1];          //获取上传文件的后缀
        try {
    
    
            // 文件保存路径
            String filePath = path + "/" + UUID.randomUUID().toString().replace("-", "")+"."+suffix;
            QueryWrapper<PubImpExcelModel> qmodel = new QueryWrapper<>();
            qmodel.eq("menu_id", menuId);
            qmodel.eq("state", 1);
            List<PubImpExcelModel> excelModels = pubImpExcelModelService.list(qmodel);//模板表信息
            if (excelModels == null && excelModels.size()<1) {
    
    
                message.put("code", 501);
                message.put("msg", "未配置导出模板");
                BaseControllerUtil.renderResult(response, message);
                return;
            }
            for (int i = 0; i < excelModels.size(); i++) {
    
    
                QueryWrapper<PubImpExcelModelcol> modelcol = new QueryWrapper<>();
                modelcol.eq("state", 1);
                modelcol.eq("model_id", excelModels.get(i).getId());
                List<PubImpExcelModelcol> ModelcolList = pubImpExcelModelcolService.list(modelcol);     //字段列信息

                Map<Integer, String> res = ReadExcelUtil.readExcelhead(file,i);           //表头信息

                PubImpExcelJdLog pubImpExcelJdLog = new PubImpExcelJdLog();
                pubImpExcelJdLog.setState(1);
                pubImpExcelJdLog.setMenuId(menuId);
                pubImpExcelJdLog.setPcNum(FileUtils.getUUID());
                pubImpExcelJdLog.setJdState("上传中");
                pubImpExcelJdLog.setStartTime(startTime);
                pubImpExcelJdLog.setOperUid(0L);
                pubImpExcelJdLog.setSourceFileName(originalFilename);
                pubImpExcelJdLog.setSouceFilePath(filePath);
                pubImpExcelJdLog.setMd5code(fileMD5String);
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);             //记录保存日志信息
                Long pubImpExcelJdLogId = pubImpExcelJdLog.getId();
                String tableName = "i"+excelModels.get(i).getId()+"_"+pubImpExcelJdLogId;         //临时表明

                pubImpExcelJdLog.setJdState("创建临时表");
                pubImpExcelJdLog.setTmpTableName(tableName);
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);

                pubImpExcelModelService.createTable(tableName, ModelcolList);  //创建临时表

                if (!new File(filePath).exists()){
    
              //保存目录如果不存在,则递归创建目录
                    new File(filePath).mkdirs();
                }
                //将接受的文件保存
                if (i==0){
    
    
                    file.transferTo(new File(filePath));            //将接受的文件保存
                }
                pubImpExcelJdLog.setJdState("上传成功");
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);

                message.put("filePath", filePath);
                pubImpExcelJdLog.setJdState("开始解析");
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);
                Map<String, Object> excelInfos;
                try {
    
    
                    excelInfos = ReadExcelUtil.getExcelInfo(filePath, ModelcolList, pubImpExcelJdLogId,res,i);//获取的excel数据
                } catch (FileNotFoundException e){
    
    
                    e.printStackTrace();
                    message.put("code", 506);
                    message.put("msg", "找不到文件");
                    BaseControllerUtil.renderResult(response, message);
                    return;
                }catch (Exception e){
    
    
                    e.printStackTrace();
                    message.put("code", 504);
                    message.put("msg", "数据解析异常,excel数据不匹配");
                    BaseControllerUtil.renderResult(response, message);
                    return;
                }
                assert excelInfos != null;
                List<List<String>> excelInfo = (List<List<String>>) excelInfos.get("list");
                List<String> excelColumnList = new ArrayList<>();
                List<String> colCodeList = new ArrayList<>();
                for (PubImpExcelModelcol pubImpExcelModelcol : ModelcolList) {
    
    
                    String excelColumn = pubImpExcelModelcol.getExcelColumn();
                    String colCode = pubImpExcelModelcol.getColCode();
                    excelColumnList.add(excelColumn);
                    colCodeList.add(colCode);
                }
                assert excelInfo != null;
                pubImpExcelJdLog.setJdState("开始插入数据到临时表");
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);
                try {
    
    
                    pubImpExcelModelService.saveData(tableName, excelInfo);
                }catch (UncategorizedSQLException e){
    
    
                    e.getSQLException();
                    message.put("code", 302);
                    message.put("msg", "必填项不能为空");
                    BaseControllerUtil.renderResult(response, message);
                    return;
                }
                pubImpExcelJdLog.setJdState("插入数据到临时表完成");
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);
//                System.out.println(excelInfo);
//            System.out.println(integer);
                String serviceName = excelModels.get(i).getServiceName();
                pubImpExcelJdLog.setJdState("开始从临时表插入数据到正式表");
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);

                IImpExcelService IImpExcelService = (IImpExcelService) SpringContextUtil.getBean(serviceName);
                Integer count = IImpExcelService.importExcelToDb(tableName, excelColumnList, colCodeList);
                pubImpExcelJdLog.setEndTime(LocalDateTime.now());
                pubImpExcelJdLog.setProblemnum(Integer.valueOf(excelInfos.get("fail").toString()));
                pubImpExcelJdLog.setJdState("从临时表插入数据到正式表完成");
                pubImpExcelJdLog.setTotalRow(count);
                pubImpExcelJdLogService.saveOrUpdate(pubImpExcelJdLog);         //保存日志
                long endData = System.currentTimeMillis();
                long expendTime = (endData - startData) / 1000;
                message.put("expendTime",expendTime/60+"m"+expendTime%60+"s");
                message.put("temTableName",tableName);
                message.put("status", "success");
                message.put("code", 200);
                message.put("successImportCount", count);
                BaseControllerUtil.renderResult(response, message);
            }

        } catch (Exception e) {
    
    
//                e.printStackTrace();
            message.put("status", "error");
        }
    }

9、接口测试

测试excel

在这里插入图片描述

model表配置

在这里插入图片描述

model_col表配置

在这里插入图片描述

Rule表配置

在这里插入图片描述

postman请求接口测试

成功!

返回类型

code:状态码
successImportCount:成功导入数
filePath:上传的文件保存的位置
temTableName:生成的临时表名
expendTime:导入耗时
status:状态
在这里插入图片描述

生成的临时表如下

在这里插入图片描述

查看正式库,数据已经导入

在这里插入图片描述

日志表记录数据如下

在这里插入图片描述

当你测试结果如以上所示。恭喜你,你已经集成动态导入。

前往gitee码云参考demo

demo

未避免麻烦,我们只需要在前端管理配置表,更方便。

文章较长,如有疑问或有什么建议欢迎评论交流!!希望对你有所帮助❤️❤️❤️❤️❤️

猜你喜欢

转载自blog.csdn.net/languageStudent/article/details/116989687