文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue-element-admin项目导入和导出的实现方法

2023-06-15 04:37

关注

这篇文章给大家分享的是有关vue-element-admin项目导入和导出的实现方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

vue-element-admin导入组件封装

模板和样式

vue-element-admin项目导入和导出的实现方法

首先封装一个类似的组件,首先需要注意的是,类似功能,vue-element-admin已经提供了,我们只需要改造即可
excel导入功能需要使用npm包xlsx,所以需要安装xlsx插件

npm i xlsx

将vue-element-admin提供的导入功能新建一个组件,位置: src/components/UploadExcel

import CommonTools from './CommonTools'import UploadExcel from './UploadExcel'export default {  install(Vue) {    Vue.component('CommonTools', CommonTools) // 注册工具栏组件    Vue.component('UploadExcel', UploadExcel) // 注册导入excel组件  }}

修改样式和布局

<template>  <div class="upload-excel">    <div class="btn-upload">      <el-button :loading="loading" size="mini" type="primary" @click="handleUpload">        点击上传      </el-button>    </div>    <input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">    <div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">      <i class="el-icon-upload" />      <span>将文件拖到此处</span>    </div>  </div></template><script>import XLSX from 'xlsx'export default {  props: {    beforeUpload: Function, // eslint-disable-line    onSuccess: Function// eslint-disable-line  },  data() {    return {      loading: false,      excelData: {        header: null,        results: null      }    }  },  methods: {    generateData({ header, results }) {      this.excelData.header = header      this.excelData.results = results      this.onSuccess && this.onSuccess(this.excelData)    },    handleDrop(e) {      e.stopPropagation()      e.preventDefault()      if (this.loading) return      const files = e.dataTransfer.files      if (files.length !== 1) {        this.$message.error('Only support uploading one file!')        return      }      const rawFile = files[0] // only use files[0]      if (!this.isExcel(rawFile)) {        this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files')        return false      }      this.upload(rawFile)      e.stopPropagation()      e.preventDefault()    },    handleDragover(e) {      e.stopPropagation()      e.preventDefault()      e.dataTransfer.dropEffect = 'copy'    },    handleUpload() {      this.$refs['excel-upload-input'].click()    },    handleClick(e) {      const files = e.target.files      const rawFile = files[0] // only use files[0]      if (!rawFile) return      this.upload(rawFile)    },    upload(rawFile) {      this.$refs['excel-upload-input'].value = null // fix can't select the same excel      if (!this.beforeUpload) {        this.readerData(rawFile)        return      }      const before = this.beforeUpload(rawFile)      if (before) {        this.readerData(rawFile)      }    },    readerData(rawFile) {      this.loading = true      return new Promise((resolve, reject) => {        const reader = new FileReader()        reader.onload = e => {          const data = e.target.result          const workbook = XLSX.read(data, { type: 'array' })          const firstSheetName = workbook.SheetNames[0]          const worksheet = workbook.Sheets[firstSheetName]          const header = this.getHeaderRow(worksheet)          const results = XLSX.utils.sheet_to_json(worksheet)          this.generateData({ header, results })          this.loading = false          resolve()        }        reader.readAsArrayBuffer(rawFile)      })    },    getHeaderRow(sheet) {      const headers = []      const range = XLSX.utils.decode_range(sheet['!ref'])      let C      const R = range.s.r            for (C = range.s.c; C <= range.e.c; ++C) {         const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]                let hdr = 'UNKNOWN ' + C // <-- replace with your desired default        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)        headers.push(hdr)      }      return headers    },    isExcel(file) {      return /\.(xlsx|xls|csv)$/.test(file.name)    }  }}</script><style scoped lang="scss">.upload-excel {  display: flex;  justify-content: center;   margin-top: 100px;   .excel-upload-input{       display: none;        z-index: -9999;     }   .btn-upload , .drop{      border: 1px dashed #bbb;      width: 350px;      height: 160px;      text-align: center;      line-height: 160px;   }   .drop{       line-height: 80px;       color: #bbb;      i {        font-size: 60px;        display: block;      }   }}</style>

创建路由和组件

建立公共导入的页面路由,新建一个公共的导入页面,挂载路由 src/router/index.js

path: '/import',    component: Layout,    hidden: true, // 隐藏在左侧菜单中    children: [{      path: '', // 二级路由path什么都不写 表示二级默认路由      component: () => import('@/views/import')    }]  },

创建import路由组件 src/views/import/index.vue

<template>  <!-- 公共导入组件 -->   <upload-excel :on-success="success" /></template>

实现导入

封装导入用户的api接口

export function importUser(data) {  return request({    url: 'user/batch',    method: 'post',    data  })}

获取导入的excel数据, 导入excel接口

 async  success({ header, results }) {      // 如果是导入用户        const userRelations = {          '入职日期': 'create_time',          '手机号': 'mobile',          '用户名': 'username',          '密码': 'password',          '邮箱': 'email',          '部门':'部门'        }        const arr = []       results.forEach(item => {          const userInfo = {}          Object.keys(item).forEach(key => {            userInfo[userRelations[key]] = item[key]          })         arr.push(userInfo)         })        await importUser(arr) // 调用导入接口        this.$router.back()    }

为了让这个页面可以服务更多的导入功能,我们可以在页面中用参数来判断,是否是导入用户

 data() {    return {      type: this.$route.query.type    }  },

当excel中有日期格式的时候,实际转化的值为一个数字,我们需要一个方法进行转化

formatDate(numb, format) {      const time = new Date((numb - 1) * 24 * 3600000 + 1)      time.setYear(time.getFullYear() - 70)      const year = time.getFullYear() + ''      const month = time.getMonth() + 1 + ''      const date = time.getDate() - 1 + ''      if (format && format.length === 1) {        return year + format + month + format + date      }      return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)    }

导入的手机号不能和之前的存在的手机号重复

逻辑判断

 async  success({ header, results }) {      if (this.type === 'user') {        const userRelations = {          '入职日期': 'create_time',          '手机号': 'mobile',          '用户名': 'username',          '密码': 'password',          '邮箱': 'email',          '部门':'部门'        }        const arr = []        // 遍历所有的数组        results.forEach(item => {        // 需要将每一个条数据里面的中文都换成英文          const userInfo = {}          Object.keys(item).forEach(key => {          // key是当前的中文名 找到对应的英文名            if (userRelations[key] === 'timeOfEntry' || userRelations[key] === 'correctionTime') {              userInfo[userRelations[key]] = new Date(this.formatDate(item[key], '/')) // 只有这样, 才能入库              return            }            userInfo[userRelations[key]] = item[key]          })          // 最终userInfo变成了全是英文          arr.push(userInfo)        })        await importUser(arr)        this.$message.success('导入成功')      }      this.$router.back() // 回到上一页    },    formatDate(numb, format) {      const time = new Date((numb - 1) * 24 * 3600000 + 1)      time.setYear(time.getFullYear() - 70)      const year = time.getFullYear() + ''      const month = time.getMonth() + 1 + ''      const date = time.getDate() - 1 + ''      if (format && format.length === 1) {        return year + format + month + format + date      }      return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)    }

用户页面跳转

<el-button type="warning" size="small" @click="$router.push('/import?type=user')">导入</el-button>

用户导出**

日常业务中,我们经常遇到excel导出功能, 怎么使用呢
Excel 的导入导出都是依赖于js-xlsx来实现的。
在 js-xlsx的基础上又封装了Export2Excel.js来方便导出数据。

安装所需依赖

npm install xlsx file-saver -Snpm install script-loader -S -D

由于js-xlsx体积还是很大的,导出功能也不是一个非常常用的功能,所以使用的时候建议使用懒加载。使用方法如下:

import('@/vendor/Export2Excel').then(excel => {  excel.export_json_to_excel({    header: tHeader, //表头 必填    data, //具体数据 必填    filename: 'excel-list', //非必填    autoWidth: true, //非必填    bookType: 'xlsx' //非必填  })})

excel导出参数的介绍

vue-element-admin提供了导出的功能模块,在课程资源/excel导出目录下,放置到src目录下

vue-element-admin项目导入和导出的实现方法

excel导出基本的结构

下面代码会用到 Export2Excel.js 模块,所以首先在 src 目录下新建 vendor 目录,其中新建 Export2Excel.js ,输入如下代码

import { saveAs } from 'file-saver'import XLSX from 'xlsx'function generateArray(table) {  var out = [];  var rows = table.querySelectorAll('tr');  var ranges = [];  for (var R = 0; R < rows.length; ++R) {    var outRow = [];    var row = rows[R];    var columns = row.querySelectorAll('td');    for (var C = 0; C < columns.length; ++C) {      var cell = columns[C];      var colspan = cell.getAttribute('colspan');      var rowspan = cell.getAttribute('rowspan');      var cellValue = cell.innerText;      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;      //Skip ranges      ranges.forEach(function (range) {        if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {          for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);        }      });      //Handle Row Span      if (rowspan || colspan) {        rowspan = rowspan || 1;        colspan = colspan || 1;        ranges.push({          s: {            r: R,            c: outRow.length          },          e: {            r: R + rowspan - 1,            c: outRow.length + colspan - 1          }        });      };      //Handle Value      outRow.push(cellValue !== "" ? cellValue : null);      //Handle Colspan      if (colspan)        for (var k = 0; k < colspan - 1; ++k) outRow.push(null);    }    out.push(outRow);  }  return [out, ranges];};function datenum(v, date1904) {  if (date1904) v += 1462;  var epoch = Date.parse(v);  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);}function sheet_from_array_of_arrays(data, opts) {  var ws = {};  var range = {    s: {      c: 10000000,      r: 10000000    },    e: {      c: 0,      r: 0    }  };  for (var R = 0; R != data.length; ++R) {    for (var C = 0; C != data[R].length; ++C) {      if (range.s.r > R) range.s.r = R;      if (range.s.c > C) range.s.c = C;      if (range.e.r < R) range.e.r = R;      if (range.e.c < C) range.e.c = C;      var cell = {        v: data[R][C]      };      if (cell.v == null) continue;      var cell_ref = XLSX.utils.encode_cell({        c: C,        r: R      });      if (typeof cell.v === 'number') cell.t = 'n';      else if (typeof cell.v === 'boolean') cell.t = 'b';      else if (cell.v instanceof Date) {        cell.t = 'n';        cell.z = XLSX.SSF._table[14];        cell.v = datenum(cell.v);      } else cell.t = 's';      ws[cell_ref] = cell;    }  }  if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);  return ws;}function Workbook() {  if (!(this instanceof Workbook)) return new Workbook();  this.SheetNames = [];  this.Sheets = {};}function s2ab(s) {  var buf = new ArrayBuffer(s.length);  var view = new Uint8Array(buf);  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;  return buf;}export function export_table_to_excel(id) {  var theTable = document.getElementById(id);  var oo = generateArray(theTable);  var ranges = oo[1];    var data = oo[0];  var ws_name = "SheetJS";  var wb = new Workbook(),    ws = sheet_from_array_of_arrays(data);    // ws['!cols'] = ['apple', 'banan'];  ws['!merges'] = ranges;    wb.SheetNames.push(ws_name);  wb.Sheets[ws_name] = ws;  var wbout = XLSX.write(wb, {    bookType: 'xlsx',    bookSST: false,    type: 'binary'  });  saveAs(new Blob([s2ab(wbout)], {    type: "application/octet-stream"  }), "test.xlsx")}export function export_json_to_excel({  multiHeader = [],  header,  data,  filename,  merges = [],  autoWidth = true,  bookType = 'xlsx'} = {}) {    filename = filename || 'excel-list'  data = [...data]  data.unshift(header);  for (let i = multiHeader.length - 1; i > -1; i--) {    data.unshift(multiHeader[i])  }  var ws_name = "SheetJS";  var wb = new Workbook(),    ws = sheet_from_array_of_arrays(data);  if (merges.length > 0) {    if (!ws['!merges']) ws['!merges'] = [];    merges.forEach(item => {      ws['!merges'].push(XLSX.utils.decode_range(item))    })  }  if (autoWidth) {        const colWidth = data.map(row => row.map(val => {            if (val == null) {        return {          'wch': 10        };      }            else if (val.toString().charCodeAt(0) > 255) {        return {          'wch': val.toString().length * 2        };      } else {        return {          'wch': val.toString().length        };      }    }))        let result = colWidth[0];    for (let i = 1; i < colWidth.length; i++) {      for (let j = 0; j < colWidth[i].length; j++) {        if (result[j]['wch'] < colWidth[i][j]['wch']) {          result[j]['wch'] = colWidth[i][j]['wch'];        }      }    }    ws['!cols'] = result;  }    wb.SheetNames.push(ws_name);  wb.Sheets[ws_name] = ws;  var wbout = XLSX.write(wb, {    bookType: bookType,    bookSST: false,    type: 'binary'  });  saveAs(new Blob([s2ab(wbout)], {    type: "application/octet-stream"  }), `${filename}.${bookType}`);}

因为数据中的key是英文,想要导出的表头是中文的话,需要将中文和英文做对应

 const headers = {        '入职日期': 'create_time',        '手机号': 'mobile',        '用户名': 'username',        '角色': 'role_name',        '邮箱': 'email',        '部门': 'department_name'      }

完成导出代码

import { formatDate } from '@/filters'// 导出数据    exportData() {      const headers = {        '入职日期': 'create_time',        '手机号': 'mobile',        '用户名': 'username',        '角色': 'role_name',        '邮箱': 'email',        '部门': 'department_name'      }      import('@/vendor/Export2Excel').then(async excel => {        const res = await getUserList({ query: '', pagenum: 1, pagesize: this.page.total })        // console.log(res)        const data = this.formatJson(headers, res.users)        console.log(data)        excel.export_json_to_excel({          header: Object.keys(headers),          data,          filename: '用户信息表',          autoWidth: true,          bookType: 'xlsx'        })      })    }        }

导出时间格式的处理

   // 该方法负责将数组转化成二维数组    formatJson(headers, rows) {      return rows.map(item => {        return Object.keys(headers).map(key => {          if (headers[key] === 'create_time') {            return formatDate(item[headers[key]]) // formatDate 函数是定义好的一个过滤器          }          return item[headers[key]]        })      })

过滤器 formatDate

import moment from 'moment'export function formatTime(value) {  return moment(value * 1000).format('YYYY-MM-DD HH:mm:ss')}export function formatDate(value) {  return moment(value * 1000).format('YYYY-MM-DD')}

为什么要使用Vue

Vue是一款友好的、多用途且高性能的JavaScript框架,使用vue可以创建可维护性和可测试性更强的代码库,Vue允许可以将一个网页分割成可复用的组件,每个组件都包含属于自己的HTML、CSS、JavaScript,以用来渲染网页中相应的地方,所以越来越多的前端开发者使用vue。

感谢各位的阅读!关于“vue-element-admin项目导入和导出的实现方法”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