excel导入

news2025/1/11 22:37:44

Excel数据导入

使用easyexcel和hutool-poi实现excel导入

1、pom依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.6</version>
        </dependency>
        
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-poi</artifactId>
            <version>5.8.21</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
        

2、导入流程描述

在这里插入图片描述

2.1、读取excel

读取excel中的源数据

2.2、数据校验
2.2.1 对源数据进行数据校验
2.2.2 将满足校验规则的数据放入normalList中
2.2.3 将不满足校验规则的数据放入errorList中
2.2.4 将最后的成功、失败数量结果放入importResult中
2.2.5 将校验结果返回给前端

将校验后的数据normalList、errorList、importResult返回给前端,如果存在错误数据(及errorList不为空)则提示用户更改,用户更改后重新对更改后的excel文件执行数据校验操作,直达所有的数据都是正确数据(及errorList为空)则执行数据入库操作

2.3 数据入库

将数据校验完成后的normalList拿到(此时的errorList一定是空的),直接进行入库操作,如果存在入库失败的数据则放入errorList中直接返给前端展示出来错误原因,不另外做其他操作

3、代码示例

3.1 excel导入返回VO
/**
 * @author: yc
 * @des:  excel导入vo
 * @date: 2024/07/17 20:57
 */
@Data
public class ExcelImportVO {

    @ApiModelProperty("错误的数据")
    private List<?> errorList;

    @ApiModelProperty("正常的数据")
    private List<?> normalList;

    @ApiModelProperty("导入结果")
    private String importResult;

}
3.2 用户导入模板
/**
 * @author: yc
 * @des:  用户导入模板
 * @date: 2024/07/18 13:35
 */
@Data
public class UserImportTemplate {

    /**
     * 行号
     */
    private Integer rowNumber;

    /**
     * 姓名
     */
    @ExcelProperty("姓名")
    @ColumnWidth(20)
    private String realName;

    /**
     * 手机号
     */
    @ExcelProperty("手机号")
    @ColumnWidth(20)
    private String mobile;

    /**
     * 组织名称
     */
    @ExcelProperty("组织名称")
    @ColumnWidth(20)
    private String organizeName;

    private String organizeId;

    /**
     * 部门名称
     */
    @ExcelProperty("部门名称")
    @ColumnWidth(20)
    private String departmentName;

    private String departmentId;

    /**
     * 校验信息
     */
    private String verifyMsg;

    /**
     * @author: yc
     * @des:  校验
     * @date: 2024/07/18 14:00
     */
    public void verify(List<BaseDepartment> departmenList, BaseDepartService baseDepartService){
        StringBuilder msg = new StringBuilder();
        // 姓名
        if(StringUtils.isBlank(this.realName)){
            msg.append("姓名不能为空");
        }
        // 手机号
        if(StringUtils.isBlank(this.mobile)){
            msg.append("姓名不能为空");
        }else{
            if (!Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$").matcher(this.mobile).matches()) {
                msg.append("手机号不正确");
            }
        }
        // 组织名称
        if(StringUtils.isBlank(this.organizeName)){
            msg.append("组织名称不能为空");
        }
        // 部门名称
        if(StringUtils.isBlank(this.departmentName)){
            msg.append("部门名称不能为空");
        }else{
            BaseDepartment department = baseDepartService.getDepartmentByName(this.departmentName, departmenList);
            if(Objects.isNull(department)){
                msg.append("部门不存在");
            }else{
                this.departmentId = department.getDepartmentId();
            }
        }
        this.verifyMsg = msg.toString();
    }

