vue 导出 - element - xlsx

2 篇文章 0 订阅
2 篇文章 1 订阅

前言

星期6,把没更完的继续更,把最近项目中的导入拿了出来,写了一个小Demo,方便大家直接使用

导出总结

说起导出,很多的后台管理里面都有,****** 什么一键导入,一键导出啊。可怜的开发仔,小丑竟是我自己

话不多说,先看电视

  • 项目业务:导入存本地,导出从本地拿

在这里插入图片描述

这里用到了 element 的上传组件,如果你也是,直接拿走

导入看上集<<<<<<<<<<

安装

npm install xlsx

上传的页面,如果你使用的是 element 的直接拷贝,小白可以看有每一步的注释

<template>
  <div class="container">
    <!-- 上传文件按钮 -->
    <div class="buttonBox">
      <router-link to="/upload">
        <el-tooltip content="数据采集页面" placement="top">
          <el-button type="primary" icon="el-icon-edit" circle></el-button>
        </el-tooltip>
      </router-link>
    </div>

    <!-- 搜索区域 -->
    <div class="searchBox">
      <el-input
        v-model="search"
        placeholder="基于姓名、手机号模糊搜索"
        @change="searchHandle"
        clearable
      ></el-input>
      <el-button type="success" @click="submit" :disabled="disabled"
        >导出选中的数据</el-button
      >
    </div>

    <!-- 列表区域 -->
    <div class="tableBox">
      <el-table
        :data="tableData"
        :height="height"
        border
        style="width: 100%"
        v-loading="loading"
        element-loading-text="主人,奴家正在努力加载中..."
        @selection-change="selectionChange"
      >
        <el-table-column
          type="selection"
          width="50"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="id"
          label="编号"
          min-width="10%"
        ></el-table-column>
        <el-table-column
          prop="name"
          label="姓名"
          min-width="20%"
        ></el-table-column>
        <el-table-column
          prop="phone"
          label="电话"
          min-width="20%"
        ></el-table-column>
        <el-table-column
          prop="time"
          label="创建时间"
          min-width="25%"
          :formatter="formatter"
        ></el-table-column>
      </el-table>
    </div>

    <!-- 分页区域 -->
    <div class="pageBox">
      <el-pagination
        background
        hide-on-single-page
        layout="total,sizes,prev,pager,next"
        :page-size="pageSize"
        :current-page="page"
        :total="total"
        @size-change="sizeChange"
        @current-change="prevNext"
        @prev-click="prevNext"
        @next-click="prevNext"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
import xlsx from 'xlsx' // 引入安装的xlsx
import { Loading } from 'element-ui' // 引入服务
import { formatTime } from '../assets/js/utils' // 引入封装的格式化时间方法
export default {
  name: 'Home',
  data() {
    return {
      tableData: [], // 进入页面时表格的显示数据
      loading: false, // 默认不加载
      height: document.documentElement.clientHeight - 120,
      // 分页相关
      pageSize: 20,
      page: 1,
      total: 10,
      search: '', // 搜索默认是空
      // 选中数据
      selectionList: [], // 复选框选中的数据
      disabled: false // 按钮默认状态
    }
  },
  created() {
    this.queryData() // 进入页面,请求接口拿到表单数据
  },
  methods: {
    // 权限
    selectionChange(val) { // element的选中复选框的回调
      this.selectionList = val // 拿到选中的数据
    },
    // 格式化
    formatter(row, col, val) { // 格式化日期 去看方法
      return formatTime(val, '{0}-{1}-{2} {3}:{4}:{5}')
    },
    // 获取数据
    queryData() { // 从本地拿,模拟接口返回
      this.loading = true  // loading开始显示加载
      let data = window.localStorage.getItem('excel') || '[]' // 获取本地数据
      this.tableData = JSON.parse(data) // 保证是数组
      this.loading = false // 拿到数据关闭加载状态
    },
    // 搜索按钮
    searchHandle() { // 模拟搜索功能
      this.page = val // 改变当前页
      this.queryData() // 请求当前页
    },
    // 分页出路
    sizeChange(val) { // 模拟表格下的分页
      this.pageSize = val  // 改变当前一页显示多少条数据
      this.page = 1 // 默认第一页
      this.queryData() // 请求接口
    },
    prevNext(val) { // 模拟点击上一页下一页
      this.page = val // 改变页码
      this.queryData() // 请求接口
    },
    // 导出数据
    submit() {
      if (this.selectionList.length <= 0) { // 没有选中数据时
        return this.$message({
          message: '小主,请您先选择要导出的数据库哦!',
          type: 'warning',
          showClose: true
        })
      }

      this.disabled = true // 选中的有数据开始加载
      let loading = Loading.service({ // 提示
        text: '小主,请您稍等片刻,女家正在玩命处理中...',
        background: 'rgba(0,0,0,.5)'
      })

      let arr = this.selectionList.map(item => { // 遍历定义数据的对应表头
        return { // 到时候根据项目自己增删改查
          编号: item.id,
          姓名: item.name,
          电话: item.phone
        }
      })

      let sheet = xlsx.utils.json_to_sheet(arr),  // JSON 变成xlsx识别的数据 顺便去null
        book = xlsx.utils.book_new() // 新建一个表格xlsx

      xlsx.utils.book_append_sheet(book, sheet, 'Sheet1') // 定义一个叫 Sheet1 的列 把sheet 数据插入到 book
      xlsx.writeFile(book, `user${new Date().getTime()}.xls`) // 把book的数据写入表格,这里还加了一个写入的时间

      loading.close() // 关闭loading加载状态
      this.disabled = false // 按钮状态
    }
  }
}
</script>

<style lang="less" scoped>
.buttonBox {
  position: fixed;
  top: 10px;
  right: 20px;
  z-index: 9999;
}
.searchBox {
  padding: 20px;
  display: flex;
  justify-content: flex-start;
  & .el-input {
    width: 25%;
  }
  & .el-button {
    margin-left: 20px !important;
  }
}

.tableBox {
  padding: 0 15px;
}
</style>

引入的一个方法的文件

// 设置异步延迟间隔
export function delay(interval = 0) {
  return new Promise(resolve => {
    let timer = setTimeout(_ => {
      clearTimeout(timer)
      resolve()
    }, interval)
  })
}

// 按照二进制读取文件
export function readFile(file) {
  return new Promise(resolve => {
    let reader = new FileReader()
    reader.readAsBinaryString(file)
    reader.onload = e => {
      resolve(e.target.result)
    }
  })
}

// 字段对应表
export let character = { // 根据实际情况,添加表头信息,类型
  name: {
    text: '姓名',
    type: 'string'
  },
  phone: {
    text: '电话',
    type: 'string'
  }
}

// 时间字符串格式化
export function formatTime(str, tpl) {
  let arr = str.match(/\d+/g).map(item => {
    return item.length < 2 ? '0' + item : item
  })
  tpl = tpl || '{0}年{1}月{2}日 {3}时{4}分{5}秒'
  return tpl.replace(/\{(\d+)\}/g, (_, group) => {
    return arr[group] || '00'
  })
}

有需要源码的,call 我…

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值