vue项目中,如何实现excel的导入导出

5,014 阅读6分钟

excel导入功能-组件封装

目标

从vue-element-admin中提供的excel导入功能迁移到当前的项目中

思路

  • 安装包
  • 拷贝组件

安装必要的插件

这个插件叫做xlsx

npm install xlsx -S

引入UploadExcel组件并注册为全局

  • 将vue-element-admin提供的组件复制到我们自己的项目 **src/components/UploadExcel**下
  • 在index.js将它注册成全局组件
import PageTools from './PageTools'
import UploadExcel from './UploadExcel'export default {
  // 插件的初始化, 插件给你提供的全局的功能, 都可以在这里配置
  install(Vue) {
    // 进行组件的全局注册
    Vue.component('PageTools', PageTools) // 注册工具栏组件
    Vue.component('UploadExcel', UploadExcel) // 注册导入excel组件
  }
}

员工管理-excel导入功能-准备页面

目标

根据业务要求,配置一个独立的路由,然后在这个单独的页面中实现员工导入功能

思路

  1. 配置路由
  2. 建立对应的页面,然后在这个页面中引入UploadExcel组件实现导入功能

建立公共导入的页面路由

新建一个公共的导入页面,即import路由组件 src/views/import/index.vue

在页面中使用前面封装的excel上传组件,并补充导入成功后的回调函数

<template>
  <upload-excel :on-success="handleSuccess" />
</template><script>
export default {
  name: 'Import',
  methods: {
    handleSuccess({ header, results }) {
      console.log(header, results)
    }
  }
}
</script>

配置路由

这个路由不需要根据权限控制,直接定义为静态路由即可。在**src/router/index.js**下的静态路由中添加一个路由

{
    path: '/import',
    component: Layout,
    hidden: true, // 不显示到左侧菜单
    children: [{
      path: '', 
      component: () => import('@/views/import')
    }]
}

测试导入效果

点击上传,分析handleSuccess的执行结果

handleSuccess({ header, results }) {
      // header 标题
      //        ['姓名','手机号']
      // results excel表格的内容
      //        [ {'姓名''小张''手机号': '13712345678'}, {.....} ]
      console.log(header, results)
    }

excel导入插件本质:把excel经过分析转换成js能够识别的常规数据,拿到数据我们可以进行任何操作

员工管理-实现excel导入-数据处理

目标

数据格式转换:将excel解析好的数据经过处理后,转成可以传给接口调用的数据

image.png

思路

调用接口进行excel上传的重点其实是数据的处理,我们需要按照接口的要求,把excel表格中经过插件处理好的数据处理成后端接口要求的格式

下面是后端接口要求的示例格式 image.png

按接口要求,处理excel导入的数据

处理内容包含:

  • 字段中文转英文。excel中读入的是姓名,而后端需要的是username
  • 日期处理。从excel中读入的时间是一个number值,而后端需要的是标准日期。

为了方便维护代码,单独封装一个方法来实现这个转换的功能。

/**
     * results excel表格的内容
      // [
          {'姓名':'小张', '手机号': '13712345678'}
        , {.....}
        ]
​
      // 目标
      // [ {'username':'小张','mobile': '13712345678'}, {.....} ]
     */
    // 把一个对象数组中的每个对象的属性名,从中文改成英文
    // 思路:对于原数组每个对象来说
    //    (1) 找出所有的中文key
    //     (2)  得到对应的英文key
    //     (3)  拼接一个新对象: 英文key:值
    transExcel(results) {
      const mapInfo = {
        '入职日期': 'timeOfEntry',
        '手机号': 'mobile',
        '姓名': 'username',
        '转正日期': 'correctionTime',
        '工号': 'workNumber',
        '部门': 'departmentName',
        '聘用形式': 'formOfEmployment'
      }
      return results.map(zhObj => {
        const enObj = {}
        const zhKeys = Object.keys(zhObj) // ['姓名', '手机号']
​
        zhKeys.forEach(zhKey => {
          const enKey = mapInfo[zhKey]
​
          enObj[enKey] = zhObj[zhKey]
        })
​
        return enObj
      })
    }

实现excel导入-封装接口并调用

目标

