5.2 iHRM人力资源 - 员工管理 - 使用文件导入导出员工

news2024/12/1 0:33:11

iHRM人力资源 - 员工管理 - 导入导出员工

文章目录

  • iHRM人力资源 - 员工管理 - 导入导出员工
  • 一、员工导出Excel
  • 二、员工导入Excel
    • 2.1 Excel导入组件封装
    • 2.2 下载导入模板
    • 2.3 Excel 导入功能
  • 三、删除员工

一、员工导出Excel

这个地方涉及一个接口二进制流blob

image-20240408204202305

就是下面这一大片乱七八糟的玩意(二进制文件流),接收完流后通过下载的方式将文件下载下载(图片左下方)

image-20240408204336372

总结步骤

image-20240408205238034

  1. api方法
/**
 * 导出员工的Excel
 */
export function exportEmployee() {
  return request({
    url: '/sys/user/export',
    // 接收二进制流类型的数据需要改变axios的接收数据类型
    // 使用blob接收二进制文件流
    responseType: 'blob'
  })
}
  1. 点击事件
<el-button size="mini" @click="exportEmployee">excel导出</el-button>
// 导出员工的Excel
async exportEmployee() {
  await exportEmployee()
}
  1. 修改响应拦截器

因为返回的不是JSON数据了,所以我们要处理一下

image-20240408210135899

// 创建响应拦截器,并且两个参数都是回调函数
service.interceptors.response.use(
  // 请求成功时响应,此时的响应默认包裹了一层data,即response.data才是后台服务返回的内容
  (response) => {
    // 首先判断响应的数据是JSON格式数据还是blob二进制文件流
    if (response.data instanceof Blob) {
      // 我们认为此时接口返回的是文件
      return response.data
    }
    // 一次性解析出response.data中的三个属性
    const { data, message, success } = response.data // 默认是JSON数据,假如不是JSON数据的话就会报错
    if (success) {
      // 此时响应正常
      return data
    } else {
      Message({ type: 'error', message: message })
      return Promise.reject(new Error(message))
    }
  },
  // 请求失败时响应
  async(error) => {
    if (error.response.status === 401) {
      Message({ type: 'warning', message: 'token 超时了,请重新登录' })
      // token超时,调用action退出登录(删除用户信息)
      // dispatch返回的是一个promise,这里会等dispatch执行完再执行路由跳转
      await store.dispatch('user/logout')
      // 主动跳转到登录页
      router.push('/login')
      return Promise.reject(error)
    }
    // this.$message.warning 不能这么使用,因为此时的this不是组件实例对象
    Message({ type: 'error', message: error.message })
    // 默认支持promise的,下面语句相当于终止了当前promise的执行
    return Promise.reject(error)
  }
)
  1. 用blob接收后就需要保存文件或者说下载文件

首先执行命令下载工具包

npm i file-saver

image-20240408210825522

导入包

import FileSaver from 'file-saver'

修改方法

// 导出员工的Excel
async exportEmployee() {
  const result = await exportEmployee()
  // 使用一个npm包,将blob文件下载到本地 执行命令 npm i file-saver
  // 使用下面这个另存为的方法
  // 参数1:blob对象,参数2:文件名称
  FileSaver.saveAs(result, '员工信息表.xlsx') // 下载二进制文件到浏览器
}

二、员工导入Excel

如下图所示,用户需要按照模板样式上传Excel表格

image-20240408213914913

模板内容如下图所示

image-20240408214022575

流程如下图所示

image-20240408214206465

2.1 Excel导入组件封装

创建组件

image-20240408214332654

  1. 组件内的基本架构
