forked from sheetjs/docs.sheetjs.com
		
	v3manifest
This commit is contained in:
		
							parent
							
								
									7fbd794137
								
							
						
					
					
						commit
						709553e22e
					
				| @ -130,6 +130,37 @@ _Writing Files_ | ||||
| XLSX.writeFile(wb, "SheetJS.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| <details><summary><b>Implementation Details</b> (click to show)</summary> | ||||
| 
 | ||||
| Under the hood, it creates a special URL and clicks a link. The library method | ||||
| includes a few workarounds for legacy browsers | ||||
| 
 | ||||
| `XLSX.writeFile(wb, "SheetJS.xlsx");` is roughly equivalent to: | ||||
| 
 | ||||
| ```js | ||||
| /* write data -- note that writeFile infers bookType from filename */ | ||||
| const u8 = XLSX.write(wb, { bookType: "xlsx", type: "buffer" }); | ||||
| /* create Blob */ | ||||
| const blob = new Blob([u8]); | ||||
| /* create object URL */ | ||||
| const url = URL.createObjectURL(new Blob([u8])); | ||||
| 
 | ||||
| /* create `A` DOM element */ | ||||
| const a = document.createElement("a"); | ||||
| /* set export file name */ | ||||
| a.download = "SheetJS.xlsx"; | ||||
| /* wire up the object URL to the DOM element */ | ||||
| a.href = url; | ||||
| /* add to the page */ | ||||
| document.body.appendChild(a); | ||||
| /* click the link */ | ||||
| a.click(); | ||||
| /* remove the element from the page */ | ||||
| document.body.removeChild(a); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| :::caution Web Workers | ||||
| 
 | ||||
| `XLSX.writeFile` requires DOM access and will not work in a Web Worker! | ||||
| @ -378,6 +409,51 @@ var wb = readFile("sheetjs.numbers"); | ||||
| writeFile(wb, "sheetjs.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| <details><summary><b>Implementation Details</b> (click to show)</summary> | ||||
| 
 | ||||
| **`XLSX.readFile(filepath)`** is equivalent to: | ||||
| 
 | ||||
| _CommonJS_ | ||||
| 
 | ||||
| ```js | ||||
| var fs = require("fs"); | ||||
| var buf = fs.readFileSync(filepath); | ||||
| var wb = XLSX.read(buf); | ||||
| ``` | ||||
| 
 | ||||
| _ECMAScript Modules_ | ||||
| 
 | ||||
| ```js | ||||
| import { read } from "xlsx"; | ||||
| import { readFileSync } from "fs"; | ||||
| 
 | ||||
| var buf = readFileSync(filepath); | ||||
| var wb = read(buf); | ||||
| ``` | ||||
| 
 | ||||
| **`XLSX.writeFile(wb, filepath)`** is equivalent to: | ||||
| 
 | ||||
| _CommonJS_ | ||||
| 
 | ||||
| ```js | ||||
| var fs = require("fs"), path = require("path"); | ||||
| var buf = XLSX.write(wb, { bookType: path.extname(filepath).slice(1), type: "buffer" }); | ||||
| fs.writeFileSync(filepath, buf); | ||||
| ``` | ||||
| 
 | ||||
| _ECMAScript Modules_ | ||||
| 
 | ||||
| ```js | ||||
| import { write } from "xlsx"; | ||||
| import { writeFileSync } from "fs"; | ||||
| import { extname } from "path"; | ||||
| 
 | ||||
| var buf = write(wb, { bookType: extname(filepath).slice(1), type: "buffer" }); | ||||
| writeFileSync(filepath, buf); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### ExtendScript | ||||
| 
 | ||||
| In Photoshop and other Adobe apps, `readFile` and `writeFile` use the `File` | ||||
| @ -390,6 +466,19 @@ var wb = XLSX.readFile("sheetjs.xlsx"); | ||||
| XLSX.writeFile(wb, "sheetjs.csv"); | ||||
| ``` | ||||
| 
 | ||||
| The [ExtendScript demo](/docs/demos/extensions/extendscript) covers the "Common | ||||
| Extensibility Platform" (CEP) and "Unified Extensibility Platform" (UXP) details. | ||||
| 
 | ||||
| ### Chrome Extensions | ||||
| 
 | ||||
| In Manifest v2 Chrome extensions, `writeFile` calls `chrome.downloads.download`. | ||||
| 
 | ||||
| This approach uses `URL.createObjectURL`, an API that is not supported in a | ||||
| Manifest v3 Background Service Worker. For small exports, raw Base64 URLs can be | ||||
| generated and downloaded. | ||||
| 
 | ||||
| The [Chromium demo](/docs/demos/extensions/chromium) covers the details. | ||||
| 
 | ||||
| ### Deno | ||||
| 
 | ||||
| `readFile` uses `Deno.readFileSync` and `writeFile` uses `Deno.writeFileSync`: | ||||
| @ -410,6 +499,34 @@ Any Deno script using `XLSX.writeFile` requires the `--allow-write` entitlement. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| <details><summary><b>Implementation Details</b> (click to show)</summary> | ||||
| 
 | ||||
| **`XLSX.readFile(filepath)`** is equivalent to: | ||||
| 
 | ||||
| _ECMAScript Modules_ | ||||
| 
 | ||||
| <CodeBlock language="ts">{`\ | ||||
| // @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts" | ||||
| import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs'; | ||||
| \n\ | ||||
| const u8: Uint8Array = Deno.readFileSync(filepath); | ||||
| const wb: XLSX.WorkBook = XLSX.read(u8);`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| **`XLSX.writeFile(wb, filepath)`** is equivalent to: | ||||
| 
 | ||||
| _ECMAScript Modules_ | ||||
| 
 | ||||
| <CodeBlock language="ts">{`\ | ||||
| // @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts" | ||||
| import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs'; | ||||
| \n\ | ||||
| const u8 = XLSX.write(wb, { bookType: filepath.slice(filepath.lastIndexOf(".")+1), type: "buffer" }); | ||||
| Deno.writeFileSync(filepath, u8);`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Bun | ||||
| 
 | ||||
| Bun requires the `fs` module: | ||||
| @ -423,10 +540,11 @@ var wb = readFile("sheetjs.numbers"); | ||||
| writeFile(wb, "sheetjs.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| The implementation is identical to [NodeJS ECMAScript Modules](#nodejs). | ||||
| 
 | ||||
| ### Apps | ||||
| 
 | ||||
| Desktop and mobile apps have their own specific APIs covered in separate demos: | ||||
| 
 | ||||
| - [Electron and other desktop apps](/docs/demos/desktop) | ||||
| - [React Native and other mobile apps](/docs/demos/mobile) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										112
									
								
								docz/docs/03-demos/09-cloud/11-deno.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										112
									
								
								docz/docs/03-demos/09-cloud/11-deno.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| --- | ||||
| title: Deno Deploy | ||||
| pagination_prev: demos/local/index | ||||
| pagination_next: demos/extensions/index | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| Deno Deploy offers "Serverless Functions" powered by Deno. | ||||
| 
 | ||||
| The [Deno installation](/docs/getting-started/installation/deno) instructions | ||||
| apply to Deno Deploy scripts. | ||||
| 
 | ||||
| :::warning | ||||
| 
 | ||||
| Deno Deploy does not offer any sort of temporary file access in functions. | ||||
| 
 | ||||
| This breaks web frameworks that use the filesystem in body parsing. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::caution | ||||
| 
 | ||||
| When the demo was last tested, Deno Deploy required a GitHub account. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Supported Frameworks | ||||
| 
 | ||||
| When the demo was last tested, the `drash` server framework used an in-memory | ||||
| approach for parsing POST request bodies. | ||||
| 
 | ||||
| ### Parsing Data | ||||
| 
 | ||||
| When files are submitted via HTTP POST, the `bodyParam` method can fetch data. | ||||
| The `content` property of the returned object can be parsed with `XLSX.read`. | ||||
| 
 | ||||
| The following example assumes the file is submitted at field name `file`: | ||||
| 
 | ||||
| <CodeBlock language="ts">{`\ | ||||
| // @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts" | ||||
| import { read, utils } from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs'; | ||||
| import * as Drash from "https://deno.land/x/drash@v2.5.4/mod.ts"; | ||||
| \n\ | ||||
| class SheetJSResource extends Drash.Resource { | ||||
|   public paths = ["/"]; | ||||
| \n\ | ||||
|   public POST(request: Drash.Request, response: Drash.Response) { | ||||
|     // highlight-start | ||||
|     /* get data from body */ | ||||
|     const file = request.bodyParam<Drash.Types.BodyFile>("file"); | ||||
|     /* parse */ | ||||
|     var wb = read(file.content, {type: "buffer", dense: true}); | ||||
|     // highlight-end | ||||
|     /* generate HTML from first worksheet */ | ||||
|     return response.html(utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]])); | ||||
|   } | ||||
| }`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| ## Demo | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 June 05. The service <https://s2c.sheetjs.com> | ||||
| was implemented using this exact sequence. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Register and Sign in. | ||||
| 
 | ||||
| 2) Click "New Project" to create a new Project. In the next screen, look for the | ||||
| "Hello World" sample and click the corresponding "Fork" button. | ||||
| 
 | ||||
| 3) Download [`s2c.ts`](pathname:///deno/s2c.ts).  Open with a text editor and | ||||
| copy the contents into the playground editor (left pane). | ||||
| 
 | ||||
| 4) Click "Save and Deploy". | ||||
| 
 | ||||
| ### Testing | ||||
| 
 | ||||
| 5) Download the test file <https://sheetjs.com/pres.xlsx> | ||||
| 
 | ||||
| 6) In the browser window, click "Choose File" and select the downloaded file. | ||||
| Click "Submit" and the page will show the contents in a HTML TABLE. | ||||
| 
 | ||||
| 7) Click the "Fullscreen" icon in the top-right corner of the page window. | ||||
| 
 | ||||
| 8) Open a terminal window and download <https://sheetjs.com/pres.numbers>: | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://sheetjs.com/pres.numbers | ||||
| ``` | ||||
| 
 | ||||
