前言
之前导出 Excel 的工作是交给后端来做的,后来才发现前端也可以导出 Excel,还是太年轻了,接下来一起看一下怎么做的。
前期准备
我们用 Vue,可以很容易生成一个表格:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37<template>
<div>
<table border="1" ref="table">
<thead>
<tr>
<th v-for="(head, index) in thead" :key="index">{{head}}</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, index) in rows" :key="index">
<td v-for="(item, idx) in row" :key="idx">{{item}}</td>
</tr>
</tbody>
</table>
<a id="hrefToExportTable" style="postion: absolute;left: -10px;top: -10px;width: 0px;height: 0px;"></a>
<button @click="download">下载</button>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
thead: ['姓名','学号','性别','年龄'],
rows: [
['小明','1','男','18'],
['小红','2','女','17'],
['小白','3','男','19'],
],
};
}
};
</script>
<style>
</style>
注意:表格的结构和我们之后要导出 Excel 之前的解析有关,所以要按照格式来。
效果:
就是一个表格,一个按钮还有一个看不见的链接。当我们点击按钮,其实就是点击链接,我们只要把链接的 href
换成base64,就可以下载 Excel,功能我们之后再补充
导出 Excel
分辨浏览器
我们在 src
下新建文件夹 libs
,然后新建文件 utils.js
(个人习惯),然后我们一步一步分析。
首先,不同的浏览器导出 Excel 的方式不一样, IE 是用 ActiveXObject
用于启动创建对象的应用程序,在创建某个对象后,可在代码中使用已定义的对象变量引用该对象。但是其他主流浏览器就是用 base64
的方式下载的,所以第一步就是要判断现在的浏览器是什么。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19function getExplorer () {
var explorer = window.navigator.userAgent;
if (explorer.indexOf('MSIE') >= 0) {
// ie
return 'ie';
} else if (explorer.indexOf('Firefox') >= 0) {
// firefox
return 'Firefox';
} else if (explorer.indexOf('Chrome') >= 0) {
// Chrome
return 'Chrome';
} else if (explorer.indexOf('Opera') >= 0) {
// Opera
return 'Opera';
} else if (explorer.indexOf('Safari') >= 0) {
// Safari
return 'Safari';
};
};
我们用 window.navigator.userAgent
来识别浏览器,
IE11的 userAgent
是 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)
,
Chrome 的 userAgent
是 Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
特定的浏览器有特定的标识符,所以第一步判断浏览器就完成了,其实,只是为了分成两类:IE 和 非 IE 。。。
转换成 Excel
1 | function tranform (table, aId, name) { |
我们一段一段讲:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25function tranform (table, aId, name) {
let tableHead = table.children[0];
let tableBody = table.children[1];
let tableInnerHTML = '<thead><tr>';
if (table.children.length !== 1) {
let len = tableBody.rows.length;
let i = -1;
while (i < len) {
if (i === -1) {
Array.from(tableHead.rows[0].children).forEach((th) => {
tableInnerHTML = tableInnerHTML + '<th>' + th.innerHTML + '</th>';
});
tableInnerHTML += '</tr><thead><tbody>';
} else {
tableInnerHTML += '<tr>';
Array.from(tableBody.rows[i].children).forEach((td) => {
tableInnerHTML = tableInnerHTML + '<td>' + td.innerHTML + '</td>';
});
tableInnerHTML += '</tr>';
}
i++;
}
tableInnerHTML += '</tbody>';
}
}
函数 transform
传入三个参数,第一个就是 table
的 DOM 节点,第二个是下载按钮的 id,第三个是 下载的文件名。
由变量名称可以知道是在获取表头和表格的元素,然后循环,将表格的 html 存到字符串 tableInnerHTML
里面,之后要用到,其实,在循环那里完全可以一把梭这么写:1
let tableInnerHTML = tableHead.outerHTML+tableBody.outerHTML;
效果是一样的,如果我们一开始表格的结构变了,那我们也要改变这条语句,而第一种方式就比较通用一点。
IE处理
1 | var idTmr; |
其实就是调用 IE 的方法,生成 IE,这就不说了
其他浏览器处理
1 | let tableToExcel = (function () { |
一个立即执行函数,首先就是 uri
,可以看到是 base64 的格式,然后 template
就是一个页面,里面的 {table}
就是我们上面生成的 tableInnerHTML
,用字符串的 replace
方法替换,然后把 uri
和 base64 连接,赋值给我们的链接,手动点击,就能下载了。
效果
可以看到,我们的文件已经下载下来了,由于是直接保存 html,所以 Excel 会警告,而且没有样式,如果想自己加样式,就在 template
那里自己写 <style>
样式。
拓展
有了 table2excel
那有没有 table2img
呢?当然有了,思路也是差不多,就是利用 html2canvas
这个插件,将 table 的 html 转成 canvas,然后 canvas 转成 图片。