上传excel文件然后在表格中渲染excel的内容

1.在编写代码之前我们先来认识一些FileReader()读取文件

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
其中File对象可以是来自用户在一个元素上选择文件后返回的FileList对象,也可以来自拖放操作生成的 DataTransfer对象,还可以是来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。

常用事件
FileReader.onload事件在读取完成后触发。

1.
image.png
image.png
  <!-- 上传文件按钮 -->
    <div class="buttonBox">
      <el-upload
        action
        accept=".xlsx, .xls"
        :auto-upload="false"
        :show-file-list="false"
        :on-change="handle"
      >
        <el-button type="primary" slot="trigger">选取EXCEL文件</el-button>
      </el-upload>

      <el-button type="success" @click="submit" :disabled="disable"
        >采集数据提交</el-button
      >
    </div>

Upload.vue文件

 methods: {
    // 采集EXCEL数据
    async handle(ev) {
      let file = ev.raw;  //这边ev打印出是一个对象,可以看如下截图
      if (!file) return;
      this.show = false;
      let loadingInstance = Loading.service({
        text: "小主,请您稍等片刻,奴家正在玩命处理中!",
        background: "rgba(0,0,0,.5)",
      });
      await delay(100);
      //读取FILE中的数据(变为JSON格式)
      let data = await readFile(file);
      let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
      console.log(workbook);
     let  worksheet = workbook.Sheets[workbook.SheetNames[0]]; //拿到sheet的数据
        console.log(worksheet);
      data = xlsx.utils.sheet_to_json(worksheet); //xlsx这个插件帮我们处理成json格式数据
      console.log(data);
      //把读取出来的数据变为最后可以传递给服务器的数据(姓名:name  电话:phone)
      let arr = [];
      data.forEach((item) => {
        let obj = {};
        for (let key in character) {
          if (!character.hasOwnProperty(key)) break;
          let v = character[key],
            text = v.text,
            type = v.type;
          v = item[text] || "";
          type === "string" ? (v = String(v)) : null;
          type === "number" ? (v = Number(v)) : null;
          obj[key] = v;
        }
        arr.push(obj);
      });

      await delay(100);
      // 展示到页面中
      this.show = true;
      this.tempData = arr;
      loadingInstance.close();
    },
    // 提交数据给服务器
    async submit() {
      if (this.tempData.length <= 0) {
        this.$message({
          message: "小主,请您先选择EXCEL文件!",
          type: "warning",
          showClose: true,
        });
        return;
      }

      this.disable = true;
      let loadingInstance = Loading.service({
        text: "小主,请您稍等片刻,奴家正在玩命处理中!",
        background: "rgba(0,0,0,.5)",
      });

      // 完成后处理的事情
      let complate = () => {
        this.$message({
          message: "小主,奴家已经帮您把数据上传了!",
          type: "success",
          showClose: true,
        });
        this.show = false;
        this.disable = false;
        loadingInstance.close();
      };

      // 需要把数据一条条传递给服务器
      let n = 0;
      let send = async () => {
        if (n > this.tempData.length - 1) {
          // 都传递完了
          complate();
          return;
        }
        let body = this.tempData[n];
        let result = await createAPI(body);
        if (parseInt(result.code) === 0) {
          // 成功
          n++;
        }
        send();
      };
      send();
    },
  },
image.png

2.然后我们读取该file,我们通过FileReader把该file读取为二进制编码。

Upload.vue
 //读取FILE中的数据(变为JSON格式)
      let data = await readFile(file);
      let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
      console.log(workbook);
     let  worksheet = workbook.Sheets[workbook.SheetNames[0]]; //拿到sheet的数据
        console.log(worksheet);
      data = xlsx.utils.sheet_to_json(worksheet); //xlsx这个插件帮我们处理成json格式数据
      console.log(data);

我们在utils.js文件封装一个读取为二进制编码的方法,如下ev.target.result打印出是一个二进制的数据。


