【SpringBoot+Mybatis-plus+poi】实现校验导入excel(一)

【SpringBoot+Mybatis-plus+poi】实现校验导入excel(一)

实现校验导入excel,我打算用两章实现:
第一章根据工厂模式(三个工厂:导入工厂、校验工厂和实现类导入方法工厂)和简单的非空校验实现user.xlsx的导入校验;
第二章根据工厂模式和自定义注解实现user.xlsx的导入校验。
首先看一下excel文档:
在这里插入图片描述
这里我删掉了部分单元格数据,作为非空校验的导入模板;
校验成功则根据id查询数据库的数据,如果结果为空则新增,否则更新
校验失败则给对应单元格标红,并在最后一列打印错误信息
上代码:

1. 实体(为Mybatis的Generator生成工具生成)

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
@TableName("t_user")
public class TUser {

    private Integer id;
    private String name;
    private String age;
    private String sex;
    private String address;
    private String contactInformation;
}

2. dao层(为Mybatis的Generator生成工具生成)

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.import1.domain.TUser;
import org.apache.ibatis.annotations.Mapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wp
 * @since 2022-01-04
 */
@Mapper
public interface TUserMapper extends BaseMapper<TUser> {

}

3. service层(为Mybatis的Generator生成工具生成)

3.1. api
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.import1.domain.TUser;

/**
 * <p>
 *  服务类
 * </p>
 *
 * @author wp
 * @since 2022-01-04
 */
public interface IUserService extends IService<TUser> {

}
3.1. impl(内部方法为实现类导入方法工厂的方法)
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wp
 * @since 2022-01-04
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements IUserService, ICombineService {

    @Autowired
    private TUserMapper userMapper;


    @Override
    @Transactional
    public XSSFWorkbook importExcel(InputStream inputStream) throws IOException {
        StringBuilder errorString = new StringBuilder();
        XSSFWorkbook wb = new XSSFWorkbook(inputStream);
        Sheet s = wb.getSheetAt(0);
        int allNums = s.getPhysicalNumberOfRows();
        IImport check = new UserImport(userMapper);
        //校验
        check.checkResult(errorString,wb,s,allNums,inputStream);

        //导入数据
        if (StringUtils.isBlank(errorString)){
            check.createData(s, allNums);
            wb =  null;
        }
        return wb;
    }
}

4. 实现类工厂生产实现类导入方法

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.InputStream;

/**
 * 禽流感环境病原学监测信息Service接口
 *
 * @author wp
 * @date 2021-12-17
 */
public interface ICombineService {

    /**
     * 通用导入
     */
    XSSFWorkbook importExcel(InputStream inputStream) throws IOException;
}

5. mapper层

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.import1.mapper.TUserMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.example.import1.domain.TUser">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="age" property="age" />
        <result column="sex" property="sex" />
        <result column="address" property="address" />
        <result column="contactInformation" property="contactInformation" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, name, age, sex, address, contactInformation
    </sql>

</mapper>

6. 导入工厂

import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.InputStream;

/**
 * 抽象导入
 * @author wp
 */
public interface IImport {

    /**
     * 校验
     * @param errorMsg
     * @param wb
     * @param s
     * @param allNums
     * @param inputStream
     * @throws IOException
     */
    void checkResult(StringBuilder errorMsg, XSSFWorkbook wb, Sheet s, int allNums, InputStream inputStream)throws IOException;

    /**
     * 导入数据
     * @param s
     * @param allNums
     */
    void createData(Sheet s, int allNums);

    /**
     * 导入数据处理
     * @param s
     * @param i
     */
    void create(Sheet s, int i);
}
6.1. 生产导入
import com.example.import1.dispose.ICheck;
import com.example.import1.dispose.IImport;
import com.example.import1.dispose.check.UserCheck;
import com.example.import1.domain.TUser;
import com.example.import1.mapper.TUserMapper;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * user导入
 * @author wp
 */
public class UserImport implements IImport {
    private final DataFormatter DATAFORMATTER = new DataFormatter();
    //excel起始校验行下标
    private static final int START_INDEX = 1;

    //excel错误信息下标
    private static final int ERROR_INDEX = 6;

    private final TUserMapper userMapper;

