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

目录

一、数据字典

(一)、什么是数据字典

(二)、数据字典的设计

二、Excel数据批量导入

(一)后端接口

1、添加依赖

2、创建Excel实体类

3、创建监听器

4、Mapper层批量插入

5、Service层创建监听器实例

6、controller层接受客户端请求

7、添加mapper发布配置

8、Swagger接口测试 

(二)前端调用

1、创建页面组件

2、配置路由

3、数据导入


一、数据字典

(一)、什么是数据字典

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

(二)、数据字典的设计

尚融宝10-Excel数据批量导入_第1张图片

  • 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添加依赖


    com.alibaba
    easyexcel



    org.apache.xmlbeans
    xmlbeans

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 {

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

xml:DictMapper.xml


    insert into dict (
    id ,
    parent_id ,
    name ,
    value ,
    dict_code
    ) values
    
        (
        #{item.id} ,
        #{item.parentId} ,
        #{item.name} ,
        #{item.value} ,
        #{item.dictCode}
        )
    

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配置文件发布配置


    
    
        
            src/main/java
            
                **/*.xml
            
            false
        
    

8、Swagger接口测试 

尚融宝10-Excel数据批量导入_第2张图片

(二)前端调用

1、创建页面组件

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



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编写代码



测试三个回调函数,

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

尚融宝10-Excel数据批量导入_第3张图片

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

尚融宝10-Excel数据批量导入_第4张图片

尚融宝10-Excel数据批量导入_第5张图片

 

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

尚融宝10-Excel数据批量导入_第6张图片

 

你可能感兴趣的:(尚融宝,excel,前端,java,后端)