尚融宝10-Excel数据批量导入

news2025/3/1 6:51:14

目录

一、数据字典

(一)、什么是数据字典

(二)、数据字典的设计

二、Excel数据批量导入

(一)后端接口

1、添加依赖

2、创建Excel实体类

3、创建监听器

4、Mapper层批量插入

5、Service层创建监听器实例

6、controller层接受客户端请求

7、添加mapper发布配置

8、Swagger接口测试 

(二)前端调用

1、创建页面组件

2、配置路由

3、数据导入


一、数据字典

(一)、什么是数据字典

何为数据字典?数据字典负责管理系统常用的分类数据或者一些固定数据,例如:省市区三级联动数据、民族数据、行业数据、学历数据等,数据字典帮助我们方便的获取和适用这些通用数据。

(二)、数据字典的设计

  • parent_id:上级id,通过id与parent_id构建上下级关系,例如:我们要获取所有行业数据,那么只需要查询parent_id=20000的数据
  • name:名称,例如:填写用户信息,我们要select标签选择民族,“汉族”就是数据字典的名称
  • value:值,例如:填写用户信息,我们要select标签选择民族,“1”(汉族的标识)就是数据字典的值
  • dict_code:编码,编码是我们自定义的,全局唯一,例如:我们要获取行业数据,我们可以通过parent_id获取,但是parent_id是不确定的,所以我们可以根据编码来获取行业数据

二、Excel数据批量导入

(一)后端接口

1、添加依赖

在srb-core中pom.xml添加依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
</dependency>

<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
</dependency>

2、创建Excel实体类

package com.atguigu.srb.core.pojo.dto;
@Data
public class ExcelDictDTO {

    @ExcelProperty("id")  // 和Excel文件的列名匹配
    private Long id;

    @ExcelProperty("上级id")
    private Long parentId;

    @ExcelProperty("名称")
    private String name;

    @ExcelProperty("值")
    private Integer value;

    @ExcelProperty("编码")
    private String dictCode;
}

3、创建监听器

package com.atguigu.srb.core.listener;

@Slf4j
//@AllArgsConstructor //全参
@NoArgsConstructor //无参
public class ExcelDictDTOListener extends AnalysisEventListener<ExcelDictDTO> {

    /**
     * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 5;
    List<ExcelDictDTO> list = new ArrayList();

    private DictMapper dictMapper;

	//传入mapper对象
    public ExcelDictDTOListener(DictMapper dictMapper) {
        this.dictMapper = dictMapper;
    }

    /**
     *遍历每一行的记录
     * @param data
     * @param context
     */
    @Override
    public void invoke(ExcelDictDTO data, AnalysisContext context) {
        log.info("解析到一条记录: {}", data);
        list.add(data);
        // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (list.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成!");
    }

    /**
     * 加上存储数据库
     */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", list.size());
        dictMapper.insertBatch(list);  //批量插入
        log.info("存储数据库成功!");
    }
}

4、Mapper层批量插入

接口:DictMapper

一开始脑抽了在想为什么方法不写在service层,要写在mapper层,因为它要写sql语句!!!而mybatisPlus没有现有的方法供调用

void insertBatch(List<ExcelDictDTO> list);

xml:DictMapper.xml

<insert id="insertBatch">
    insert into dict (
    id ,
    parent_id ,
    name ,
    value ,
    dict_code
    ) values
    <foreach collection="list" item="item" index="index" separator=",">
        (
        #{item.id} ,
        #{item.parentId} ,
        #{item.name} ,
        #{item.value} ,
        #{item.dictCode}
        )
    </foreach>
</insert>

5、Service层创建监听器实例

接口 DictService

void importData(InputStream inputStream);

实现:DictServiceImpl

注意:此处添加了事务处理,默认情况下rollbackFor = RuntimeException.class

@Transactional(rollbackFor = {Exception.class})
@Override
public void importData(InputStream inputStream) {
    // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
    EasyExcel.read(inputStream, ExcelDictDTO.class, new ExcelDictDTOListener(baseMapper)).sheet().doRead();
    log.info("importData finished");
}

