“ 莫约一周前,写过一篇前端上传解析.txt文件的文章,后来项目过程中又遇到了前端生成excel文件并下载这么一个需求,而在这之前,一般下载都是后端给一个链接,直接a链接下载的那种,这次就算是涨知识了吧!”
首先,他们要求做的是导出一个.txt文件,根据先前做下载的经验,我当时确实是没怎么犹豫,直接说了句做不了,然后我看群里后端队伍分享了好多前端自己生成文件的链接,瞄了几眼,好像都是要用好多好多的插件什么的,但是即便如此,这次下载定是要前端自己写了,不过也没关系,天塌下来有大个子撑着,我一个打酱油的实在弄不出来无非也就是落个菜的一批的名声,又不是一次两次了,我太担得起了,所以,当时也就是抱着试试看的心态搜了一下,果然,有好多前辈做过这种前端自己生成文件的事儿,而且就几行代码,看着还挺简单的,粘贴复制过去改扒改扒我的也能用了,嗯,意外之喜,还蛮有成就感的,简单记录了一下,以免之后再用到的时候,不至于在这种小事情上给前端丢人。
01
—
生成.txt文件并下载
我看核心原理应该是用了dataURL转换,最后还是用a链接的形式下载的,总共代码加起来,不超过10行,我还是在vue的项目里做一个简单的演示吧:
首先,我需要备一个简单的下载入口,和一个文本域:
至于样式,设不设的都行,简单处理一下吧:
然后给按钮添加点击事件,给文本域绑定一个动态值。
我们在点击按钮的时候传入文本域的值,所以核心代码要在这个点击事件里面去写:
用了'data:text/txt;charset=utf-8',配合a链接,聪明人一看便知,确实是没有多少东西,可以说是很简单。
02
—
生成excel文件(表格)并下载
另外还有一个需求是将一个table导出,其实原理应该跟前面那个东西差不多,只不过导出文件的后缀名不太一样而已。
先弄一个按钮跟表格,再造点数据:
这都不是什么难事,接下来还是给导出按钮增加一个点击事件,核心代码还是在这个点击事件里面实现:
具体操作如下:
也没有太多代码,就不上传githib了,完整的实现步骤在下面拷贝一份,需要的自己复制哈:
导出
{{item}}
{{item.id}}{{item.name}}{{item.sex}}{{item.age}}{{item.skill}}
export default {
name: "homePage",
components: {},
data() {
return {
tableTitle: ['编号','姓名',"性别","年龄","技能"],
tableData: [
{id: 1, name: '周翡',age: 22,sex: '女',skill: '破血刀'},
{id: 2, name: '谢霉霉', age: 23, sex: '男', skill: '逃跑'},
{id: 3, name: '吴楚楚', age: 22, sex: '女', skill: '过目不忘'}
]
}
},
created() {},
methods: {
downLoadExcel (title, data, fileName) {
//定义表头
let str = `${title}\n` // 增加\t为了不让表格显示科学计数法或者其他格式
for(let i = 0 ; i < data.length ; i++ ){
for(let item in data[i]){
str+=`${data[i][item] + '\t'},`;
}
str+='\n';
}
let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str); // encodeURIComponent解决中文乱码
// 通过创建a标签实现
let link = document.createElement("a");
link.href = uri;
// 对下载的文件命名
link.download = `${fileName || '表格数据'}.csv`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
.homePage {
padding: 20px;
.download {
border: none;
background: #e4393c;
width: 80px;
height: 30px;
border-radius: 5px;
color: #fff;
font-size: 14px;
margin-bottom: 10px;
}
.table {
thead {
th {
border: 1px solid #ddd;
width: 80px;
}
}
tbody {
td {
border: 1px solid #ddd;
text-align: center;
}
}
}
}