| 9) Copy the first `curl` line from the page and run in the terminal. For | ||||
| example, if the deployment is `clean-badger-69`, the command would be | ||||
| 
 | ||||
| ```bash | ||||
| curl -X POST -F"file=@pres.numbers" https://clean-badger-69.deno.dev/ | ||||
| ``` | ||||
| 
 | ||||
| The output will be an HTML table | ||||
| 
 | ||||
| 10) Copy the second `curl` line from the page and run in the terminal. For | ||||
| example, if the deployment is `clean-badger-69`, the command would be | ||||
| 
 | ||||
| ```bash | ||||
| curl -X POST -F"file=@pres.numbers" -F"type=csv" https://clean-badger-69.deno.dev/ | ||||
| ``` | ||||
| 
 | ||||
| The output will be CSV. | ||||
| @ -15,9 +15,11 @@ support.  Over the years there have been a few different JavaScript platforms: | ||||
| - "ExtendScript": This uses an old JavaScript dialect but is supported in older | ||||
|   versions of Creative Suite and Creative Cloud. | ||||
| 
 | ||||
| - "CEP": This was recommended in CS6 but eventually deprecated. | ||||
| - "Common Extensibility Platform" (CEP): This was introduced in Creative Suite. | ||||
|   App automation uses ExtendScript, but integration logic uses modern JS. | ||||
| 
 | ||||