<template>
  <!--弹层部分-->
  <!--visible 控制是否显示-->
  <el-dialog
    width="500px"
    title="员工导入"
    :visible="showExcelDialog"
    @close="$emit('update:showExcelDialog', false)"
  >
    <el-row type="flex" justify="center">
      <div class="upload-excel">
        <!--文本输入框的类型是file,可以接收的文件类型.xlsx或者.xls-->
        <input
          ref="excel-upload-input"
          class="excel-upload-input"
          type="file"
          accept=".xlsx, .xls"
        >
        <div class="drop">
          <i class="el-icon-upload"/>
          <el-button type="text">下载导入模板</el-button>
          <span>将文件拖到此处或
            <el-button type="text">点击上传</el-button>
          </span>
        </div>
      </div>
    </el-row>
    <el-row type="flex" justify="end">
      <!--取消按钮中有一个点击事件,后面是update:props属性名,值  这是直接修改.sync修饰符的属性值-->
      <!-- update:props属性名,值 直接修改 .sync修饰符的属性值 -->
      <el-button size="mini" type="primary" @click="$emit('update:showExcelDialog', false)">取消</el-button>
    </el-row>
  </el-dialog>
</template>
<script>

export default {
  props: {
    // 控制弹层是否展示
    showExcelDialog: {
      type: Boolean,
      default: false
    }
  },
  methods: {}
}
</script>