    public UserImport(TUserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    public void checkResult(StringBuilder errorMsg, XSSFWorkbook wb, Sheet s, int allNums, InputStream inputStream) throws IOException {
        //获取默认单元格样式(在第一行创建一个空单元格获取默认样式)
        XSSFCellStyle orgSty = (XSSFCellStyle) s.getRow(0).createCell(100).getCellStyle();
        //设置单元格为文本格式
        XSSFDataFormat format = wb.createDataFormat();
        orgSty.setDataFormat(format.getFormat("@"));
        //错误标红单元格样式
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        cellStyle.setDataFormat(format.getFormat("@"));
        // 重复数据缓存
        List<String> dataList = new ArrayList<>();
        ICheck<TUserMapper> check = new UserCheck();
        check.check(s, allNums, errorMsg, cellStyle, dataList, START_INDEX, ERROR_INDEX, DATAFORMATTER, userMapper);
    }

    @Override
    public void createData(Sheet s, int allNums) {
        for (int i = START_INDEX; i < allNums; i++) {
            Row r = s.getRow(i);
            if (r == null) {
                continue;
            }
            // 导入禽流感环境病原学监测信息
            create(s, i);
        }
    }

    @Transactional
    public void create(Sheet s, int i) {
        Row r = s.getRow(i);
        TUser user = new TUser();

        // id
        String id = DATAFORMATTER.formatCellValue(r.getCell(0));
        int idInt = Integer.parseInt(id);
        TUser userCondition = userMapper.selectById(id);
        user.setId(idInt);

        // 姓名
        String name = DATAFORMATTER.formatCellValue(r.getCell(1));
        user.setName(name);

        // 年龄
        String age = DATAFORMATTER.formatCellValue(r.getCell(2));
        user.setAge(age);

        // 性别
        String sex = DATAFORMATTER.formatCellValue(r.getCell(3));
        user.setSex(sex);

        // 地址
        String address = DATAFORMATTER.formatCellValue(r.getCell(4));
        user.setAddress(address);

        // 联系方式
        String contactInformation = DATAFORMATTER.formatCellValue(r.getCell(5));
        user.setContactInformation(contactInformation);

        if (null != userCondition) {
            userMapper.updateById(user);
        }else {
            userMapper.insert(user);
        }
    }
}

7. 校验工厂

import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;

import java.util.List;

/**
 * 抽象通用校验
 * @param <M> mapper泛型
 */
public interface ICheck<M> {

    /**
     * 通用校验
     * @param s
     * @param allNums
     * @param errorString
     * @param cellStyle
     * @param dataList
     */
    void check(Sheet s, int allNums, StringBuilder errorString, XSSFCellStyle cellStyle, List<String> dataList,
               int START_INDEX, int ERROR_INDEX, DataFormatter DATAFORMATTER, M m);
}
7.1. 生产校验方式
import com.example.import1.dispose.ICheck;
import com.example.import1.mapper.TUserMapper;
import com.example.import1.util.CheckoutUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;

import java.util.List;

/**
 * user校验
 */
public class UserCheck implements ICheck<TUserMapper> {
    @Override
    public void check(Sheet s, int allNums, StringBuilder errorString, XSSFCellStyle cellStyle, List<String> dataList,
                      int START_INDEX, int ERROR_INDEX, DataFormatter dataFormatter, TUserMapper userMapper) {
        for(int i = START_INDEX; i<allNums ;i++) {
            //定义错误信息msg
            StringBuilder errorMsg = new StringBuilder();
            Row r = s.getRow(i);

            if(r == null) {
                break;
            }
            //获取错误信息清空
            Cell orgErrCell = r.getCell(ERROR_INDEX);
            if(orgErrCell!=null) {
                orgErrCell.setCellValue("");
            }

            Cell idCell = r.getCell(0);
            String id = dataFormatter.formatCellValue(idCell);
            // 非空校验
            CheckoutUtils.isNull("id", errorMsg, idCell, id, cellStyle, r, 0);

            // 姓名
            Cell nameCell = r.getCell(1);
            String name = dataFormatter.formatCellValue(nameCell);
            // 非空校验
            CheckoutUtils.isNull("姓名", errorMsg, nameCell, name, cellStyle, r, 1);

            // 年龄
            Cell ageCell = r.getCell(2);
            String age = dataFormatter.formatCellValue(ageCell);
            // 非空校验
            CheckoutUtils.isNull("年龄", errorMsg, ageCell, age, cellStyle, r, 2);

            // 性别
            Cell sexCell = r.getCell(3);
            String sex = dataFormatter.formatCellValue(sexCell);
            // 非空校验
            CheckoutUtils.isNull("性别", errorMsg, sexCell, sex, cellStyle, r, 3);

            // 地址
            Cell addressCell = r.getCell(4);
            String address = dataFormatter.formatCellValue(addressCell);
            // 非空校验
            CheckoutUtils.isNull("地址", errorMsg, addressCell, address, cellStyle, r, 4);

            // 联系方式
            Cell contactInformationCell= r.getCell(5);
            String contactInformation = dataFormatter.formatCellValue(contactInformationCell);
            // 非空校验
            CheckoutUtils.isNull("联系方式", errorMsg, contactInformationCell, contactInformation, cellStyle, r, 5);

            if(orgErrCell==null) {
                orgErrCell= r.createCell(ERROR_INDEX);
            }
            orgErrCell.setCellValue(errorMsg.toString());
            errorString.append(errorMsg);
        }
    }
}

8. 工具类

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;

public class CheckoutUtils {
    /**
     * 非空校验
     * @param zhName
     * @param errorMsg
     * @param cell
     * @param cellStyle
     * @return
     */
    public static boolean isNull(String zhName, StringBuilder errorMsg, Cell cell, String cellString, XSSFCellStyle cellStyle, Row r, int i){
        //如果为空则增加错误信息
        if(StringUtils.isBlank(cellString)) {
            errorMsg.append(zhName).append("必填; ");
            setCellStyle(r, i, cell, cellStyle);
            return false;
        }
        CellStyle style = cell.getCellStyle();
        if (IndexedColors.RED.getIndex() == style.getFillBackgroundColor()) {
            cell.setCellStyle(null);
        }
        return true;
    }