6、controller层接受客户端请求

 AdminDictController

package com.atguigu.srb.core.controller.admin;

@Api(tags = "数据字典管理")
@RestController
@RequestMapping("/admin/core/dict")
@Slf4j
@CrossOrigin  // 跨域
public class AdminDictController {

    @Resource
    private DictService dictService;

    @ApiOperation("Excel批量导入数据字典")
    @PostMapping("/import")
    public R batchImport(
            @ApiParam(value = "Excel文件", required = true)
            @RequestParam("file") MultipartFile file) {

        try {
            InputStream inputStream = file.getInputStream();
            dictService.importData(inputStream);
            return R.ok().message("批量导入成功");
        } catch (Exception e) {
            //UPLOAD_ERROR(-103, "文件上传错误"),
            throw new BusinessException(ResponseEnum.UPLOAD_ERROR, e);
        }
    }
}

7、添加mapper发布配置

注意:因为maven工程在默认情况下src/main/java目录下的所有资源文件是不发布到target目录下的,因此我们需要在pom.xml中添加xml配置文件发布配置

<build>
    <!-- 项目打包时会将java目录中的*.xml文件也进行打包 -->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>

8、Swagger接口测试 

(二)前端调用

1、创建页面组件

创建 src/views/core/dict/list.vue

<template>
  <div class="app-container">
    
  </div>
</template>

<script>
export default {
  
}
</script>

2、配置路由

{
    path: '/core',
    component: Layout,
    redirect: '/core/dict/list',
    name: 'coreDict',
    meta: { title: '系统设置', icon: 'el-icon-setting' },
    alwaysShow: true,
    children: [
      {
        path: 'dict/list',
        name: '数据字典',
        component: () => import('@/views/core/dict/list'),
        meta: { title: '数据字典' }
      }
    ]
},

3、数据导入

在 src/views/core/dict/list.vue编写代码

<template>
  <div class="app-container">
    <div style="margin-bottom: 10px;">
      <el-button
        @click="dialogVisible = true"
        type="primary"
        size="mini"
        icon="el-icon-download"
      >
        导入Excel
      </el-button>
    </div>

    <el-dialog title="数据字典导入" :visible.sync="dialogVisible" width="30%">
      <el-form>
        <el-form-item label="请选择Excel文件">
          <el-upload
            :auto-upload="true"
            :multiple="false"
            :limit="1"
            :on-exceed="fileUploadExceed"
            :on-success="fileUploadSuccess"
            :on-error="fileUploadError"
            :action="BASE_API + '/admin/core/dict/import'"
            name="file"
            accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
          >
            <el-button size="small" type="primary">点击上传</el-button>
          </el-upload>
        </el-form-item>
      </el-form>                                                                                                                                                                                           
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">
          取消
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  // 定义数据
  data() {
    return {
      dialogVisible: false, //文件上传对话框是否显示
      BASE_API: process.env.VUE_APP_BASE_API //获取后端接口地址
    }
  },

  methods: {
    // 上传多于一个文件时
    fileUploadExceed() {
      this.$message.warning('只能选取一个文件')
    },

    //上传成功回调
    fileUploadSuccess(response) {
      if (response.code === 0) {
        this.$message.success('数据导入成功')
        this.dialogVisible = false
      } else {
        this.$message.error(response.message)
      }
    },

    //上传失败回调
    fileUploadError(error) {
      this.$message.error('数据导入失败')
    }
  }
}
</script>

测试三个回调函数,

测试失败回调函数,数据库中表单没有删除时导入文件会出现主键冲突

 测试上传超出文件数量回调函数时,需要将自动上传设置为false,此时选择文件不会自动上传,然后分两次选择文件,超出limit限制会报错

 

 删除数据库记录,导入Excel文件,显示导入成功,弹窗自动关闭

 

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

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

相关文章

2023年,想要靠做软件测试获得高薪,我还有机会吗?