    /**
     * @author: yc
     * @des:  模板转实体
     * @date: 2024/07/18 14:09
     */
    public BaseUser template2entity(){
        BaseUser baseUser = new BaseUser();
        baseUser.setUserId(IdUtil.simpleUUID());
        baseUser.setAccount(this.mobile);
        baseUser.setPassword("8e00646ca539d84f41e085c6ee9a54ba");
        baseUser.setSecretkey("f240625eb8a38ae1");
        baseUser.setRealName(this.realName);
        baseUser.setMobile(this.mobile);
        baseUser.setOrganizeId(this.organizeId);
        baseUser.setDepartmentId(this.departmentId);
        baseUser.setDeleteMark(0);
        baseUser.setEnabledMark(1);
        baseUser.setModifyDate(new Date());
        baseUser.setCreateDate(new Date());
        return baseUser;
    }

}
3.3 excel文件数据读取、校验
    /**
     * @author: yc
     * @des:  excel导入前检验
     * @date: 2024/07/18 10:56
     */
    @Override
    public Result<ExcelImportVO> excelImportVerify(MultipartFile file) {
        ExcelImportVO excelImportVO = new ExcelImportVO();
        if(Objects.isNull(file)){
            return Result.fail(ResultCode.GLOBAL_PARAM_ERROR.getCode(),"上传文件不能为空");
        }
        String fileName = file.getOriginalFilename();
        //文件名
        String name = fileName.substring(0,fileName.lastIndexOf("."));
        //文件类型
        String type = fileName.substring(fileName.lastIndexOf("."));
        if(StringUtils.isBlank(type) || (!type.equals(".xlsx") && !type.equals(".xls"))){
            return Result.fail(ResultCode.FAILURE.getCode(),"文件名格式不正确,请上传.xlsx或.xls文件");
        }
        //判断文件名长度是否小于3,解决 临时文件 too short问题
        fileName = name.length() <= 3 ? name + (new Random().nextInt(900)+100) + type : fileName;
        // 从excel中拿到数据
        List<UserImportTemplate> dataList = new ArrayList<>();
        try {
            ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
            List<List<Object>> excelDataList = excelReader.read(1);
            if(CollectionUtils.isEmpty(excelDataList)){
                return Result.fail(ResultCode.FAILURE.getCode(),"无数据导入");
            }
            AtomicInteger rowNumber = new AtomicInteger(1);
            excelDataList.forEach(i -> {
                Object[] rowData = i.toArray(new Object[10]);
                UserImportTemplate template = new UserImportTemplate();
                template.setRealName(null == rowData[0] ? "" : String.valueOf(rowData[0]));
                template.setMobile(null == rowData[1] ? "" : String.valueOf(rowData[1]));
                template.setOrganizeName(null == rowData[2] ? "" : String.valueOf(rowData[2]));
                template.setDepartmentName(null == rowData[3] ? "" : String.valueOf(rowData[3]));
                template.setRowNumber(rowNumber.getAndAdd(1));
                dataList.add(template);
            });
            // 数据校验
            // 部门信息
            List<BaseDepartment> departmenList = baseDepartService.list();
            dataList.forEach(i -> {
                i.verify(departmenList,baseDepartService);
            });
            StringBuilder resultMsg = new StringBuilder();
            // 正常数据
            excelImportVO.setNormalList(dataList.stream().filter(i -> StringUtils.isBlank(i.getVerifyMsg())).collect(Collectors.toList()));
            // 错误数据
            excelImportVO.setErrorList(dataList.stream().filter(i -> StringUtils.isNotBlank(i.getVerifyMsg())).collect(Collectors.toList()));
            resultMsg.append("成功" + excelImportVO.getNormalList().size() + "条");
            if(!CollectionUtils.isEmpty(excelImportVO.getErrorList())){
                resultMsg.append(",失败" + excelImportVO.getErrorList().size() + "条");
            }
            excelImportVO.setImportResult(resultMsg.toString());
        } catch (Exception e) {
            return Result.fail(ResultCode.FAILURE.getCode(),e.getMessage());
        }
        return Result.data(excelImportVO);
    }