    private static void setCellStyle(Row r, int i, Cell cell, XSSFCellStyle cellStyle) {
        if (null == cell) {
            cell = r.createCell(i);
        }
        cell.setCellStyle(cellStyle);
    }
}

9. pom路径

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>import1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>import1</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mybatis plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

10. controller层

import com.example.import1.domain.TUser;
import com.example.import1.service.ICombineService;
import com.example.import1.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wp
 * @since 2022-01-04
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private ICombineService combineService;

    /**
     * 用户查询
     * @return
     */
    @GetMapping("/query/user")
    public ResponseEntity<List<TUser>> queryUser(){
        return ResponseEntity.ok(userService.list());
    }

    /**
     * 用户导入
     */
    @PostMapping("/import/user")
    public ResponseEntity<Boolean> importExcel(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws IOException {
        XSSFWorkbook wb = combineService.importExcel(file.getInputStream());
        if (wb!=null){
            ServletOutputStream outputStream = response.getOutputStream();
            wb.write(outputStream);
            wb.close();
            outputStream.close();
        }
        return ResponseEntity.ok(true);
    }
}

11. Generator代码生成工具

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.ArrayList;
import java.util.List;

public class MpBatisGenerator {

    private static String projectPath = null;


    public static void main(String[] args) {
//        projectPath = System.getProperty("user.dir");
        projectPath = "D:\\本地项目\\import1";
        AutoGenerator autoGenerator = new AutoGenerator();
        autoGenerator.setGlobalConfig(configGlobalConfig());
        autoGenerator.setDataSource(configDataSource());
        autoGenerator.setStrategy(configStrategyConfig());
        autoGenerator.setPackageInfo(configPackageConfig());
//        autoGenerator.setCfg(customerConfig());
        autoGenerator.execute();
    }


    /**
     * 自定义生成文件配置
     *
     * @return
     */
//    private static InjectionConfig customerConfig() {
//        InjectionConfig config = new InjectionConfig() {
//            @Override
//            public void initMap() {
//
//            }
//        };
//        List<FileOutConfig> files = new ArrayList<FileOutConfig>();
//        files.add(new FileOutConfig() {
//            @Override
//            public String outputFile(TableInfo tableInfo) {
//                String expand = "c:/dam";
//                String entityFile = String.format((expand + File.separator + "%s" + ".java"), tableInfo.getControllerName());
//                return entityFile;
//            }
//        });
//        config.setFileOutConfigList(files);
//        return config;
//    }

    /**
     * 全局配置
     *
     * @return
     */
    private static GlobalConfig configGlobalConfig() {
        GlobalConfig config = new GlobalConfig();
        // 是否支持AR模式
        config.setActiveRecord(true)
                // 作者
                .setAuthor("wp")
                // 生成路径
                .setOutputDir(projectPath + "/src/test/java/")
//                .setOutputDir("c:/pms/src/main/java/")
                // 文件覆盖
                .setFileOverride(true)
                // 主键策略
                .setIdType(IdType.AUTO)
                // 设置生成的service接口的名字的首字母是否为I,例如IEmployeeService
                .setServiceName("%sService")
                //开启swagger2模式
                .setSwagger2(true)
                //生成基本的resultMap
                .setBaseResultMap(true)
                //生成基本的SQL片段
                .setBaseColumnList(true)
                //生成后打开文件夹
                .setOpen(false).setDateType(DateType.ONLY_DATE);
        return config;
    }