时间过得很快&#xff0c;一眨眼&#xff0c;马上就要进入2023年了&#xff0c;到了年底&#xff0c;最近后台不免又出现了经常被同学问道这几个问题&#xff1a;2023年还能转行软件测试吗&#xff1f;零基础转行可行吗&#xff1f; 本期小编就“2023年&#xff0c;入行软件测…

一文解决nltk安装问题ModuleNotFoundError: No module named ‘nltk‘,保姆级教程

目录 问题一&#xff1a;No module named ‘nltk‘ 问题二&#xff1a;Please use the NLTK Downloader to obtain the resource 下载科学上网工具 问题三&#xff1a;套娃报错 如果会科学上网&#xff0c;可以直接看问题三 问题一&#xff1a;No module named ‘nltk‘ Mo…

【微服务笔记16】微服务组件之Gateway服务网关基础环境搭建

这篇文章&#xff0c;主要介绍微服务组件之Gateway服务网关基础环境搭建。 目录 一、Gateway服务网关 1.1、什么是Gateway 1.2、Gateway基础环境搭建 &#xff08;1&#xff09;基础环境介绍 &#xff08;2&#xff09;引入依赖 &#xff08;3&#xff09;添加路由配置信…

软件测试工程师的进阶之旅

很多人对测试工程师都有一些刻板印象&#xff0c;比如觉得测试“入门门槛低&#xff0c;没有技术含量”、“对公司不重要”、“操作简单工作枯燥”“一百个开发&#xff0c;一个测试”等等。 会产生这种负面评论&#xff0c;是因为很多人对测试的了解&#xff0c;还停留在几年…

Lesson12 udptcp协议

netstat命令->查看网络状态 n 拒绝显示别名&#xff0c;能显示数字的全部转化成数字l 仅列出有在 Listen (监听) 的服務状态p 显示建立相关链接的程序名t (tcp)仅显示tcp相关选项u (udp)仅显示udp相关选项a (all)显示所有选项&#xff0c;默认不显示LISTEN相关 pidof命令-&…

SQL select详解(基于选课系统)

表详情&#xff1a; 学生表&#xff1a; 学院表&#xff1a; 学生选课记录表&#xff1a; 课程表&#xff1a; 教师表&#xff1a; 查询&#xff1a; 1. 查全表 -- 01. 查询所有学生的所有信息 -- 方法一&#xff1a;会更复杂&#xff0c;进行了两次查询&#xff0c;第一…

机器学习笔记之正则化(六)批标准化(BatchNormalization)

机器学习笔记之正则化——批标准化[Batch Normalization] 引言引子&#xff1a;梯度消失梯度消失的处理方式批标准化 ( Batch Normalization ) (\text{Batch Normalization}) (Batch Normalization)场景构建梯度信息比例不平衡批标准化对于梯度比例不平衡的处理方式 ICS \text{…

《抄送列表》:过滤次要文件,优先处理重要文件

目录 一、题目 二、思路 1、查找字符/字符串方法&#xff1a;str1.indexOf( ) 2、字符串截取方法&#xff1a;str1.substring( ) 三、代码 详细注释版&#xff1a; 简化注释版&#xff1a; 一、题目 题目&#xff1a;抄送列表 题目链接&#xff1a;抄送列表 …

Java[集合] Map 和 Set

哈喽&#xff0c;大家好~ 我是保护小周ღ&#xff0c;本期为大家带来的是 Java Map 和 Set 集合详细介绍了两个集合的概念及其常用方法&#xff0c;感兴趣的朋友可以来学习一下。更多精彩敬请期待&#xff1a;保护小周ღ *★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* ‘ 一、…

JVM知识汇总

1、JVM架构图 2、Java编译器 Java编译器做的事情很简单&#xff0c;其实就是就是将Java的源文件转换为字节码文件。 1. 源文件存储的是高级语言的命令&#xff0c;JVM只认识"机器码"&#xff1b; 2. 因此将源文件转换为字节码文件&#xff0c;即是JVM看得懂的"…

