咸吃萝卜淡操心:导入xlsx文件表格新增数据

0. 缘起

东西做着做着忽然发现表格下方有个(导入)按钮,我纳闷了,想之前就直接传了个文件,怕不是需要把tableData换成这个,于是就开始自己琢磨。最后捏,发现人后端做完了这个导入新增的功能,我默默地删了新写的代码,不过这玩意也挺有挑战的,值得纪念!

1. 代码

          <el-upload
            class="upload-demo"
            name="excelFile"
            :headers="getHeaders()"
            :action="url"
            :auto-upload="true"
            :show-file-list="false"
            :on-success="onSuccess"
            :on-error="onError"
            :before-upload="onBefore"
            accept=".xlsx,.xls"
          >
            <el-button type="primary">导入</el-button>
          </el-upload>
    readExcel(file) {
      console.log("file: ", file);
      const fileReader = new FileReader();
      fileReader.onload = (ev) => {
        try {
          const data = ev.target.result;
          const workbook = XLSX.read(data, {
            type: "binary",
          });
          for (let sheet in workbook.Sheets) {
            const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
            console.log("sheetArray: ", sheetArray);
          }
        } catch (e) {
          this.$message.warning("文件类型不正确!");
          return false;
        }
      };
      fileReader.readAsBinaryString(file.raw);
    },
    // Update successfully
    onSuccess(response, file) {
      if (response.code === 0) {
        this.$message.success({
          message: "文件上传成功",
          duration: 1000,
        });
        // this.readExcel(file);
      } else {
        this.$message.error(response.message);
      }
      this.loading.close();
    },

2. 解析

其实大体上就两步,第一步,拿到XLSX,第二步,把XLSX里的file转换为可用的对象

2.1 解析XLSX的插件

npm install xlsx

import XLSX from 'xlsx'

2.2 获取file作为可用对象

这里我用了el-upload的上传文件成功的钩子来获取file,也可以用addEventListener的方法监听upload事件。注意这里参数列表第二个就是file,也是XLSX插件需要的。

参数 说明 类型
on-success 文件上传成功时的钩子 function(response, file, fileList

3. 导出 XLSX

    exportExcel() {
      let data = this.downloadData;
      //
      // 新建空workbook,然后加入worksheet
      const ws = XLSX.utils.json_to_sheet(data);
      // 设置每列的列宽,10代表10个字符,注意中文占2个字符
      ws["!cols"] = [{ wch: 10 }, { wch: 25 }];
      // 新建book
      const wb = XLSX.utils.book_new();
      // 生成xlsx文件(book,sheet数据,sheet命名)
      XLSX.utils.book_append_sheet(wb, ws, "数据详情");
      // 写文件(book,xlsx文件名称)
      XLSX.writeFile(wb, this.sideTableTitle + "详情.xlsx");
    },
              for (let i = 0; i < sk.name.length; i++) {
                self.downloadData.push({ 姓名: sk.name[i], 次数: sk.value[i] });
              }

4. 实际运用

嘿嘿,没想到我还可以用这个来筛选表格数据,JS,恁太强大了!

4.1 从XLSX文件中获取数据

    readExcel(file) {
      console.log("file: ", file);
      const fileReader = new FileReader();
      fileReader.onload = (ev) => {
        console.log("ev: ", ev);
        try {
          const data = ev.target.result;
          const workbook = XLSX.read(data, { type: "binary" });
          for (let sheet in workbook.Sheets) {
            const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
            console.log("sheetArray: ", sheetArray);
            this.tableDataL = sheetArray.map((key) => {
              return key?.nameL;
            });
            this.tableDataS = sheetArray
              .map((key) => {
                return key?.nameS;
              })
              .filter((key) => {
                return key !== undefined;
              });
            console.log(this.tableDataS, "this.tableDataL: ", this.tableDataL);
            this.getUniqueData();
          }
        } catch (e) {
          this.$message.warning("文ERROR!");
          console.log("ERROR IN READ");
          return false;
        }
      };
      fileReader.readAsBinaryString(file.raw);
    },

4.2 数组处理

取两列数组中没有重复的值,交集取并

    getUniqueData() {
      let unique = this.tableDataL.filter((key) => {
        return !this.tableDataS.includes(key);
      });
      console.log("unique", unique);
    },

效果就是第一列70个名字,第二列100个名字,其中有70个是第一列的,要把不重复的30个找出来。

4.3 导出unique的XLSX文件

    exportExcel() {
      let data = this.getUniqueData().map((key) => {
        return { name: key };
      });
      // self.downloadData.push({ 姓名: sk.name[i], 次数: sk.value[i] });
      // 新建空workbook,然后加入worksheet
      const ws = XLSX.utils.json_to_sheet(data);
      // 设置每列的列宽,10代表10个字符,注意中文占2个字符
      ws["!cols"] = [{ wch: 10 }, { wch: 25 }];
      // 新建book
      const wb = XLSX.utils.book_new();
      // 生成xlsx文件(book,sheet数据,sheet命名)
      XLSX.utils.book_append_sheet(wb, ws, "数据详情");
      // 写文件(book,xlsx文件名称)
      XLSX.writeFile(wb, "特殊姓名.xlsx");
    },

引用

Element](https://element.eleme.cn/#/zh-CN/component/upload)

【Vue 笔记】Vue 读取excel数据并生成数组 (wikimoe.com)

vue中使用excel导入导出 - LGW0 - 博客园 (cnblogs.com)

posted @ 2022-01-05 16:42  乐盘游  阅读(327)  评论(0编辑  收藏  举报