| - "UXP": This is the current Adobe recommendation for new CC extensions. | ||||
| - "Unified Extensibility Platform" (UXP): This is the current recommendation for | ||||
|   new Adobe CC extensions in supported apps (Photoshop 2021+ and InDesign 2022+) | ||||
| 
 | ||||
| This demo intends to cover parts relevant to SheetJS.  General setup as well as | ||||
| general Adobe considerations are not covered here.  A basic familiarity with | ||||
|  | ||||
| @ -4,39 +4,88 @@ pagination_prev: demos/cloud/index | ||||
| pagination_next: demos/bigdata/index | ||||
| --- | ||||
| 
 | ||||
| :::warning | ||||
| :::note | ||||
| 
 | ||||
| This demo was written using the Manifest V2 extension platform.  Chrome Web | ||||
| Store will not accept new V2 extensions, but these can be sideloaded using the | ||||
| "Load unpacked" extension option. | ||||
| 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. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| This library is compatible with Chrome and Chromium extensions and should just | ||||
| work out of the box.  Specific API support is listed in the Chrome extensions | ||||
| API documentation. | ||||
| The [Standalone scripts](/docs/getting-started/installation/standalone) can be | ||||
| integrated in a Chromium extension. | ||||
| 
 | ||||
| [Right-Click and download the final CRX](pathname:///chromium/SheetJSDemo.crx) | ||||
| This demo includes examples for exporting bookmarks from a popup and scraping | ||||
| tables with a content script and a background script. | ||||
| 
 | ||||
| :::caution | ||||
| [The demo](#demo) includes unpacked extensions for Manifest V2 and Manifest V3. | ||||
| 
 | ||||
| New releases of Chrome / Chromium will block with `CRX_REQUIRED_PROOF_MISSING`. | ||||
| :::note | ||||
| 
 | ||||
| To try the extension: | ||||
| 
 | ||||
| 1) Right-click and select "Save Link As ..." to save the CRX file | ||||
| 
 | ||||
| 2) Open `chrome://extensions/` in the browser and enable Developer mode | ||||
| 
 | ||||
