开发一个简单的 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 })
      }
    })