3.4 数据入库
    /**
     * @author: yc
     * @des:  excel导入
     * @date: 2024/07/18 10:57
     */
    @Override
    public Result<ExcelImportVO> excelImport(List<UserImportTemplate> successList) {
        ExcelImportVO excelImportVO = new ExcelImportVO();
        if(CollectionUtils.isEmpty(successList)){
            return Result.fail(ResultCode.FAILURE.getCode(),"导入数据不存在");
        }
        List<UserImportTemplate> errorList = new ArrayList<>();
        for(UserImportTemplate template : successList){
            try {
                super.save(template.template2entity());
            }catch (Exception e){
                template.setVerifyMsg("当前数据已存在");
                errorList.add(template);
            }
        }
        successList.removeAll(errorList);
        excelImportVO.setNormalList(successList);
        excelImportVO.setErrorList(errorList);
        StringBuilder resultMsg = new StringBuilder();
        resultMsg.append("成功" + excelImportVO.getNormalList().size() + "条");
        if(!CollectionUtils.isEmpty(excelImportVO.getErrorList())){
            resultMsg.append(",失败" + excelImportVO.getErrorList().size() + "条");
        }
        excelImportVO.setImportResult(resultMsg.toString());
        return Result.data(excelImportVO);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2040270.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL 数据库设计、事务、视图 <12>

一、数据库设计 1.多表之间的关系 1&#xff09; 一对一&#xff08;了解&#xff09; 如&#xff1a;人和身份证 分析&#xff1a;一个人只有一个身份证&#xff0c;一个身份证只能对应一个人 2&#xff09;一对多&#xff08;多对一&#xff09; 如&#xff1a;部门和员…

Apache-JMeter压测工具教程

下载安装 《JMeter官网下载》 下载完成后&#xff0c;找个文件夹进行解压 配置环境变量 JAVA_HOME&#xff08;如果是JAVA8还需要配置CLASSPATH&#xff09;、JMETER_HOME JMETER_HOME修改bin目录下的jmeter.properties文件编码为UTF-8 5.6.3这个版本encoding已经默认为UT…

图片鼠标中心滚轮放大

功能背景 实现以鼠标在图中的位置为中心进行图片的滚轮缩放&#xff0c;现在是无论鼠标位置在哪都以图片中心进行缩放&#xff0c;这不符合预期&#xff1b; 关键点 缩放前鼠标在的位置是 A&#xff08;clinetX,clientY&#xff09; 点&#xff0c;缩放后鼠标的位置是 A’&a…

驱动基础开发

1、字符设备传统开发模板 字符设备驱动框架&#xff0c;首先我们需要去用module_init这个宏去修饰整个驱动的入口函数&#xff0c;用module_exit去修饰整个驱动的出口函数&#xff0c;然后还需要用MODULE_LICENSE用于声明模块的许可证类型。 在入口函数里面我们需要注册字符设…

mitmdump 实时抓包处理

mitmdump 是 mitmproxy 的命令行接口&#xff0c;可以对接 Python 脚本处理请求和响应&#xff0c;这是比 Fiddler , Charles 等工具更加方便的地方&#xff0c;有了它&#xff0c;我们不用再手动抓取和分析HTTP 请求和响应&#xff0c;只要写好请求和响应的处理逻辑就好了。 …

jenkins jdk8下载

jdk8 对应的 jenkins版本是2.346.1 http://updates.jenkins-ci.org/download/war/2.346.1/jenkins.warjenkins和jdk安装教程(安装支持jdk8的最新版本) https://blog.csdn.net/u013078871/article/details/127200623刚买的腾讯云安装jenkins步骤&#xff0c;服务器安装jenkins步…

基于华为atlas的皮带跑偏、空载、堆煤、启停探索

生乎吾前&#xff0c;其闻道也固先乎吾&#xff0c;吾从而师之&#xff1b;生乎吾后&#xff0c;其闻道也亦先乎吾&#xff0c;吾从而师之。吾师道也&#xff0c;夫庸知其年之先后生于吾乎&#xff1f;是故无贵无贱&#xff0c;无长无少&#xff0c;道之所存&#xff0c;师之所…

超详细!!!electron-vite-vue开发桌面应用之配置路由router(五)

云风网 云风笔记 云风知识库 一、安装依赖 npm install vue-router二、配置项目文件路径 三、配置路由router 在src下新建一个router目录&#xff0c;然后在里面添加一个index.ts文件&#xff0c;在里面配置路由 import { createRouter, createWebHashHistory } from vue-…

针对thinkphp站点的漏洞挖掘和经验分享

0x1 前言 浅谈 目前在学习和研究thinkphp相关漏洞的打法&#xff0c;然后最近对于thinkphp资产的收集方面有了一个简单的认识&#xff0c;然后写一篇新手看的thinkphp相关的漏洞收集和挖掘的文章来分享下。然后后面是给师傅们分享下后台文件上传&#xff0c;然后直接打一个ge…

RCE-eval长度限制绕过技巧

目录 限制16字符 题目源码 方法一&#xff1a;$_GET[1] 方法二&#xff1a;file_put_contents 方法三&#xff1a;usort(…$_GET); 限制7字符 题目源码 限制16字符 题目源码 <?php $param $_REQUEST[param]; If ( strlen($param) < 17 && stripos($param…

微服务系列:Spring Cloud 之 Feign、Ribbon、Hystrix 三者超时时间配置

Feign 自身有超时时间配置 Feign 默认集成的 Ribbon 中也有超时时间配置 假如我们又使用了 Hystrix 来实现熔断降级&#xff0c;Hystrix 自身也有一个超时时间配置 注: spring-cloud-starter-openfeign 低一点的版本中默认集成的有 Hystrix&#xff0c;高版本中又移除了。 …

Gin框架接入Prometheus,grafana辅助pprof检测内存泄露

prometheus与grafana的安装 grom接入Prometheus,grafana-CSDN博客 Prometheus 动态加载 我们想给Prometheus新增监听任务新增ginapp项目只需要在原来的配置文件下面新增ginapp相关metric 在docker compose文件下面新增 执行 docker-compose up -d curl -X POST http://lo…

C++ 设计模式——模板方法模式

模板方法模式 模板方法模式逐步重构并引入模板方法模式初始实现提取共性并引入模板方法模式实现具体类 完整代码示例模板方法模式的 UML 图UML 图详细介绍 模板方法模式适用于以下场景 模板方法模式 模板方法模式是一种行为设计模式&#xff0c;它定义了一个算法的骨架&#x…

C++11代码实战经典—MySQL数据库连接池

课程总目录 文章目录 一、项目介绍1.1 关键技术点1.2 项目背景1.3 连接池功能点介绍1.4 MySQL Server参数介绍1.5 项目功能点设计和技术细节 二、MySQL数据库编程三、项目代码逐步实现3.1 连接池单例模式实现3.2 实现加载配置项3.3 连接池的构造函数3.4 实现生产者3.5 实现消费…

其他浏览器正常,火狐浏览器ui-grid换行问题

ui-grid火狐浏览器兼容性问题 ui-grid表格插件问题描述解决方案 ui-grid表格插件 火狐浏览器 UI-grid 兼容性问题 其他如Edge、谷歌、360浏览器正常情况下 火狐浏览器 问题描述 如上图一和图二显示&#xff0c;UI-gird在火狐换行了&#xff1a;从图片来看&#xff1b;后面…

【车载开发系列】ASPICE标准实践---使用Drome系统保证一致性

【车载开发系列】ASPICE标准实践—使用Drome系统保证一致性 【车载开发系列】ASPICE标准实践---使用Drome系统保证一致性 【车载开发系列】ASPICE标准实践---使用Drome系统保证一致性一、一致性的目的二、ASPICE标准三、ASPICE标准实施难点四、保证一致性的实践1. 参与评审2. 可…

ES6-ES13学习笔记

目录 初识ES6 变量声明 解构赋值 对象解构 ​编辑 数组解构 ​编辑模版字符串 字符串扩展 includes() repeat() startsWith() endsWith() 数值扩展 二进制和八进制表示法 &#xff08;Number.&#xff09;isFinite()与isNaN() Number.isInteger() Math.trunc …

vue前端可以完整的显示编辑子级部门,用户管理可以为用户分配角色和部门?

用户和角色是一对多的关系用户和部门是多对多得关系<template><div class="s"><!-- 操作按钮 --><div class="shang"><el-input v-model="searchText" placeholder="请输入搜索关键词" style="width:…

上海凯泉泵业入职测评北森题库题型分析、备考题库、高分攻略

上海凯泉泵业&#xff08;集团&#xff09;有限公司是一家大型综合性泵业公司&#xff0c;专注于设计、生产、销售泵、给水设备及其控制设备。作为中国泵行业的领军企业&#xff0c;凯泉集团拥有7家企业和5个工业园区&#xff0c;总资产达到25亿元&#xff0c;生产性建筑面积35…

Python 在PDF中添加条形码、二维码

在PDF中添加条码是一个常见需求&#xff0c;特别是在需要自动化处理、跟踪或检索PDF文件时。作为一种机器可读的标识符&#xff0c;PDF中的条码可以包含各种类型的信息&#xff0c;如文档的唯一标识、版本号、日期等。以下是一篇关于如何使用Python在PDF中添加条形码或二维码的…