开发一个简单的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
    7
    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 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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

    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
    40
    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 });
    }
    });

检测到页面内容有更新,是否刷新页面