image.png

FileReader 包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。


image.png

文件一旦开始读取,无论成功或失败,实例的 result 属性都会被填充。如果读取失败,则 result 的值为 null ,否则即是读取的结果,绝大多数的程序都会在成功读取文件的时候,抓取这个值。

3.通过刚才第二步骤我们知道了二进制数据,然后在将二进制数据用插件读取,读取之后生成一个excel的工作目录。

  let data = await readFile(file);
  let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
  console.log(workbook);
打印出如下
image.png

4.我们通过这个workbook.Sheets[workbook.SheetNames[0]]拿到sheet的数据,然后我们需要转成json格式的数据如何操作?【我们是通过xlsx.utils.sheet_to_json(worksheet)】转成json格式数据。

image.png
   let data = await readFile(file);
   let workbook = xlsx.read(data, { type: "binary" }); //用插件去读取,把二进制制读取完生成一个excel的工作目录
   console.log(workbook);
   let  worksheet = workbook.Sheets[workbook.SheetNames[0]]; //拿到sheet的数据
   console.log(worksheet);
  data = xlsx.utils.sheet_to_json(worksheet); //xlsx这个插件帮我们处理成json格式数据
   console.log(data);
打印如下
image.png

6k条的数据解析差不多30s左右,如果是上传到服务器差不多要3分钟。

5.此时我们成功的转化为json数据,但是当我们调接口传给服务器肯定是不能以姓名和电话这个中文名这个字段传给服务器,所以我们需要转一下。注意:【这边拿到的电话是number类型,一般数字我们需要转成number在传给后端】

代码处理如下:
 console.log(data);
      //把读取出来的数据变为最后可以传递给服务器的数据(姓名:name  电话:phone)
      let arr = [];
      data.forEach((item) => {   //这里的item指的是{name:"老王",电话:18856565656}
        let obj = {};
        for (let key in character) {
          if (!character.hasOwnProperty(key)) break;
          let v = character[key],
            text = v.text,
            type = v.type;
          v = item[text] || "";
          type === "string" ? (v = String(v)) : null;
          type === "number" ? (v = Number(v)) : null;
          obj[key] = v;
        }
        arr.push(obj);
      });
      console.log(arr)

utils.js文件代码


image.png

打印出来效果如下:


image.png

6.然后等表格全部读取之后才显示出来,我们现在data中定义一个show为false


image.png

image.png

每次解析数据之前,都把我们的表格隐藏掉,当我们拿到数据才显示。


image.png

7.这边做个loading的视觉效果


image.png

delay是在utils.js里面封装


image.png

8.完成以上步骤之后接下来就是调用接口,准备把数据上传到服务器上面,有两种上传方式,一种是数据同时发,另外一种是把数据一条一条发送,这边选用一条一条发送。


image.png

image.png

image.png
  // 提交数据给服务器
    async submit() {
      if (this.tempData.length <= 0) {
        this.$message({
          message: "小主,请您先选择EXCEL文件!",
          type: "warning",
          showClose: true,
        });
        return;
      }

      this.disable = true;
      let loadingInstance = Loading.service({
        text: "小主,请您稍等片刻,奴家正在玩命处理中!",
        background: "rgba(0,0,0,.5)",
      });

      // 完成后处理的事情
      let complate = () => {
        this.$message({
          message: "小主,奴家已经帮您把数据上传了!",
          type: "success",
          showClose: true,
        });
        this.show = false;
        this.disable = false;
        loadingInstance.close();
      };

      // 需要把数据一条条传递给服务器
      let n = 0;
      let send = async () => {
        if (n > this.tempData.length - 1) {
          // 都传递完了
          complate();
          return;
        }
        let body = this.tempData[n];
        let result = await createAPI(body);
        if (parseInt(result.code) === 0) {
          // 成功
          n++;
        }
        send();
      };
      send();
    },
  },
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容