开发一个简单的Chrome插件
2021.11.19 Fri
现在需要开发一个浏览器插件将页面上的数据导出 excel 格式文件,JS 生成 Excel 表格可以使用 Sheet JS,官方支持各种框架,包括 Chrome Extension,只需要引入一个 Js 文件即可使用。
下面拿维基百科上中国皇帝寿命列表开刀,试图通过插件导出这个数据表格。
于是先来列一个清单文件 manifest.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14{
"background": {
"service_worker": "background.js"
},
"permissions": ["tabs", "downloads"],
"host_permissions": ["https://zh.wikipedia.org/wiki/"],
"content_scripts": [
{
"matches": ["https://zh.wikipedia.org/wiki/%E4%B8%AD%E5%9B%BD%E7%9A%87%E5%B8%9D%E5%AF%BF%E5%91%BD%E5%88%97%E8%A1%A8"],
"run_at": "document_end",
"js": ["js/contentScript.js", "js/xlsx.full.min.js"]
}
]
}将需要使用的 Sheet JS 文件 xlsx.full.min.js 在清单文件里列出,就可以在 Js 文件里直接使用了,因为需要下载导出的 Excel 文件,所以需要在权限里声明 download 权限,而 tabs 权限是用来向 content scirpt 通信。
popup 页面
1
2
3
4
5
6
7
8
9
10
11
12<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="./css/popup.css" />
</head>
<body>
<div class="content">
<button>Export</button>
</div>
</body>
<script src="./js/popup.js"></script>
</html>popup Js 文件
1
2
3
4
5
6
7const button = document.querySelector('.content button');
button.addEventListener('click', () => {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, 'export');
});
});监听 button 的点击事件,获取当前的活动窗口 tabId,向该活动窗口的 content script 发送消息
contentScript.js 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16exportTable = () => {
const table = document.querySelector('table.wikitable');
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.table_to_sheet(table, {
raw: true,
display: true,
});
XLSX.utils.book_append_sheet(wb, ws);
XLSX.writeFile(wb, '中国皇帝寿命');
};
chrome.runtime.onMessage.addListener((res) => {
if (res == 'export') {
exportTable();
}
});content script 监听到导出的消息就启动导出函数。
Sheet Js 有多种方法可以生成 excel 文件,table_to_sheet 是将页面的 table 表格转换成 sheet,只需要给定 table 元素就可以自动生成 sheet,对于非 table 元素的数据可以使用 json_to_sheet(),通过循环数据生成一个指定对象作函数参数。然后再将 sheet 添加到 workbook 里面。
background.js
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
38
39
40chrome.runtime.onInstalled.addListener(function () {
chrome.action.disable();//禁止插件的action功能
chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
//声明只有在特定页面激活插件的action功能
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { urlContains: 'zh.wikipedia.org/wiki/' },
}),
],
actions: [new chrome.declarativeContent.ShowPageAction()],
},
]);
});
});
let currentTabId;
//监听浏览器加载动作
chrome.webNavigation.onCompleted.addListener(
(details) => {
currentTabId = details.tabId;
},
{
url: [
{
urlContains:
'https://zh.wikipedia.org/wiki/%E4%B8%AD%E5%9B%BD%E7%9A%87%E5%B8%9D%E5%AF%BF%E5%91%BD%E5%88%97%E8%A1%A8',
},
],
}
);
chrome.runtime.onMessage.addListener((message) => {
if (message.delay && currentTabId) {
chrome.tabs.sendMessage(currentTabId, { delay: message.delay });
}
});