Excel表格的上传解析导入

238 阅读1分钟

配合封装好的api,文件进行二进制读取,字段对应表,设置异步间隔延迟

<template>
  <div>
    <el-upload
      ref="upload"
      class="upload-demo"
      action
      accept=".xlsx,.xls"
      :on-change="handle"
      :show-file-list="false"
      :auto-upload="false"
    >
      <el-button
        slot="trigger"
        size="small"
        type="primary"
      >选取文件</el-button>
      <el-button
        style="margin-left: 10px;"
        size="small"
        type="success"
        :disabled="disable"
        @click="submitUpload"
      >导入</el-button>
      <div
        slot="tip"
        class="el-upload__tip"
      >只能上传exel文件!</div>
    </el-upload>
    <div v-show="isshow" class="tabletip">
      <h3>小主,一下是采集完成的数据,请您检查无误后,点击“导入”按钮上传到服务器哦!</h3>
      <el-table
        :data="tempData"
        style="width: 100%"
        border
      >
        <el-table-column prop="name" label="姓名" />
        <el-table-column prop="sex" label="性别" />
        <el-table-column prop="age" label="年龄" />
        <el-table-column prop="adress" label="姓名" />
      </el-table>
    </div>
  </div>
</template>

<script>
import { readFile, character, delay } from '@/utils/readFile'
import xlsx from 'xlsx'
import { Loading } from 'element-ui'
export default {
  name: 'Upload',
  components: {},
  props: {},
  data () {
    return {
      fileList: [{
        name: 'food.jpeg',
        url: '123'
      }],
      tempData: [],
      isshow: false,
      disable: false
    }
  },
  computed: {},
  watch: {},
  created () { },
  mounted () { },
  methods: {
    async handle (e) {
      const file = e.raw
      if (!file) return
      this.isshow = false
      let instance = Loading.service({
        text: '小主,请您稍等片刻,奴家正在玩命处理中',
        background: 'rgba(0,0,0,.5)'
      })
      await delay(100)
      // 读取file数据并转化成json格式
      const data = await readFile(file)
      const workbook = xlsx.read(data, { type: 'binary' })
      // console.log(workbook)
      const worksheet = workbook.Sheets[workbook.SheetNames[0]]
      const data1 = xlsx.utils.sheet_to_json(worksheet)
      // let arr = []
      // for (let k in data1[0]) {
      //   arr.push(data1[0][k])
      // }
      // console.log(data1)
      // console.log(arr)
      // // 利用构造函数把数据转化成可传递给服务器的数据
      // let XinXi = function (name, sex, age, adress) {
      //   this.name = name
      //   this.sex = sex
      //   this.age = age
      //   this.adress = adress
      // }
      // let newObj = new XinXi(...arr)
      // console.log(newObj.name)
      // 把读取的数据转为服务器可用的数据格式
      let arr = data1.map(item => {
        let o = {}
        for (let k in character) {
          // if (!character.hasOwnProperty(k)) break
          let text = character[k].text
          let type = character[k].type
          let el = item[text] || ''
          type === 'string' ? el = String(el) : null
          type === 'number' ? el = Number(el) : null
          o[k] = el
        }
        return o
      })
      await delay(100)
      // 展示选中的数据
      console.log(arr)
      this.tempData = arr
      this.isshow = true
      instance.close()
    },
    async submitUpload() {
      if (this.tempData.length <= 0) {
        this.$message({
          message: '小主,请您先选择EXCEL文件哦',
          type: 'warning',
          showClose: true
        })
        return
      }
      this.disable = true
      let instance = Loading.service({
        text: '小主,请您稍等片刻,奴家正在玩命处理中',
        background: 'rgba(0,0,0,.5)'
      })
      // 完成后处理的事情
      let complete = () => {
        this.message({
          message: '小主,奴家已经帮你把数据上传了!',
          type: 'success',
          showClose: false
        })
      }
      // 需要把数据一条条传给服务器
      let n = 0
      let send = async () => {
        if (n > this.tempData.length - 1) {
          complete()
          this.isshow = false
          this.disable = true
          instance.close()
          return
        }
        let body = this.tempData(n)
        let result = await API(body)
        if (parseInt(result.code) === 0) {
          n++
        }
        send()
      }
      send()
    }
  }
}
</script>

<style scoped>
.upload-demo {
  margin: 50px 80px;
}
</style>