| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | --- | 
					
						
							| 
									
										
										
										
											2023-01-14 03:13:35 +00:00
										 |  |  | title: Chrome and Chromium | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | pagination_prev: demos/cloud/index | 
					
						
							|  |  |  | pagination_next: demos/bigdata/index | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-22 06:32:55 +00:00
										 |  |  | The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone) | 
					
						
							|  |  |  | can be integrated in a Chromium extension. | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | This demo includes examples for exporting bookmarks from a popup and scraping | 
					
						
							|  |  |  | tables with a content script and a background script. | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | [The demo](#demo) includes unpacked extensions for Manifest V2 and Manifest V3. | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-12 06:47:52 +00:00
										 |  |  | :::note Tested Deployments | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo was last tested on 2024 March 11 against Chrome 122. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::caution pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo showcases Manifest V2 and Manifest V3 extensions. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Chrome Web Store will not accept new V2 extensions, but these can be sideloaded | 
					
						
							|  |  |  | using the "Load unpacked" extension option in Developer mode. | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-12 06:47:52 +00:00
										 |  |  | **New Chrome and Chromium Extensions should use Manifest V3!** | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | ::: | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | ## Loading SheetJS Scripts
 | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | SheetJS libraries should be bundled in the extension. For path purposes, it is | 
					
						
							|  |  |  | strongly recommended to place `xlsx.full.min.js` in the root folder. | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | #### Popup Pages
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Manifest V2 and Manifest V3 extensions, popup pages can load the standalone | 
					
						
							|  |  |  | script using a normal `<script>` tag: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html | 
					
						
							|  |  |  | <script type="text/javascript" src="xlsx.full.min.js"></script> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### Content Scripts
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Manifest V2 and Manifest V3 extensions, the standalone script can be loaded | 
					
						
							|  |  |  | through the `content_scripts` field: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  |   /* in manifest.json v2 or v3 */ | 
					
						
							|  |  |  |   "content_scripts": [{ | 
					
						
							|  |  |  |     "matches": ["<all_urls>"], | 
					
						
							|  |  |  |     "js": ["xlsx.full.min.js", "content.js"], | 
					
						
							|  |  |  |     "run_at": "document_end" | 
					
						
							|  |  |  |   }], | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `XLSX` global will be visible to other content scripts. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### Background Scripts
 | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | In Manifest V2 extensions, if the standalone script is added as a background | 
					
						
							|  |  |  | script, other background scripts will be able to access the `XLSX` global! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  |   /* in manifest.json v2 only! */ | 
					
						
							|  |  |  |   "background": { | 
					
						
							|  |  |  |     "scripts": ["xlsx.full.min.js", "table.js"], | 
					
						
							|  |  |  |     "persistent": false | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Manifest V3 extensions, background service workers can load the standalone | 
					
						
							|  |  |  | script through `importScripts`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* assuming background script is in the same folder as xlsx.full.min.js */ | 
					
						
							|  |  |  | importScripts("./xlsx.full.min.js"); | 
					
						
							|  |  |  | // now XLSX will be available | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ## Relevant Operations
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | The official documentation covers details including required permissions. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | ### Generating Downloads
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | #### Manifest V2
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | The `writeFile` function works in a Chrome or Chromium extension: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | XLSX.writeFile(wb, "export.xlsx"); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Under the hood, it uses the `chrome.downloads` API.  `"downloads"` permission | 
					
						
							|  |  |  | should be set in `manifest.json`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | #### Manifest V3
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In a background service worker, `URL.createObjectURL` is unavailable. Instead, | 
					
						
							|  |  |  | `XLSX.write` can generate a Base64 string for a synthetic URL: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* generate Base64 string */ | 
					
						
							|  |  |  | const b64 = XLSX.write(wb, {bookType: "xlsx", type: "base64"}); | 
					
						
							|  |  |  | chrome.downloads.download({ | 
					
						
							|  |  |  |   /* make a base64 url manually */ | 
					
						
							|  |  |  |   url: `data:application/octet-stream;base64,${b64}`, | 
					
						
							|  |  |  |   filename: `SheetJSTables.xlsx` | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | ### Content Script Table Scraping
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `table_to_book` and `table_to_sheet` can help build workbooks from DOM tables: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var tables = document.getElementsByTagName("table"); | 
					
						
							|  |  |  | var wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  | for(var i = 0; i < tables.length; ++i) { | 
					
						
							|  |  |  |   var ws = XLSX.utils.table_to_sheet(tables[i]); | 
					
						
							|  |  |  |   XLSX.utils.book_append_sheet(wb, ws, "Table" + i); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Demo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The demo extension includes multiple features to demonstrate sample usage. | 
					
						
							|  |  |  | Production extensions should include proper error handling. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | <details open><summary><b>Testing Unpacked Extension</b> (click to hide)</summary> | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | 1) Download the zip for the desired Manifest version: | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | - [Manifest V2](pathname:///chromium/SheetJSChromiumUnpackedV2.zip) | 
					
						
							|  |  |  | - [Manifest V3](pathname:///chromium/SheetJSChromiumUnpackedV3.zip) | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | 2) Open `chrome://extensions/` in the browser and enable Developer mode | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | 3) Drag and drop the downloaded zip file into the window. | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Bookmark Exporter
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | <details open><summary><b>Testing</b> (click to hide)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 0) Go to <https://sheetjs.com> and create a bookmark in the browser. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) Click the Extensions icon (puzzle icon to the right of the address bar) and | 
					
						
							|  |  |  | select "SheetJS Demo". | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 2) If a small popup is not displayed, click on the SheetJS icon | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) Click "Export Bookmarks" and click "Save". Open the downloaded file! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```mermaid | 
					
						
							|  |  |  | sequenceDiagram | 
					
						
							|  |  |  |   actor U as User | 
					
						
							|  |  |  |   participant P as Popup | 
					
						
							|  |  |  |   participant A as Chromium | 
					
						
							|  |  |  |   U->>P: click icon | 
					
						
							|  |  |  |   P->>A: `chrome.bookmarks.getTree` | 
					
						
							|  |  |  |   A->>P: bookmark tree | 
					
						
							|  |  |  |   Note over P: walk tree | 
					
						
							|  |  |  |   Note over P: make workbook | 
					
						
							|  |  |  |   P->>U: `XLSX.writeFile` | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | `chrome.bookmarks` API enables bookmark tree traversal.  The "Export Bookmarks" | 
					
						
							|  |  |  | button in the extension pop-up recursively walks the bookmark tree, pushes the | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | bookmark URLs into a data array, and exports into a simple spreadsheet. | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* walk the bookmark tree */ | 
					
						
							|  |  |  | function recurse_bookmarks(data, tree) { | 
					
						
							|  |  |  |   if(tree.url) data.push({Name: tree.title, Location: tree.url}); | 
					
						
							|  |  |  |   (tree.children||[]).forEach(function(child) { recurse_bookmarks(data, child); }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* get bookmark data */ | 
					
						
							|  |  |  | chrome.bookmarks.getTree(function(res) { | 
					
						
							|  |  |  |   /* load into an array */ | 
					
						
							|  |  |  |   var data = []; | 
					
						
							|  |  |  |   res.forEach(function(t) { recurse_bookmarks(data, t); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* create worksheet */ | 
					
						
							|  |  |  |   var ws = XLSX.utils.json_to_sheet(data, { header: ['Name', 'Location'] }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* create workbook and export */ | 
					
						
							|  |  |  |   var wb = XLSX.utils.book_new(); | 
					
						
							|  |  |  |   XLSX.utils.book_append_sheet(wb, ws, 'Bookmarks'); | 
					
						
							|  |  |  |   XLSX.writeFile(wb, "bookmarks.xlsx"); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Table Exporter
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | <details open><summary><b>Testing</b> (click to hide)</summary> | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | 1) Go to <https://sheetjs.com/demo/table> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 2) Right-click anywhere in the page and select "SheetJS Demo" > "Export All Tables in Page" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) Save and open the downloaded file! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The background script configures a context menu with the option to export data. | 
					
						
							|  |  |  | The flow diagrams show the data flow when the user chooses to export. They | 
					
						
							|  |  |  | differ in the denouement | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```mermaid | 
					
						
							|  |  |  | sequenceDiagram | 
					
						
							|  |  |  |   actor U as User | 
					
						
							|  |  |  |   participant P as Background Script | 
					
						
							|  |  |  |   participant A as Content Script | 
					
						
							|  |  |  |   U->>P: Context Click > "Export" | 
					
						
							|  |  |  |   Note over P: Query for active tab | 
					
						
							|  |  |  |   P->>A: Ask active tab for data | 
					
						
							|  |  |  |   Note over A: `table_to_sheet` | 
					
						
							|  |  |  |   Note over A: generate workbook | 
					
						
							|  |  |  |   A->>P: workbook object | 
					
						
							|  |  |  |   Note over U,A: ... different denouement for Manifest V2 / V3 extensions ... | 
					
						
							| 
									
										
										
										
											2022-08-01 08:15:50 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-06 10:01:12 +00:00
										 |  |  | #### Manifest V2
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For Manifest V2 extensions, `XLSX.writeFile` just works: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```mermaid | 
					
						
							|  |  |  | sequenceDiagram | 
					
						
							|  |  |  |   actor U as User | 
					
						
							|  |  |  |   participant P as Background Script | 
					
						
							|  |  |  |   Note over P,U: ... background script received workbook ... | 
					
						
							|  |  |  |   P->>U: `XLSX.writeFile` download | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### Manifest V3
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For Manifest V3 extensions, since `URL.createObjectURL` is not available in | 
					
						
							|  |  |  | background service workers, a synthetic URL is created: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```mermaid | 
					
						
							|  |  |  | sequenceDiagram | 
					
						
							|  |  |  |   actor U as User | 
					
						
							|  |  |  |   participant P as Background Script | 
					
						
							|  |  |  |   Note over P,U: ... background script received workbook ... | 
					
						
							|  |  |  |   Note over P: `XLSX.write` Base64 | 
					
						
							|  |  |  |   Note over P: Create Data URL | 
					
						
							|  |  |  |   P->>U: `chrome.downloads.download` | 
					
						
							|  |  |  | ``` |