完成按钮跳转,导入完成(接口调用)之后,再跳回到原来的页面

分析

在页面上,点击了导入之后,做跳转,跳到上传页面;

把接口准备好,

接口api

src/api/employee

/**
 * @description: 导入excel
 * @param {*} data
 * @return {*}
 */
export function importEmployee(data) {
  return request({
    url: '/sys/user/batch',
    method: 'post',
    data
  })
}

在页面中使用

导入API import { importEmployee } from '@/api/employees'

封装doImport

​
   async doImport(data) {
      try {
        const res = await importEmployee(data)
        console.log('importEmployee', res)
        this.$message.success('导入成功')
​
        // 页面后退
        this.$router.back()
      } catch (err) {
        console.log('importEmployee', err)
        this.$message.error('导入失败')
      }
    },
    //  1. 把数据从excel文件读入到浏览器内存
    handleSuccess({ header, results }) {
      console.log(header, results)
​
      // 2. 按接口要求 组装数据
      const data = this.transExcel(results)
      console.log('按接口要求 组装数据', data)
      // 3. 调用接口做上传
      this.doImport(data)
    },

excel导出功能介绍

背景

在表格(element-table)中查询到了我们需要的数据,希望用他们生成excel文件,保存在本地。

思路

前端主导(工作大量在前端)

image.png

  • 取回数据,保存excel文件

后端主导(工作大量在后端)

image.png

  • 前端调用接口

分析vue-element-admin中的导出方案

目标

先去vue-admin中去学习导出功能的用法,并归纳总结把它用到本项目中的步骤

前置工作:这个功能在我们课程一开始学习的vue-element-admin中有现成的功能参考,我们也在项目资源里提供了现成的插件包,大家先把它复制到自己项目的src目录

学习使用现成的excel导出组件

通过路由路径定位到源码位置

image.png 熟悉案例代码

网上示例地址:gitee.com/panjiachen/…

onclick: function (){
  import('@/vendor/Export2Excel').then(excel => {
    const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date']
    const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
    const list = this.list
    const data = this.formatJson(filterVal, list)
    excel.export_json_to_excel({
      header: tHeader,
      data,
      filename: this.filename,
      autoWidth: this.autoWidth,
      bookType: this.bookType
    })
    this.downloadLoading = false
 })
}

具体说明

  1. 插件包位于src/vendor/export2Excel中,采用的是按需引入的方式

    什么时候正式要使用导出功能了,插件才会被正式引入到应用里

    import('@/vendor/Export2Excel').then(excel => {})
    
  2. Export2Excel依赖的包有js-xlsxfile-saverscript-loader

    也就是说,在项目跑起来之前要安装依赖

    npm install file-saver script-loader --save
    

员工导出-基础导出功能实现

目标

把vue-element-admin中的导出功能,迁移本项目

使用静态数据实现基础的导出功能(先不使用从接口获取的数据)

思路

  1. 将vue-element-admin中的src/vendor/export2Excel复制到本项目中,直接使用
  2. 在项目中安装依赖
npm install file-saver script-loader xlsx --save

给导出按钮添加点击事件

回调函数内容如下

import('@/vendor/Export2Excel').then(excel => {
  // excel表示导入的模块对象
  console.log(excel)
  excel.export_json_to_excel({
    header: ['姓名', '工资'], // 表头 必填
    data: [
      ['刘备', 100],
      ['关羽', 500]
    ], // 具体数据 必填
    filename: 'excel-list', // 文件名称
    autoWidth: true, // 宽度是否自适应
    bookType: 'xlsx' // 生成的文件类型
  })
})

以上代码表示:

  1. 当我们正式点击导出按钮之后,才去加载vendor文件夹中的Export2Excel模块
  2. import方法执行完毕返回的是一个promise对象,在then方法中我们可以拿到使用的模块对象
  3. 重点关注data的配置部分,我们发现它需要一个严格的二维数组

Excel导出参数说明

参数说明类型可选值默认值
header导出数据的表头Array/[]
data导出的具体数据Array/[[]]
filename导出文件名String/excel-list
autoWidth单元格是否要自适应宽度Booleantrue / falsetrue
bookType导出文件类型Stringxlsx, csv, txt, morexlsx