vue导入excel表并且展示excel数据,并且解决了change事件只会触发一次,多次失效的问题

1. 安装: cnpm install xlsx --save

2.  新建js文件:

import Vue from 'vue'
import XLSX from 'xlsx'
 
/**
 * 导入ex表格 得到json数据
 * 已注入所有Vue实例,
 * template模板里调用 $importf
 * 组件方法里调用 this.$importf
 * 例:<input type="file" id="file22" @change="importf('file22')" />
 * this.$importf(id) 得到 json数据
 */
const importf = (id) => {
  let promise = new Promise((resolve, reject) => {
    // 导入
    // FileReader共有4种读取方法:
    // 1.readAsArrayBuffer(file) :将文件读取为ArrayBuffer。
    // 2.readAsBinaryString(file) :将文件读取为二进制字符串
    // 3.readAsDataURL(file) :将文件读取为Data URL
    // 4.readAsText(file, [encoding]) :将文件读取为文本,encoding缺省值为'UTF-8'
    var wb // 读取完成的数据
    var rABS = false // 是否将文件读取为二进制字符串
    let obj = document.getElementById(id)
    if (!obj.files) {
      return
    }
    var f = obj.files[0]
    var reader = new FileReader()
    if (rABS) {
      reader.readAsArrayBuffer(f)
    } else {
      reader.readAsBinaryString(f)
    }
    var arr = []
    reader.onload = function (e) {
      var data = e.target.result
      if (rABS) {
        wb = XLSX.read(btoa(fixdata(data)), { // 手动转化
          type: 'base64'
        })
      } else {
        wb = XLSX.read(data, {
          type: 'binary'
        })
      }
      arr = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])
      resolve(arr)
    }
    reader.onerror = function (e) {
      reject(arr)
    }
  })
  return promise
}
const fixdata = (data) => { // 文件流转BinaryString
  var o = ''
  var l = 0
  var w = 10240
  for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
  o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
  return o
}

Vue.prototype.$importf = importf

3. 在main.js文件里面引入js文件: 

import '@/extensions/excel

4. 在主文件里面添加导入按钮:

<input type="file" class="blue_input" name="file" id="file" :value="value" @click="clickAsync('file', $event.target.files, $event)"/>
          <table style="margin: 20px 0;">
            <thead>
              <tr>
                <th v-for="(head, index) in tableHeads">
                  {{index}}
                </th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(item, i) in tabelBody">
                <td v-for="(head, index) in tableHeads">
                  {{item[index]}}
                </td>
              </tr>
            </tbody>
          </table>

 

data里面定义: 

value: '',

tableHeads: [],

contracts: [],

tabelBody: [],

 

clickAsync (idName, val, el) {
        el.srcElement.value = ''
        this.value = ''
        this.contracts = []
        this.tableHeads = []
        this.tabelBody = []
        document.getElementById(idName).addEventListener('change', async (e) => {
          this.allItem = e.target.files
          this.value = e.target.value
          if (this.allItem.length > 0) {
            this.$emit('clickAsync', this.allItem);
          }
          let itemList = await this.$importf(idName)
          this.contracts.push({ value: this.allItem })
          if (itemList && itemList.length > 0) {
            this.tableHeads = itemList[0]
            this.tabelBody = itemList
          }
        })
      },

 注: 解决多次上传文件名相同内容不同,但是change事件只会出发一下,所以使用click事件,在click事件里面监听change事件,并且使用el.srcElement.value = ''

提交传值: 

submit1() {
        if (this.contracts.length > 0) {
          const contracts = this.contracts.filter(contract => contract.value).map(contract => contract.value);
          Permission.orientOperateBatch({
            file: contracts.length < 1 ? '' : contracts,

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值