| 3) Click and drag the downloaded CRX file into the Extensions page to install. | ||||
| This demo was last tested on 2023 June 06 against Chrome 114 | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Loading SheetJS Scripts | ||||
| 
 | ||||
| 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. | ||||
| 
 | ||||
| #### 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 | ||||
| 
 | ||||
| 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 | ||||
| ``` | ||||
| 
 | ||||
| ## Relevant Operations | ||||
| 
 | ||||
| The official documentation covers details including required permissions. | ||||
| 
 | ||||
| ### Generating Downloads | ||||
| 
 | ||||
| #### Manifest V2 | ||||
| 
 | ||||
| The `writeFile` function works in a Chrome or Chromium extension: | ||||
| 
 | ||||
| ```js | ||||
| @ -46,6 +95,21 @@ XLSX.writeFile(wb, "export.xlsx"); | ||||
| Under the hood, it uses the `chrome.downloads` API.  `"downloads"` permission | ||||
| should be set in `manifest.json`. | ||||
| 
 | ||||
| #### 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` | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ### Content Script Table Scraping | ||||
| 
 | ||||
| `table_to_book` and `table_to_sheet` can help build workbooks from DOM tables: | ||||
| @ -64,24 +128,50 @@ for(var i = 0; i < tables.length; ++i) { | ||||
| The demo extension includes multiple features to demonstrate sample usage. | ||||
| Production extensions should include proper error handling. | ||||
| 
 | ||||
| <details><summary><b>Testing Unpacked Extension</b> (click to show)</summary> | ||||
| <details open><summary><b>Testing Unpacked Extension</b> (click to hide)</summary> | ||||
| 
 | ||||
| 1) [Right-Click and download the zip](pathname:///chromium/SheetJSChromiumUnpacked.zip) | ||||
| 1) Download the zip for the desired Manifest version: | ||||
| 
 | ||||
