Vue项目中使用xlsx实现批量导入导出功能

Vue项目之—使用xlsx实现批量导入导出功能

安装 xlsx
  • npm i xlsx

导入

封装导入组件
改造 vue-element-admin(点击复制UploadExcel组件代码)
  • 封装成一个全局组件 src/components/UploadExcel
注册全局导入组件
// src/component/index.js
import UploadExcel from './UploadExcel'
export default {
  install(Vue) {
    Vue.component('UploadExcel', UploadExcel) // 注册导入excel组件
  }
}

// main.js
import Component from '@/component'
Vue.use(Component)
利用element-ui修改样式和布局
<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>
<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>
实现导入excel的功能:
  1. 创建 import 组件 views/import/index.vue
  2. 建立公共导入的页面路由
    {
        path: '/import',
        component: Layout,
        hidden: true, // 隐藏在左侧菜单中
        children: [{
          path: '', // 二级路由path什么都不写 表示二级默认路由
          component: () => import('@/views/import')
        }]
      },
    
  3. 封装导入数据的api接口
  4. 实现excel导入
    • import组件中获取导入的 excel 数据,导入 excel接口
      • success({result})
    • 为了让这个页面可以服务更多的导入功能,我们可以在页面中用参数来判断,是否是导入员工
      • @click="$router.push('/import?type=order')"(使用)
      • type: this.$route.query.type
    • 中英文对照
      • Object.keys(userRelations)
    实现代码:
    // views/import/index.vue
    
    async success({ results }) {
      const arr = results.map(item => this.zhToEn(item, this.type))
      await importOrder(arr)
      this.$message.success('导入数据成功!')
      this.$router.back() // 回到上一页
    },
        
    zhToEn(zhs, type) {
      const orderInfo = {}
      if (type === 'order') {
        const orderRelations = {
          订单量: 'orderVol',
          订单号: 'orderNum',
          名称: 'orderName',
          签订日期: 'signTime',
          ...
        }
        Object.keys(zhs).map(item => {
          console.log(item)
          const value = orderRelations[item]
          if (value === 'signTime' || value === 'xxTime') {
            console.log(1111)
            // 因为 Excel 存储的日期是从 1900 年 1 月 1 日开始按天数来计算的,也就是说 1900 年 1 月 1 日在 Excel 中是 1。
            // 因此我们需要对时间进行格式化
           orderInfo[value] = this.formatExcelDate(zhs[item])
          } else {
          orderInfo[value] = zhs[item]
          }
        })
        return orderInfo
      }
    },
    
    formatExcelDate(num, format = '-') {
      if (!/^\d+$/.test(num)) return
      num = parseInt(num)
      let millisecond = 0 // 转化后的毫秒数
      if (num > 60) {
        // 对大于 60 的日期进行减 1 处理
        millisecond = (num - 25568 - 1) * 3600 * 24 * 1000
      } else {
        millisecond = (num - 25568) * 3600 * 24 * 1000
      }
      const date = new Date(millisecond) // 根据转化后的毫秒数获取对应的时间
      const yy = date.getFullYear()
      const m = date.getMonth() + 1
      const mm = m >= 10 ? m : '0' + m
      const d = date.getDate()
      const dd = d >= 10 ? d : '0' + d
      return yy + format + mm + format + dd // 返回格式化后的日期
    }
    
    
    
    
    
    
    

导出

  1. 安装excel所需依赖
    npm install xlsx file-saver -S
    npm install script-loader -S -D
    
  2. 基本数据
    • 因为数据中的key是英文,想要导出的表头是中文的话,需要将中文和英文做对应
      • const headers = {'手机号':'mobile',...}
      • const { rows } = await getEmployeeList({ page: 1, size: this.page.total })
  3. 书写按需格式化函数
    • formatJson(headers, rows)
      • 该方法负责将数组转化成二维数组
      • 映射中英文
    • formatDate
      • 格式化时间
      • import { formatDate } from '@/filters/index'
  4. excel导出基本的结构
    import('@/vendor/Export2Excel').then(excel => {
      excel.export_json_to_excel({
       header: Object.keys(headers), //表头 必填 Array
       data, //具体数据 必填 Array
       filename: 'excel-list', //导出文件名 非必填
       autoWidth: true, //单元格是否要自适应宽度非必填
       bookType: 'xlsx' //导出文件类型 非必填
      })
    })
    
  5. 复杂表头的导出
实现代码:
exportFn() {
  const headers = {
    订单量: 'orderVol',
    订单号: 'orderNum',
    名称: 'orderName',
    签订日期: 'signTime',
  }
  // 导出 excel
  import('@/vendor/Export2Excel').then(async excel => {
    //  excel 是引入文件的导出对象
    // 导出  header 从哪里来
    // data 从哪里来
    // 现在没有一个接口获取所有的数据
    // 获取订单的接口 页码 每页条数    100   1 10000
    const { rows } = await getOrderList({ page: 1, size: this.page.total })
    const data = this.formatJson(headers, rows) // 返回的 data 就是 要导出的结构
    const multiHeader = [['订单量', '订单号', '', '', '', '', '名称']]
    const merges = ['A1:A2', 'B1:F1', 'G1:G2']
    excel.export_json_to_excel({
      header: Object.keys(headers),
      data,
      filename: '订单资料表',
      multiHeader, // 复杂表头
      merges // 合并选项
    })
  })
},
// 将表头数据和数据进行对应
// [{}]  =>   [[]]
formatJson(headers, rows) {
  return rows.map(item => {
    // item 是一个对象  { orderName: 132111,ordername: '小米手机'  }
    // ["订单号", "订单量", "名称" 。。]
    return Object.keys(headers).map(key => {
      // 需要判断 字段
      if (headers[key] === 'signTime' || headers[key] === 'xxTime') {
        // 格式化日期
        return formatDate(item[headers[key]])
      } 
      return item[headers[key]]
    })
    // ["132", '张三’, ‘’,‘’,‘’d]
  })
  // return rows.map(item => Object.keys(headers).map(key => item[headers[key]]))
  // 需要处理时间格式问题
},

❗难点:

难点是导出的时候,需要把请求到的数据转换为xlsx要求的格式才能导出成功;实现批量导入功能的时候,也需要把通过xlsx插件解析好的Excel表格数据转换为接口需要的数据格式

✨比如:批量导入数据时,因为获取到的Excel表格数据字段都是中文名的,但是后端接口需要的是英文名,因此我们把数据通过接口传递给后端之前需要先把数据转换为后端规定的格式,我们的做法是先准备好一个中英文字段对照字典表,然后再根据字典表把Excel表格的中文字段名替换成英文字段名,从而实现数据转换。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wendyymei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值