vue项目中如何使用excel导入导出

vue项目中如何使用excel导入导出

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

导入

安装依赖

安装插件

npm install xlsx

引入组件

将vue-element-admin提供的组件复制到我们自己的项目 **src/components/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')
    }]
}

测试路由结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-geLsuA7b-1629724067018)(解决跨域的几种方法.assets/image-20210823205507375.png)]

测试导入效果

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

按要求处理数据

处理内容包含:

  • 字段中文转英文。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数据日期不准确处理

// 把excel文件中的日期格式的内容转回成标准时间
// https://blog.csdn.net/qq_15054679/article/details/107712966
export function formatExcelDate(numb, format = '/') {
  const time = new Date((numb - 25567) * 24 * 3600000 - 5 * 60 * 1000 - 43 * 1000 - 24 * 3600000 - 8 * 3600000)
  time.setYear(time.getFullYear())
  const year = time.getFullYear() + ''
  const month = time.getMonth() + 1 + ''
  const date = time.getDate() + ''
  if (format && format.length === 1) {
    return year + format + month + format + date
  }
  return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)
}

更新格式转换函数

import { formatExcelDate } from '@/utils/index.js'

// 更新格式转换函数
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]
+          if (enKey === 'timeOfEntry' || enKey === 'correctionTime') {
            // 后端需要的日期格式是标准时间
+            enObj[enKey] = new Date(formatExcelDate(zhObj[zhKey]))
          } else {
            enObj[enKey] = zhObj[zhKey]
          }
        })

        return enObj
      })
    }

调用接口读入文件

定义接口api

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

在页面中使用

导入API

封装doImport

import { importEmployee } from '@/api/employees'

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)
  }

导出

  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中的src/vendor/export2Excel复制到项目中,直接使用

给导出注册点击事件

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' // 生成的文件类型
  })
})

Excel导出参数说明

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

处理数据

formatData(list) {
      const map = {
        'id': '编号',
        'password': '密码',
        'mobile': '手机号',
        'username': '姓名',
        'timeOfEntry': '入职日期',
        'formOfEmployment': '聘用形式',
        'correctionTime': '转正日期',
        'workNumber': '工号',
        'departmentName': '部门',
        'staffPhoto': '头像地址'
      }
      console.log(list)
      let header = []
      // header = ['id', 'mobile', 'username', .....]
      // data = [
      //     ['65c2', '1380000002', '管理员', ....],
      //     ['65c3', '1380000003', '孙财', ....],
      // ]
      let data = []
      // 开始代码
      // 找到一个元素
      const one = list[0]
      if (!one) {
        return { header, data }
      }
      header = Object.keys(one).map(key => {
        return map[key]
      })

      // data把list中每一个对象转成 对应的value数组
      data = list.map(obj => {
        // 把  Obj['formOfEmployment']: 1 , 2   ---> '正式', '非正式'
        const key = obj['formOfEmployment'] // 1, 2
        obj['formOfEmployment'] = hireTypEnmu[key] // hireTypEnmu:{1:'正式', '2':'非正式' }

        return Object.values(obj)
      })

      return { header, data }
    },
hExport() {
      import('@/vendor/Export2Excel').then(async excel => {
        // 发ajax请求,获取数据
        const res = await getEmployee(this.page, this.size)
        const list = res.data.rows
        console.log('从后端获取的数据', list)

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

你可能感兴趣的:(element,vue,vue,javascript,js)