vue 使用 XLSX 导入表格

引言

后台管理系统中有时会出现需要导入表格的情况,因此查阅资料封装此功能

下载插件

npm i xlsx

封装组件

第一种

<!-- uploadExcel.vue -->
<template>
  <div>
    <el-upload
      ref="upload"
      action="/"
      :on-change="onChange"
      :auto-upload="false"
      :show-file-list="false"
      accept=".xls, .xlsx"
    >
      <el-button type="warning" icon="el-icon-folder-add">导入表格</el-button>
    </el-upload>
  </div>
</template>

<script>
import XLSX from 'xlsx';
export default {
      
      
  data () {
      
      
    return {
      
      
      // 上传的文件
      fileData: ''
    };
  },
  methods: {
      
      
    // 文件改变事件
    onChange (file) {
      
      
      // 保存当前选择文件
      this.fileData = file;
      // 调用读取数据的方法
      this.readExcel();
    },
    // 读取数据
    readExcel () {
      
      
      const files = this.fileData;
      if (!files) {
      
      
        // 没有文件
        return false;
      } else if (!/\.(xls|xlsx)$/.test(files.name.toLowerCase())) {
      
      
        this.$message.error('请上传xls或者xlsx文件');
        return false;
      }
      const fileReader = new FileReader();
      fileReader.onload = (e) => {
      
      
        try {
      
      
          const data = e.target.result;
          const workbook = XLSX.read(data, {
      
      
            type: 'binary'
          });
          if (workbook.SheetNames.length >= 1) {
      
      
            this.$message.success('导入成功');
          }
          // 取第一张表
          const wsname = workbook.SheetNames[0];
          // 生成json表格内容
          const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname]);
          this.$emit('getUploadData', ws);
          // 清空value值,不然页面为刷新时无法重复使用
          this.$refs.upload.value = '';
        } catch (e) {
      
      
          return false;
        }
      };
      fileReader.readAsBinaryString(files.raw);
    }
  }
};
</script>

<style lang="less" scoped>
</style>

页面中使用

<template>
  <div>
    <upload-excel @getUploadData="getExcelData"></upload-excel>
  </div>
</template>


<script>
import UploadExcel from '@/components/table/uploadExcel.vue';
export default {
      
      
  data () {
      
      
    return {
      
      
      // 上传表格处理完成的数据
      uploadData: []
    };
  },
  methods: {
      
      
    getExcelData (data) {
      
      
      let obj = {
      
      };
      const list = [];
      data.forEach((item) => {
      
      
        obj = {
      
      };
        for (const key in item) {
      
      
          if (key === '日期') {
      
      
            obj.date = item[key];
          } else if (key === '姓名') {
      
      
            obj.name = item[key];
          } else if (key === '地址') {
      
      
            obj.address = item[key];
          } else {
      
      
            obj.ceshi = item[key];
          }
        }
        list.push(obj);
      });
      this.uploadData = list;
    }
  },
  components: {
      
      
    UploadExcel
  }
};
</script>

第二种

<!-- index.vue-->
<template>
  <div>
    <input
      class="input-file"
      type="file"
      accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
      @change="exportData"
    />
    <button @click="btnClick">导入参数</button>
  </div>
</template>

<script>
import XLSX from 'xlsx';

export default {
      
      
  methods: {
      
      
    btnClick () {
      
      
      document.querySelector('.input-file').click();
    },
    exportData (event) {
      
      
      if (!event.currentTarget.files.length) {
      
      
        return;
      }
      // 拿取文件对象
      const f = event.currentTarget.files[0];
      // 用FilefileReader 来读取
      const fileReader = new FileReader();
      // 重写FileReader上的readAsBinaryString方法
      FileReader.prototype.readAsBinaryString = (f) => {
      
      
        let binary = '';
        let wb; // 读取完成的数据
        let outdata; // 你需要的数据
        const fileReader = new FileReader();
        fileReader.onload = (e) => {
      
      
          // 读取成Uint8Array,再转换为Unicode编码(Unicode占两个字节)
          const bytes = new Uint8Array(fileReader.result);
          const length = bytes.byteLength;
          for (let i = 0; i < length; i++) {
      
      
            binary += String.fromCharCode(bytes[i]);
          }
          // 接下来就是xlsx了,具体可看api
          wb = XLSX.read(binary, {
      
      
            type: 'binary'
          });
          outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
          // 自定义方法向父组件传递数据
          this.$emit('getResult', outdata);
          // 清空value值,不然页面为刷新时无法重复使用
          document.querySelector('.input-file').value = '';
        };
        fileReader.readAsArrayBuffer(f);
      };
      fileReader.readAsBinaryString(f);
    }
  }
};
</script>

<style scoped>
.input-file {
      
      
  display: none;
}
</style>

页面中使用

<template>
  <div>
    <my-table @getUploadData="getExcelData"></my-table>
  </div>
</template>

<script>
import MyTable from '@/components/table/index.vue';
export default {
      
      
  data () {
      
      
    return {
      
      
      uploadData: []
    };
  },
   methods: {
      
      
    getExcelData (data) {
      
      
      let obj = {
      
      };
      const list = [];
      data.forEach((item) => {
      
      
        obj = {
      
      };
        for (const key in item) {
      
      
          if (key === '日期') {
      
      
            obj.date = item[key];
          } else if (key === '姓名') {
      
      
            obj.name = item[key];
          } else if (key === '地址') {
      
      
            obj.address = item[key];
          } else {
      
      
            obj.ceshi = item[key];
          }
        }
        list.push(obj);
      });
      this.uploadData = list;
    }
  },
  components: {
      
      
    MyTable
  }
};
</script>

<style lang="less" scoped>
</style>

根据资料做的修改,仅供参考,具体需求根据项目变动

猜你喜欢

转载自blog.csdn.net/m0_64344940/article/details/122578337