    /**
     * 数据源配置
     *
     * @return
     */
    private static DataSourceConfig configDataSource() {
        DataSourceConfig dsConfig = new DataSourceConfig();
        // 设置数据库类型
        dsConfig.setDbType(DbType.MYSQL)
                .setDriverName("com.mysql.cj.jdbc.Driver")
                .setUrl("jdbc:mysql://localhost:3306/demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8")
                .setUsername("root")
                .setPassword("root")
                .setTypeConvert(new MySqlTypeConvert() {
                    // 自定义数据库表字段类型转换【可选】
                    @Override
                    public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                        System.out.println("转换类型:" + fieldType);
                        if (fieldType.toLowerCase().contains("tinyint")) {
                            return DbColumnType.INTEGER;
                        }
                        return super.processTypeConvert(globalConfig, fieldType);
                    }
                });
        return dsConfig;
    }

    /**
     * 策略配置
     *
     * @return
     */
    private static StrategyConfig configStrategyConfig() {
        StrategyConfig stConfig = new StrategyConfig();

        List<TableFill> tableFillList = new ArrayList<TableFill>();
        //如 每张表都有一个创建时间、修改时间
        //而且这基本上就是通用的了,新增时,创建时间和修改时间同时修改
        //修改时,修改时间会修改,
        //虽然像Mysql数据库有自动更新几只,但像ORACLE的数据库就没有了,
        //使用公共字段填充功能,就可以实现,自动按场景更新了。
        //如下是配置
        /*TableFill sysCreateTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill sysUpdateTime = new TableFill("update_time", FieldFill.UPDATE);
        TableFill sysCreateBy = new TableFill("create_by", FieldFill.INSERT);
        TableFill sysUpdateBy = new TableFill("update_by", FieldFill.UPDATE);
        tableFillList.add(sysCreateTime);
        tableFillList.add(sysUpdateTime);
        tableFillList.add(sysCreateBy);
        tableFillList.add(sysUpdateBy);*/

        // 全局大写命名
        stConfig.setCapitalMode(true)
                // 指定表名 字段名是否使用下划线
                //.setDbColumnUnderline(true)
                // 数据库表映射到实体的命名策略
                .setNaming(NamingStrategy.underline_to_camel)
                //.setTablePrefix("tbl_")
                // 生成的表
                .setInclude(new String[]{
                        "t_user"
                })
                .setEntityBooleanColumnRemoveIsPrefix(false)
                // 自定义实体,公共字段
                .setTableFillList(tableFillList);
        return stConfig;
    }

    /**
     * 包名策略配置
     * @return
     */
    private static PackageConfig configPackageConfig() {
        PackageConfig pkConfig = new PackageConfig();
        pkConfig.setParent("com.example.import1")
                //dao
                .setMapper("dao")
                //service
                .setService("service")
                //controller
                .setController("controller")
                .setEntity("entity")
                //mapper.xml
                .setXml("mapper");
        return pkConfig;
    }
}

12. 配置文件yml

server:
  port:
    8546

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo
    username: root
    password: root

# MyBatis配置
mybatis-plus:
  # 搜索指定包别名
  typeAliasesPackage: com.example.import1.domain
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapperLocations: classpath*:mapper/**/*Mapper.xml

logging:
  level:
    com.example: debug

13. 项目层级

在这里插入图片描述

14. postman运行方式

在这里插入图片描述

15. 运行结果(校验失败)

在这里插入图片描述

16. 运行结果(补上缺失数据,校验成功)

在这里插入图片描述
在这里插入图片描述
本章对于SpringBoot+Mybatis-plus+poi实现导入校验就完成了,当我们有几个不同类型的单元格导入的情况下,可以实现实现类工厂导入方法,使用校验工厂和导入工厂分别生产对应类型的校验方法和导入方法,以完成对新增其他类型excel的导入校验
下一章将本章的非空校验改为自定义注解+反射实现对excel表格校验。
纯手打,技术有限,请各位大佬批评指正,谢谢!

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值