<style scoped lang="scss">
.upload-excel {
  display: flex;
  justify-content: center;
  margin: 20px;
  width: 360px;
  height: 180px;
  align-items: center;
  color: #697086;

  .excel-upload-input {
    display: none;
    z-index: -9999;
  }

  .btn-upload,
  .drop {
    border: 1px dashed #dcdfe6;
    width: 100%;
    height: 100%;
    text-align: center;
    line-height: 160px;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  .drop {
    line-height: 40px;
    color: #bbb;

    i {
      font-size: 60px;
      display: block;
      color: #c0c4cc;
    }
  }
}
</style>

  1. 在index.vue文件中引入组件
// 引入自定义的组件
import ImportExcel from '@/views/employee/import-excel.vue'
export default {
  name: 'Employee',
  components: {
    ImportExcel
  },
    ......
}
<!--放置导入Excel组件--> 
<import-excel></import-excel>
  1. 控制自定义组件的显示和隐藏
<!--放置导入Excel组件-->
<!--sync修饰符,我们点击关闭弹层或者取消的时候,会自然的把父组件的值改掉-->
<import-excel :show-excel-dialog.sync="showExcelDialog"></import-excel>

数据

      // 控制Excel弹层的显示和隐藏
      showExcelDialog: false

此时弹框的取消和关闭是管用的

image-20240408230640601

  1. 点击按钮弹出弹层
<el-button size="mini" @click="showExcelDialog=true">excel导入</el-button>

2.2 下载导入模板

如下图所示的按钮,点击下载一个Excel模板

image-20240408231002314

这个地方和“导出员工Excel”差不多的形式

image-20240409113511140

  1. api请求
/**
 * 下载员工的导入模板
 */
export function getExportTemplate() {
  return request({
    url: '/sys/user/import/template',
    // 接收二进制流类型的数据需要改变axios的接收数据类型
    // 使用blob接收二进制文件流
    responseType: 'blob'
  })
}
  1. 在我们封装的组件里填写点击“下载导入模板”后,下载模板

    image-20240409144354041

<div class="drop">
  <i class="el-icon-upload"/>
  <el-button type="text" @click="getTemplate">下载导入模板</el-button>
  <span>将文件拖到此处或
    <el-button type="text">点击上传</el-button>
  </span>
</div>

方法

import FileSaver from 'file-saver'
  methods: {
    // 下载导入模板
    async getTemplate() {
      const result = await getExportTemplate()
      // console.log(result) // 使用一个npm包 直接将blob文件下载到本地 file-saver
      // FileSaver.saveAs(blob对象,文件名称)
      FileSaver.saveAs(result, '员工导入模板.xlsx') // 下载文件(另存为)
    }
  }
  1. 效果

    挺完美的

image-20240409144740165

2.3 Excel 导入功能

下面将实现这个功能

image-20240409145125735

流程如下图所示

为什么要清空?

因为我们使用了一个input框,所以关闭或者上传后要清空内容

image-20240409145422610

  1. 点击上传按钮,弹出文件选择器
<el-row type="flex" justify="center">
  <div class="upload-excel">
    <!--文本输入框的类型是file,可以接收的文件类型.xlsx或者.xls-->
    <!--当我们点击“点击上传”按钮后,下面的input框就应该弹出来-->
    <!--有了ref,我们就能获取input框中的DOM对象-->
    <input
      ref="excel-upload-input"
      class="excel-upload-input"
      type="file"
      accept=".xlsx, .xls"
    >
    <div class="drop">
      <i class="el-icon-upload"/>
      <el-button type="text" @click="getTemplate">下载导入模板</el-button>
      <span>将文件拖到此处或
        <el-button type="text" @click="handleUpload">点击上传</el-button>
      </span>
    </div>
  </div>
</el-row>

方法

// 弹出文件选择器 - 只有一种方式,通过input框中的file属性
handleUpload() {
  // input框只要触发了点击事件,就会弹出文件选择器
  this.$refs['excel-upload-input'].click() // 这种写法和this.$refs.属性名是一样的
}

效果

image-20240409150429074

  1. 将文件进行上传

    请求参数如下所示

    现在的参数不是JSON了,而是form-data

image-20240409151519249

api方法

/**
 * 上传Excel接口
 */
export function uploadExcel(data) {
  return request({
    url: '/sys/user/import/template',
    method: 'post',
    // 此处的data是form-data类型,因为要上传文件,不是JSON类型
    data: data
  })
}

按钮

<!--文本输入框的类型是file,可以接收的文件类型.xlsx或者.xls-->
<!--当我们点击“点击上传”按钮后,下面的input框就应该弹出来-->
<!--有了ref,我们就能获取input框中的DOM对象-->
<!--当我们选择上传文件后,就会触发@change事件-->
<input
  ref="excel-upload-input"
  class="excel-upload-input"
  type="file"
  accept=".xlsx, .xls"
  @change="uploadChange"
>

方法

// 当触发@change事件的时候,会传过来一个event
// event.target是事件源,也就是我们的input
// 在event.target对象中,有一个files数组,数组中的每一个对象都是一个file对象
async uploadChange(event) {
  const files = event.target.files // input的文件列表
  // 判断文件的长度,没有的话就不上传了
  if (files.length > 0) {
    // 调用上传接口
    // 参数是form-data类型,需要文件file
    const data = new FormData()
    // files[0] 文件
    data.append('file', files[0]) // 将文件的参数加入到form-data中
    try {
      await uploadExcel(data)
      // 此时一定是响应成功的,成功之后要重新加载数据(重新加载index页面的数据,并不是这个组件的)
      this.$emit('uploadSuccess')// 通知父组件,上传成功
      // 关闭弹层
      this.$emit('update:showExcelDialog', false)
      // 清空文件选择器
      // this.$refs['excel-upload-input'].value = ''
    } catch (error) {
      // 捕获失败
      // 清空文件选择器
      // this.$refs['excel-upload-input'].value = ''
    } finally {
      // 清空文件选择器
      this.$refs['excel-upload-input'].value = ''
    }
  }
}

image-20240409190321436

index页面中的组件

<!--放置导入Excel组件-->
<!--sync修饰符,我们点击关闭弹层或者取消的时候,会自然的把父组件的值改掉-->
<!--@uploadSuccess 表示监听子组件的uploadSuccess,监听到就重新加载页面数据-->
<import-excel :show-excel-dialog.sync="showExcelDialog" @uploadSuccess="getEmployeeList"></import-excel>

三、删除员工

image-20240409203535656

如下图所示

image-20240409193027926

流程如下所示

image-20240409203507745

  1. 按钮
<el-table-column label="操作" width="280px">
  <!--插槽-->
  <template v-slot="{row}">
    <!--type="text"表示按钮是链接的形式-->
    <el-button size="mini" type="text">查看</el-button>
    <el-button size="mini" type="text">角色</el-button>
    <!--气泡确认框-->
    <!--点击确认后会执行 @onConfirm-->
    <el-popconfirm title="这段内容确定要删除吗?" @onConfirm="confirmDel(row.id)">
      <el-button slot="reference" style="margin-left: 10px" size="mini" type="text">删除</el-button>
    </el-popconfirm>
  </template>
</el-table-column>
  1. api方法
/**
 * 删除员工的接口
 */
export function delEmployee(id) {
  return request({
    url: `/sys/user/${id}`,
    method: 'delete'
  })
}
  1. 方法
async confirmDel(id) {
  await delEmployee(id)
  // 判断是不是当前页的最后一个
  if (this.list.length === 1 && this.queryParams.page > 1) {
    this.queryParams.page--
  }
  // 重新获取部门数据
  getEmployeeList()
  this.$message.success('删除用户成功')
}
argin-left: 10px" size="mini" type="text">删除</el-button>
    </el-popconfirm>
  </template>
</el-table-column>

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

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

相关文章

力扣HOT100 - 234. 回文链表

解题思路&#xff1a; class Solution {public boolean isPalindrome(ListNode head) {List<Integer> list new ArrayList<Integer>();// 将链表的值复制到数组中ListNode cur head;while (cur ! null) {list.add(cur.val);cur cur.next;}// 使用双指针判断是否…

力扣hot100:136. 只出现一次的数字 及其衍生

文章目录 一、LeetCode&#xff1a;136. 只出现一次的数字 使用到的异或运算的特点&#xff1a; 两个相同的数异或&#xff0c;结果为0 一、LeetCode&#xff1a;136. 只出现一次的数字 LeetCode&#xff1a;136. 只出现一次的数字 这里数组nums的特点是&#xff0c;除了一…

线程控制及线程底层原理

thread id 本质是一个地址。 以十六机制打印id。 线程终止的两种方法。 1.直接return&#xff1b; 2.pthread_exit(); 注意exit()是用来终止进程的&#xff0c;不能用于线程。 那怎么获取线程的返回值呢&#xff1f; 首先&#xff0c;和进程一样&#xff0c;线程退出也需要…

Python 入门指南(一)

原文&#xff1a;zh.annas-archive.org/md5/97bc15629f1b51a0671040c56db61b92 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 这个学习路径帮助你在 Python 的世界中感到舒适。它从对 Python 的全面和实用的介绍开始。你将很快开始在学习路径的第一部分编写程序…

2024年阿里云4核8G配置云服务器价格低性能高!

阿里云4核8G服务器租用优惠价格700元1年&#xff0c;配置为ECS通用算力型u1实例&#xff08;ecs.u1-c1m2.xlarge&#xff09;4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选&#xff0c;CPU采用Intel(R) Xeon(R) Platinum处理器&#xff0c;阿里云优惠 aliyunfuwuqi…

基于docker的Jenkin的服务平台搭建

项目拓扑图 项目环境: jenkins-2.440 sonarqube-9.9.4 apache-maven-3.9.6 gitlab-ce-12.4.2 java17 docker20 harbor.v2.6.0 centos7.9 项目目的: 模拟企业构建一个流行的持续集成和持续部署环境,可以更轻松地创建和管理构建环境&#xff0c;实现自动化构建和部署应用程序的…

大模型开发轻松入门——(1)从搭建自己的环境开始

pip install openai import openai import osfrom dotenv import load_dotenv, find_dotenv _ load_dotenv(find_dotenv())openai.api_key os.getenv(OPENAI_API_KEY)

3d模型怎么全是网格?---模大狮模型网

在进行3D建模或场景设计时&#xff0c;有时会遇到一个普遍问题&#xff0c;即所见的3D模型表面全是由网格组成&#xff0c;而没有显示实际的表面纹理或颜色。这可能会导致困惑和挫败感&#xff0c;阻碍项目的进展。本文将深入探讨这一现象背后的原因&#xff0c;并提供多种解决…

2024九章云极DataCanvas智算操作系统新品发布会震撼来袭!

从大模型到智能算力&#xff0c;从“数字中国”到“新质生产力”……在技术突破和时代引领双轮驱动下&#xff0c;人工智能技术应用不断刷新全社会的认知&#xff0c;人工智能产业机遇席卷而来、发展将颠覆想象。随着AIGC和大模型的快速发展&#xff0c;建设拥有“卓越算力”和…

Chrome修改主题颜色

注意&#xff1a;自定义Chrome按钮只在搜索引擎为Google的时候出现。

如何鉴别品深茶叶的真伪?

鉴别品深茶叶的真伪可以通过以下三点进行判断&#xff1a;第一是看&#xff0c;观察茶叶的颜色和形状是否自然&#xff1b;第二是闻&#xff0c;感受茶叶的香气是否纯净&#xff1b;第三是泡&#xff0c;品尝茶汤的味道是否醇厚。最好的方式还是通过官方访问进行查询&#xff0…

Linux系统——Elasticsearch企业级日志分析系统

目录 前言 一、ELK概述 1.ELK简介 2.ELK特点 3.为什么要使用ELK 4.完整日志系统基本特征 5.ELK工作原理 6.Elasticsearch介绍 6.1Elasticsearch概述 6.2Elasticsearch核心概念 7.Logstash介绍 7.1Logstash简介 7.2Logstash主要组件 8.Kibana介绍 8.1Kibana简介 …

划重点!免费SSL证书要慎用

HTTPS协议逐渐成为当下网络传输协议的主流方式&#xff0c;这一点为人共知&#xff0c;也正是基于这一点&#xff0c;SSL证书的使用越来越被网站所接受。同时&#xff0c;SSL证书市场产品种类繁多&#xff0c;从免费版本到价格不等的收费版都有&#xff0c;不少用户考虑成本等因…

【网络编程】web服务器shttpd源码剖析——命令行和文件配置解析

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的网络编程系列之web服务器shttpd源码剖析——命令行解析&#xff0c;在这篇文章中&#xff0c;你将会学习到在Linux内核中如何创建一个自己的并发服务器shttpd&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘…

QTableWidget的使用案例

QTableWidget的使用案例 创建QTableWidget m_table_widget new QTableWidget(this);m_table_widget->setObjectName("TableWidget");m_table_widget->setShowGrid(false);m_table_widget->setSortingEnabled(true);m_table_widget->setEditTriggers(QAb…

EcoVadis评估是什么?EcoVadis评估的步骤有哪些

EcoVadis评估是一种针对供应链中各个环节的环境和社会责任进行评估的工具。其评估范围广泛&#xff0c;涵盖了环境、劳工与人权、商业道德和可持续采购等多个领域。通过收集企业的公开信息、企业提供的数据和自我评估问卷等方式&#xff0c;EcoVadis能够为企业提供一个全面的可…

C++ 之 newmat 矩阵运算库使用笔记

文章目录 Part.I IntroductionChap.I newmat 简介 Part.II 安装与编译Chap.I 直接使用源码Chap.II 基于 CMake 使用源码Chap.III 编译成库 Part.III 关于矩阵的构造与运算Chap.I 矩阵的构造与初始化Chap.II 矩阵的运算Chap.III 矩阵维数和类型的更改Chap.IV 矩阵最值统计 Refer…

Spring容器结构

文章目录 1.基本介绍1.Spring5官网2.API文档3.Spring核心学习内容4.几个重要概念 2.快速入门1.需求分析2.入门案例1.新建Java项目2.导入jar包3.编写Monster.java4.src下编写Spring配置文件1.创建spring配置文件&#xff0c;名字随意&#xff0c;但是需要放在src下2.创建Spring …

蓝桥杯(基础题)

试题 C: 好数 时间限制 : 1.0s 内存限制: 256.0MB 本题总分&#xff1a;10 分 【问题描述】 一个整数如果按从低位到高位的顺序&#xff0c;奇数位&#xff08;个位、百位、万位 &#xff09;上 的数字是奇数&#xff0c;偶数位&#xff08;十位、千位、十万位 &…

张大哥笔记:电脑周边的10大刚需创业小项目

hello&#xff0c;大家好&#xff0c;我是张大哥&#xff0c;今天一口气给大家分享围绕电脑周边的10大刚需创业小项目&#xff0c;本文章旨在帮助大家如何快速切入到细分领域里面搞钱&#xff01; 如何赚钱&#xff0c;无非就是解决人群痛点&#xff0c;你要懂得根据用户痛点去…