实际开发过程中需要将前端以表格形式展示的数据保存为csv格式的文件,由于数据涉及到的种类比较多,格式化都是放在前端进行的,所以后端以接口下载的形式返回csv文件会比较麻烦,于是想着直接写个组件爬取页面中表格内的数据。
开发框架:Vue+Webpack+Element-UI
首先分析一下涉及到的知识点,其实涉及到的知识点也比较简单:
获取页面节点信息 获取页面数据 了解csv文件的格式要求 保存为csv文件并下载
首先是获取页面的节点规律,这点很简单,直接找到需要爬取的页面,打开开发者工具,使用element页面查看即可。获取节点规律即简单又重要,只有清晰的了解页面的结构才能更加直接快捷的获取数据。
了解了页面的HTML结构之后我们就可以针对性的书写循环获取页面中的数据了。
这里是要保存为csv格式的文件,所以需要先搞清楚csv文件的格式要求,csv文件是使用逗号区分列,使用‘\r\n’区分行。
了解了csv文件的格式要求之后之后我们就可以直接保存了,这里下载的话可以将数据先拼接成字符串,然后再使用Blob,最后动态生成a标签的方式进行。不了解Blob?猛戳这里。
注意事项:
了解原理之后就直接开始撸,新建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>
code:
<style scoped lang="scss">
.download{
position: absolute;
right: 260px;
top: 25px;
}
</style>
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>
大功告成!