| 2) Create a `SheetJSChromium` folder in your Downloads directory, move the zip | ||||
|    file into the folder, and extract the zip file. | ||||
| - [Manifest V2](pathname:///chromium/SheetJSChromiumUnpackedV2.zip) | ||||
| - [Manifest V3](pathname:///chromium/SheetJSChromiumUnpackedV3.zip) | ||||
| 
 | ||||
| 3) Open `chrome://extensions/` in the browser and enable Developer mode | ||||
| 2) Open `chrome://extensions/` in the browser and enable Developer mode | ||||
| 
 | ||||
| 4) Click "Load Unpacked" and select the `SheetJSChromium` folder. | ||||
| 3) Drag and drop the downloaded zip file into the window. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Bookmark Exporter | ||||
| 
 | ||||
| <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` | ||||
| ``` | ||||
| 
 | ||||
| `chrome.bookmarks` API enables bookmark tree traversal.  The "Export Bookmarks" | ||||
| button in the extension pop-up recursively walks the bookmark tree, pushes the | ||||
| bookmark URLs into a data array, and exports into a simple spreadsheet: | ||||
| bookmark URLs into a data array, and exports into a simple spreadsheet. | ||||
| 
 | ||||
| ```js | ||||
| /* walk the bookmark tree */ | ||||
| @ -108,17 +198,57 @@ chrome.bookmarks.getTree(function(res) { | ||||
| 
 | ||||
| ### Table Exporter | ||||
| 
 | ||||
| The `content.js` content script converts a table in the DOM to workbook object | ||||
| using the `table_to_book` utility function: | ||||
| <details open><summary><b>Testing</b> (click to hide)</summary> | ||||
| 
 | ||||
| ```js | ||||
| // event page script trigger | ||||
| chrome.tabs.sendMessage(tab.id); | ||||
| // content script convert | ||||
| var wb = XLSX.utils.table_to_book(elt); | ||||
| // event page script callback | ||||
| XLSX.writeFile(wb, "export.xlsx"); | ||||
| 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 ... | ||||
| ``` | ||||
| 
 | ||||
| Since the workbook object is a plain JS object, the object is sent back to an | ||||
| event page script which generates the file and attempts a download. | ||||
| #### 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` | ||||
| ``` | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								docz/static/chromium/SheetJSChromiumUnpackedV3.zip
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								docz/static/chromium/SheetJSChromiumUnpackedV3.zip
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										118
									
								
								docz/static/deno/s2c.ts
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										118
									
								
								docz/static/deno/s2c.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | ||||
| // @deno-types="https://cdn.sheetjs.com/xlsx-0.19.3/package/types/index.d.ts"
 | ||||
| import { read, utils, set_cptable, version } from 'https://cdn.sheetjs.com/xlsx-0.19.3/package/xlsx.mjs'; | ||||
| import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.19.3/package/dist/cpexcel.full.mjs'; | ||||
| set_cptable(cptable); | ||||
| 
 | ||||
| import * as Drash from "https://deno.land/x/drash@v2.5.4/mod.ts"; | ||||
| 
 | ||||
| class SheetJSResource extends Drash.Resource { | ||||
|   public paths = ["/"]; | ||||
| 
 | ||||
|   public OPTIONS(request: Drash.Request, response: Drash.Response) { | ||||
|     const allHttpMethods: string[] = [ "GET", "POST", "PUT", "DELETE" ]; | ||||
|     response.headers.set("Allow", allHttpMethods.join()); | ||||
|     response.headers.set("Access-Control-Allow-Methods", allHttpMethods.join()); | ||||
|     response.headers.set("access-control-allow-origin", "*"); | ||||
|     response.status_code = 204; | ||||
|     return response; | ||||
|   } | ||||
| 
 | ||||
|   public POST(request: Drash.Request, response: Drash.Response) { | ||||
|     const file = request.bodyParam<Drash.Types.BodyFile>("file"); | ||||
|     const type = request.bodyParam<string>("type"); | ||||
|     try { response.headers.set("access-control-allow-origin", "*"); } catch(e) {} | ||||
|     if (!file) throw new Error("File is required!"); | ||||
|     var wb = read(file.content, {type: "buffer", dense: true}); | ||||
|     return response.html( (type == "csv" ? utils.sheet_to_csv : utils.sheet_to_html)(wb.Sheets[wb.SheetNames[0]])); | ||||
|   } | ||||
| 
 | ||||
|   public GET(request: Drash.Request, response: Drash.Response): void { | ||||
|     try { response.headers.set("access-control-allow-origin", "*"); } catch(e) {} | ||||
|     return response.html(`\ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>SheetJS Spreadsheet to HTML Conversion Service</title> | ||||
|     <meta charset="utf-8" /> | ||||
| <style> | ||||
| * { | ||||
| 	padding: 0; | ||||
| 	margin: 0; | ||||
| 	box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| html, body { | ||||
| 	width: 100vw; | ||||
| 	max-width: 100%; | ||||
| 	font-size: 16px; | ||||
| 	font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; | ||||
| 	-webkit-font-smoothing: antialiased; | ||||
| 	background: white; | ||||
| 	color: black; | ||||
| } | ||||
| 
 | ||||
| body { | ||||
| 	padding-top: 5px; | ||||
|   max-width: 760px; | ||||
|   margin-left: auto; | ||||
|   margin-right: auto; | ||||
| } | ||||
| 
 | ||||
| table { | ||||
|   border-collapse: collapse; | ||||
| } | ||||
| table, tr, th, td { border: 1px solid; } | ||||
| div { | ||||
|   padding: 5px; | ||||
| } | ||||
| li { margin: 5px 0;} | ||||
| </style> | ||||
|   </head> | ||||
|   <body> | ||||
| <h2><a href="//sheetjs.com/">SheetJS</a> Spreadsheet Conversion Service</h2> | ||||
| <br/> | ||||
| <h3>API</h3> | ||||
| <br/> | ||||
| Send a <code>POST</code> request to <a id="u">https://s2c.sheetjs.com</a> with the file in the <code>file</code> body parameter:<br/>
 | ||||
| <br/> | ||||
| <pre> | ||||
|     curl -X POST -F"file=@pres.numbers" <span id="v">https://s2c.sheetjs.com/</span>
 | ||||
| </pre> | ||||
| <br/> | ||||
| The response will be an HTML TABLE generated from the first worksheet. | ||||
| <br/><br/> | ||||
| For CSV data, pass the parameter <code>type=csv</code>:<br/> | ||||
| <br/> | ||||
| <pre> | ||||
|     curl -X POST -F"file=@pres.numbers" -F"type=csv" <span id="w">https://s2c.sheetjs.com/</span>
 | ||||
| </pre> | ||||
| <br/><br/> | ||||
| <h3>Try it out!</h3> | ||||
| <br/> | ||||
| <form action="/" method="post" enctype="multipart/form-data"> | ||||
| <input type="file" name="file" /><br/><br/> | ||||
| Use the file input element to select a file, then click "Submit"<br/><br/> | ||||
| <button type="submit">Submit</button><br/><br/> | ||||
| </form> | ||||
| 
 | ||||
| SheetJS Library Version: <code>${version}</code> | ||||
|   </body> | ||||
|   <script>w.innerHTML = v.innerHTML = u.innerHTML = u.href = window.location;</script> | ||||
| </html>`,
 | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const server = new Drash.Server({ | ||||
|   hostname: "", | ||||
|   port: 3000, | ||||
|   protocol: "http", | ||||
|   resources: [ | ||||
|     SheetJSResource, | ||||
|   ], | ||||
| }); | ||||
| 
 | ||||
| server.run(); | ||||
| 
 | ||||
| console.log(`Server running at ${server.address}.`); | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user