Vue组件-爬取页面表格中的数据并保存为csv文件

背景

实际开发过程中需要将前端以表格形式展示的数据保存为csv格式的文件,由于数据涉及到的种类比较多,格式化都是放在前端进行的,所以后端以接口下载的形式返回csv文件会比较麻烦,于是想着直接写个组件爬取页面中表格内的数据。

开发框架:Vue+Webpack+Element-UI

实现

分析

首先分析一下涉及到的知识点,其实涉及到的知识点也比较简单:

获取页面节点信息
获取页面数据
了解csv文件的格式要求
保存为csv文件并下载

  • 获取页面节点信息

首先是获取页面的节点规律,这点很简单,直接找到需要爬取的页面,打开开发者工具,使用element页面查看即可。获取节点规律即简单又重要,只有清晰的了解页面的结构才能更加直接快捷的获取数据。

  • 获取页面数据

了解了页面的HTML结构之后我们就可以针对性的书写循环获取页面中的数据了。

  • 了解csv文件的格式要求

这里是要保存为csv格式的文件,所以需要先搞清楚csv文件的格式要求,csv文件是使用逗号区分列使用‘\r\n’区分行

  • 保存为csv文件并下载

了解了csv文件的格式要求之后之后我们就可以直接保存了,这里下载的话可以将数据先拼接成字符串,然后再使用Blob,最后动态生成a标签的方式进行。不了解Blob?猛戳这里

注意事项:

  • 本次实现的都是在很特定的页面爬取数据的方式,需要用在其他不同页面还需要更改扩展代码使其更加通用
  • 注意使用双引号将每一个拼接的数据包起来,避免转义

HTML

了解原理之后就直接开始撸,新建downloadToCsv.vue文件

code:

<template>
    <el-button
      class="download"
      @click="downloadTable"
      v-show="toTopShow"
       type="primary"
       plain
       icon="el-icon-download"
       size="mini"
    >
    保存数据为csv文件
    </el-button>
</template>

CSS

code:

<style scoped lang="scss">
.download{
    position: absolute;
    right: 260px;
    top: 25px;
}
</style>

JavaScript

code:

  methods: {
    //   转义br和>
    transferred(data) {
      return data.replace(/<br>/g, "\r\n").replace(/>/g, ">");
    },
    downloadTable() {
      let fileName = Date.now() + ".csv";//使用当前时间戳作为文件名
      var columnDelimiter = ","; //列分割符
      var lineDelimiter = "\r\n"; //行分割符
      var table__header = document.getElementsByClassName(
        "el-table__header"
      )[0];//获取表头
      var table__body = document.getElementsByClassName("el-table__body")[0];//获取tbody
      var head = table__header.tHead;
      let result = "";// 最终结果的字符串
      var ths = head.getElementsByTagName("span");
      for (let i = 0, l = ths.length; i < l; i++) {
        result +=
          this.transferred('"' + ths[i].innerHTML + '"') + columnDelimiter;//每一列用逗号分隔
      }
      result += lineDelimiter;// 每一行使用"\r\n"分隔
      var trs = table__body.getElementsByTagName("tr");
      for (let i = 0, l = trs.length; i < l; i++) {
        let spandata = trs[i].getElementsByTagName("span");
        for (let i = 0, l = spandata.length; i < l; i++) {
          result +=
            this.transferred('"' + spandata[i].innerHTML + '"') +
            columnDelimiter;
        }
        result += lineDelimiter;
      }
      var blob = new Blob(["\uFEFF" + result], { type: "text/csv;" });//记得将编码格式设置一下,避免最终下载的文件出现乱码
      var downloadLink = document.createElement("a");
      if ("download" in downloadLink) {
        var url = URL.createObjectURL(blob);
        downloadLink.href = url;
        downloadLink.download = fileName;
        downloadLink.hidden = true;
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
      } else {
        if (navigator.msSaveBlob) {
          //IE10+
          navigator.msSaveBlob(blob, fileName);
        }
      }
    }
  },
  mounted() {}
};
</script>

大功告成!

发表评论

电子邮件地址不会被公开。 必填项已用*标注