2022-06-16 vue+iview+xlsx 实现导入excel并将数据渲染到table

前言:业务需要批量导入数据,在导入前把数据展示出来做个预览,这里写的就是这预览部分。

需要一些依赖:npm install -S file-saver xlsx

在main.js引入:

import XLSX from 'xlsx'

Vue.prototype.XLSX = XLSX

注:我在网上看到的一篇文章,有用,便摘抄了一部分内容进来。原博主文章:http://t.zoukankan.com/guwufeiyang-p-13245875.html

原博主用的是element的框架,我用的是iview,这二者还有有一点区别的,在于等会用到的FileReader(一种异步文件读取机制)files.raw

html部分,需要用到upload组件,这个element和iview的大同小异,代码如下:

       <Upload
        action=""
        accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        :format="['xls', 'xlsx']"
        :show-upload-list="false"
        :max-size="2048"
        :before-upload="handleBefore2"
      >
        <Button
          type="primary"
          style="background-color: #1890ff;border-color: #1890ff; color: #fff;"
        >
          <Icon type="md-arrow-round-up" size="14" />
          批量导入
        </Button>
      </Upload>

methods部分:

    // 导入之前判断
    handleBefore2(file) {
      const types = [
        "application/vnd.ms-excel",
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      ];
      if (types.indexOf(file.type) === -1) {
        Message.warning("不支持的文件类型");
        return false;
      }
      this.handleImport22(file);
      return false;
    },

 // 处理批量导入快递单号(把excel数据渲染在table里)
    handleImport22(file) {
      let that = this;
      const fileReader = new FileReader(file);
      fileReader.onload = ev => {
        try {
          const data = ev.target.result;
          const workbook = that.XLSX.read(data, {
            type: "binary"
          });
          const wsname = workbook.SheetNames[0]; //取第一张表
          const ws = that.XLSX.utils.sheet_to_json(workbook.Sheets[wsname]); //生成json表格内容
          for (var i = 0; i < ws.length; i++) {
            var sheetData = {
              // 键名为绑定 el 表格的关键字,值则是 ws[i][对应表头名]
              id: ws[i]["序号"],
              name: ws[i]["姓名"]
            };
            that.batchImportData.push(sheetData);
          }
        } catch (e) {
          return false;
        }
      };
      // 如果为原生 input 则应是 files[0]
      fileReader.readAsBinaryString(file); // 这里要注意
    },

代码倒数第二行:fileReader.readAsBinaryString(file);

这里要注意:如果是element的,那就是fileReader.readAsBinaryString(file.row);如果是iview就不用row。

这是因为element的upload组件在封装原生input时多加了一层row,而iview就没有。我记得antd好像也包裹了一层row。

加了row的结果:导致FileReader读取不到input的值。
解决方案:file.row。

posted @ 2022-06-16 17:52  叶乘风  阅读(669)  评论(0编辑  收藏  举报