Node.js—Buffer(缓冲器)

文章目录 1、概念2.、特点3、创建Buffer3.1 Buffer.alloc3.2 Buffer.allocUnsafe3.3 Buffer.from 4、操作Buffer4.1 Buffer 与字符串的转化4.2 Buffer 的读写 参考 1、概念 Buffer 是一个类似于数组的对象 &#xff0c;用于表示固定长度的字节序列。Buffer 本质是一段内存空间…

视觉学习(四) --- 基于yolov5进行数据集制作和模型训练

环境信息 Jetson Xavier NX&#xff1a;Jetpack 4.4.1 Ubuntu&#xff1a;18.04 CUDA: 10.2.89 OpenCV: 4.5.1 cuDNN&#xff1a;8.0.0.180一.yolov5 项目代码整体架构介绍 1. yolov5官网下载地址&#xff1a; GitHub: https://github.com/ultralytics/yolov5/tree/v5.0 2. …

单元测试中的独立运行

单元测试中的独立运行 单元测试是针对代码单元的独立测试。要测试代码单元&#xff0c;首先要其使能够独立运行。项目中的代码具有依赖关系&#xff0c;例如&#xff0c;一个源文件可能直接或间接包含大量头文件&#xff0c;并调用众多其他源文件的代码&#xff0c;抽取其中的一…

论文阅读:Unsupervised Manifold Linearizing and Clustering

Author: Tianjiao Ding, Shengbang Tong, Kwan Ho Ryan Chan, Xili Dai, Yi Ma, Benjamin D. Haeffele Abstract 在本文中&#xff0c;我们建议同时执行聚类并通过最大编码率降低来学习子空间联合表示。 对合成和现实数据集的实验表明&#xff0c;所提出的方法实现了与最先进的…

limit、排序、分组单表查询(三)MySQL数据库(头歌实践教学平台)

文章目的初衷是希望学习笔记分享给更多的伙伴&#xff0c;并无盈利目的&#xff0c;尊重版权&#xff0c;如有侵犯&#xff0c;请官方工作人员联系博主谢谢。 目录 第1关&#xff1a;对查询结果进行排序 任务描述 相关知识 对查询结果排序 指定排序方向 编程要求 第2关&a…

浏览器架构和事件循环

浏览器架构 早期浏览器【单进程多线程】 Page Thread 页面渲染&#xff0c;负责执行js,plugin,drawNetWork Thread 网络请求其余线程 file, storage缺点&#xff1a;只要其中一个线程崩溃&#xff0c;页面就会崩溃。 现代浏览器架构 多进程的浏览器&#xff0c;浏览器的每一个…

几种常见的激活函数

文章目录 常见的激活函数介绍Sigmoid函数ReLU函数LeakyReLU函数Tanh函数Softmax函数总结 常见的激活函数介绍 激活函数是神经网络中的重要组成部分&#xff0c;它决定了神经元的输出。在神经网络的前向传播中&#xff0c;输入数据被传递给神经元&#xff0c;经过加权和和激活函…

Unity自动化打包(1)

一 安装Jenkins https://www.jenkins.io/download/ 官网 1&#xff09; 使用 brew 安装 2&#xff09; 安装完成后一般都会遇到问题 我用的是jenkins-lts 稳定版 解决办法 删除掉对应的文件夹 1 rm -rf /usr/local/Homebrew/Library/Taps/homebrew/homebrew-services 2…

kafka延时队列内部应用简介

kafka延时队列_悠然予夏的博客-CSDN博客 两个follower副本都已经拉取到了leader副本的最新位置&#xff0c;此时又向leader副本发送拉取请求&#xff0c;而leader副本并没有新的消息写入&#xff0c;那么此时leader副本该如何处理呢&#xff1f;可以直接返回空的拉取结…

[ 高并发]Java高并发编程系列第二篇--线程同步

并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求,而且也能怎么你在整个项目中的一个处理逻辑的能力体现.那么,你真的知道什么…