开发一个简单的 Chrome 插件
#Chrome Extention 2021/11/19 22:31:21
现在需要开发一个浏览器插件将页面上的数据导出 excel 格式文件,JS 生成 Excel 表格可以使用 Sheet JS,官方支持各种框架,包括 Chrome Extension,只需要引入一个 Js 文件即可使用。 下面拿维基百科上中国皇帝寿命列表开刀,试图通过插件导出这个数据表格。
-
于是先来列一个清单文件 manifest.json
{ "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 页面
<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 文件
const 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 文件
exportTable = () => { 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
chrome.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 }) } })