栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

【SpringBoot+Mybatis-plus+poi】实现校验导入excel(一)
  • 【SpringBoot+Mybatis-plus+poi】实现校验导入excel(一)
      • 1. 实体(为Mybatis的Generator生成工具生成)
      • 2. dao层(为Mybatis的Generator生成工具生成)
      • 3. service层(为Mybatis的Generator生成工具生成)
        • 3.1. api
        • 3.1. impl(内部方法为实现类导入方法工厂的方法)
      • 4. 实现类工厂生产实现类导入方法
      • 5. mapper层
      • 6. 导入工厂
        • 6.1. 生产导入
      • 7. 校验工厂
        • 7.1. 生产校验方式
      • 8. 工具类
      • 9. pom路径
      • 10. controller层
      • 11. Generator代码生成工具
      • 12. 配置文件yml
      • 13. 项目层级
      • 14. postman运行方式
      • 15. 运行结果(校验失败)
      • 16. 运行结果(补上缺失数据,校验成功)

【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;


@Mapper
public interface TUserMapper extends baseMapper {

}
3. service层(为Mybatis的Generator生成工具生成) 3.1. api
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.import1.domain.TUser;


public interface IUserService extends IService {

}
3.1. impl(内部方法为实现类导入方法工厂的方法)
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl 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;


public interface ICombineService {

    
    XSSFWorkbook importExcel(InputStream inputStream) throws IOException;
}
5. mapper层




    
    
        
        
        
        
        
        
    

    
    
        id, name, age, sex, address, contactInformation
    



6. 导入工厂
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

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


public interface Iimport {

    
    void checkResult(StringBuilder errorMsg, XSSFWorkbook wb, Sheet s, int allNums, InputStream inputStream)throws IOException;

    
    void createData(Sheet s, int allNums);

    
    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;


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 dataList = new ArrayList<>();
        ICheck 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;


public interface ICheck {

    
    void check(Sheet s, int allNums, StringBuilder errorString, XSSFCellStyle cellStyle, List 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;


public class UserCheck implements ICheck {
    @Override
    public void check(Sheet s, int allNums, StringBuilder errorString, XSSFCellStyle cellStyle, List dataList,
                      int START_INDEX, int ERROR_INDEX, DataFormatter dataFormatter, TUserMapper userMapper) {
        for(int i = START_INDEX; i 
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 {
    
    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路径


    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.6.2
         
    
    com.example
    import1
    0.0.1-SNAPSHOT
    import1
    Demo project for Spring Boot
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.2.0
        
        
            com.baomidou
            mybatis-plus-generator
            3.2.0
        
        
            org.apache.velocity
            velocity-engine-core
            2.0
        

        
            mysql
            mysql-connector-java
            runtime
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            org.apache.poi
            poi
            4.1.2
        
        
        
            org.apache.poi
            poi-ooxml
            4.1.2
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    



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;


@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    private IUserService userService;

    @Autowired
    private ICombineService combineService;

    
    @GetMapping("/query/user")
    public ResponseEntity> queryUser(){
        return ResponseEntity.ok(userService.list());
    }

    
    @PostMapping("/import/user")
    public ResponseEntity 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();
    }


    
//    private static InjectionConfig customerConfig() {
//        InjectionConfig config = new InjectionConfig() {
//            @Override
//            public void initMap() {
//
//            }
//        };
//        List files = new ArrayList();
//        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;
//    }

    
    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;
    }

    
    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;
    }

    
    private static StrategyConfig configStrategyConfig() {
        StrategyConfig stConfig = new StrategyConfig();

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

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

    
    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表格校验。
纯手打,技术有限,请各位大佬批评指正,谢谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/696298.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号