forked from sheetjs/docs.sheetjs.com
		
	headless
This commit is contained in:
		
							parent
							
								
									b96947e8f4
								
							
						
					
					
						commit
						514ed5f76d
					
				| @ -151,7 +151,7 @@ xport.addEventListener("click", async() => { | ||||
| </script>`} | ||||
| </code></pre> | ||||
| 
 | ||||
| Web Worker support is noted in [the demo](/docs/demos/worker#installation) | ||||
| Web Worker support is noted in [the demo](/docs/demos/bigdata/worker#installation) | ||||
| 
 | ||||
| ## Bower | ||||
| 
 | ||||
|  | ||||
| @ -7,6 +7,7 @@ sidebar_custom_props: | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| # Frameworks and Bundlers | ||||
| 
 | ||||
| @ -84,6 +85,19 @@ yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| When the `xlsx` library is a dependency of a dependency, the `overrides` field | ||||
| in `package.json` can control module resolution: | ||||
| 
 | ||||
| <CodeBlock language="json" title="package.json">{`\ | ||||
| { | ||||
|   // highlight-start | ||||
|   "overrides": { | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz" | ||||
|   } | ||||
|   // highlight-end | ||||
| }`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Encoding support | ||||
|  | ||||
| @ -7,6 +7,7 @@ sidebar_custom_props: | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| # NodeJS | ||||
| 
 | ||||
| @ -80,6 +81,19 @@ yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| When the `xlsx` library is a dependency of a dependency, the `overrides` field | ||||
| in `package.json` can control module resolution: | ||||
| 
 | ||||
| <CodeBlock language="json" title="package.json">{`\ | ||||
| { | ||||
|   // highlight-start | ||||
|   "overrides": { | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz" | ||||
|   } | ||||
|   // highlight-end | ||||
| }`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Vendoring | ||||
|  | ||||
| @ -7,6 +7,7 @@ sidebar_custom_props: | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| # AMD (define) | ||||
| 
 | ||||
| @ -124,27 +125,27 @@ require(["xlsx"], function( | ||||
| When `async` is disabled, the scripts can be referenced directly in `require` | ||||
| calls. | ||||
| 
 | ||||
| ```html | ||||
| <CodeBlock language="html">{`\ | ||||
| <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:0"></script> | ||||
| <script> | ||||
| require([ | ||||
| // highlight-next-line | ||||
|   "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js" | ||||
|   "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js" | ||||
| ], function( | ||||
| // highlight-next-line | ||||
|   _XLSX // !! NOTE: this is not XLSX! A different variable name must be used | ||||
| ) { | ||||
|   // ... use XLSX here | ||||
| }) | ||||
| </script> | ||||
| ``` | ||||
| }); | ||||
| </script>`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| #### Asynchronous Loading | ||||
| 
 | ||||
| When `async` is enabled, Dojo will only understand the name `xlsx`.  The config | ||||
| object can map package names to scripts: | ||||
| 
 | ||||
| ```html | ||||
| <CodeBlock language="html">{`\ | ||||
| <script> | ||||
| // This setting must appear *before* loading dojo.js | ||||
| dojoConfig = { | ||||
| @ -153,18 +154,18 @@ dojoConfig = { | ||||
|     { | ||||
|       name: "xlsx", | ||||
|       // if self-hosting the script, location should be a folder relative to baseUrl setting | ||||
|       location: "https://cdn.sheetjs.com/xlsx-latest/package/dist", | ||||
|       location: "https://cdn.sheetjs.com/xlsx-${current}/package/dist", | ||||
|       // name of the script (without the .js extension) | ||||
|       main: "xlsx.full.min" | ||||
|     } | ||||
|     // highlight-end | ||||
|   ] | ||||
| } | ||||
| }; | ||||
| </script> | ||||
| <script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script> | ||||
| <script> | ||||
| require(["xlsx"], function(_XLSX) { | ||||
|   // ... use XLSX here | ||||
| }); | ||||
| </script> | ||||
| ``` | ||||
| </script>`} | ||||
| </CodeBlock> | ||||
| @ -10,6 +10,7 @@ sidebar_custom_props: | ||||
| import current from '/version.js'; | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| SheetJS predates ECMAScript modules and bundler tools like Webpack. As best | ||||
| practices have evolved, stress testing SheetJS libraries have revealed bugs in | ||||
| @ -799,7 +800,7 @@ other tools using SystemJS have switched to Webpack. | ||||
| SystemJS fails by default because the library does not export anything in the | ||||
| web browser.  The `meta` configuration option can be used to expose `XLSX`: | ||||
| 
 | ||||
| ```js | ||||
| <CodeBlock language="js">{`\ | ||||
| SystemJS.config({ | ||||
|   meta: { | ||||
|     'xlsx': { | ||||
| @ -807,14 +808,14 @@ SystemJS.config({ | ||||
|     } | ||||
|   }, | ||||
|   map: { | ||||
|     'xlsx': 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js', | ||||
|     'xlsx': 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js', | ||||
|     'fs': '',     // <--| | ||||
|     'crypto': '', // <--| suppress native node modules | ||||
|     'stream': ''  // <--| | ||||
|   } | ||||
| }); | ||||
| SystemJS.import('main.js'); // load `main.js` | ||||
| ``` | ||||
| SystemJS.import('main.js'); // load \`main.js\``} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| The `main.js` script can freely `require("xlsx")`. | ||||
| 
 | ||||
|  | ||||
| @ -5,6 +5,7 @@ pagination_next: demos/net/index | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| @ -112,9 +113,9 @@ cd sheetjs-vtl | ||||
| 
 | ||||
| 2) Install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm i -S https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz vue3-table-lite@1.2.4 | ||||
| ``` | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz vue3-table-lite@1.2.4`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 3) Download [`src/App.vue`](pathname:///vtl/App.vue) and replace the contents: | ||||
| 
 | ||||
|  | ||||
| @ -5,6 +5,7 @@ title: Browser Automation | ||||
| import current from '/version.js'; | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| Headless automation involves controlling "headless browsers" to access websites | ||||
| and submit or download data.  It is also possible to automate browsers using | ||||
| @ -31,13 +32,10 @@ sequenceDiagram | ||||
|   U->>C: run script | ||||
|   rect rgba(255, 0, 0, 0.25) | ||||
|     C->>B: launch browser | ||||
|     B->>C: ready | ||||
|     C->>B: load URL | ||||
|     B->>C: site loaded | ||||
|   end | ||||
|   rect rgba(0, 127, 0, 0.25) | ||||
|     C->>B: add SheetJS script | ||||
|     B->>C: script loaded | ||||
|   end | ||||
|   rect rgba(255, 0, 0, 0.25) | ||||
|     C->>B: ask for file | ||||
| @ -50,7 +48,7 @@ sequenceDiagram | ||||
|   end | ||||
| ``` | ||||
| 
 | ||||
| Steps: | ||||
| <details open><summary><b>Key Steps</b> (click to hide)</summary> | ||||
| 
 | ||||
| 1) Launch the headless browser and load the target site. | ||||
| 
 | ||||
| @ -64,6 +62,8 @@ Steps: | ||||
| 
 | ||||
| 4) When the automation context receives data, save to a file | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| This demo exports data from <https://sheetjs.com/demos/table>. | ||||
| 
 | ||||
| :::note | ||||
| @ -76,11 +76,7 @@ the automation context is more efficient and strongly recommended. | ||||
| ## Puppeteer | ||||
| 
 | ||||
| Puppeteer enables headless Chromium automation for NodeJS.  Releases ship with | ||||
| an installer script.  Installation is straightforward: | ||||
| 
 | ||||
| ```bash | ||||
| npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz puppeteer | ||||
| ``` | ||||
| an installer script that prepares a compatible browser version. | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="nodejs" label="NodeJS"> | ||||
| @ -89,10 +85,9 @@ Binary strings are the favored data type.  They can be safely passed from the | ||||
| browser context to the automation script.  NodeJS provides an API to write | ||||
| binary strings to file (`fs.writeFileSync` using encoding `binary`). | ||||
| 
 | ||||
| To run the example, after installing the packages, save the following script to | ||||
| `SheetJSPuppeteer.js` and run `node SheetJSPuppeteer.js`.  Steps are commented: | ||||
| The key steps are commented below: | ||||
| 
 | ||||
| ```js title="SheetJSPuppeteer.js" | ||||
| <CodeBlock language="js" title="SheetJSPuppeteer.js">{`\ | ||||
| const fs = require("fs"); | ||||
| const puppeteer = require('puppeteer'); | ||||
| (async () => { | ||||
| @ -102,34 +97,53 @@ const puppeteer = require('puppeteer'); | ||||
|   page.on("console", msg => console.log("PAGE LOG:", msg.text())); | ||||
|   await page.setViewport({width: 1920, height: 1080}); | ||||
|   await page.goto('https://sheetjs.com/demos/table'); | ||||
| 
 | ||||
| \n\ | ||||
|   /* (2) Load the standalone SheetJS build from the CDN */ | ||||
|   await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js' }); | ||||
| 
 | ||||
|   await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js' }); | ||||
| \n\ | ||||
|   /* (3) Run the snippet in browser and return data */ | ||||
|   const bin = await page.evaluate(() => { | ||||
|     /* NOTE: this function will be evaluated in the browser context. | ||||
|        `page`, `fs` and `puppeteer` are not available. | ||||
|        `XLSX` will be available thanks to step 2 */ | ||||
| 
 | ||||
|        \`page\`, \`fs\` and \`puppeteer\` are not available. | ||||
|        \`XLSX\` will be available thanks to step 2 */ | ||||
| \n\ | ||||
|     /* find first table */ | ||||
|     var table = document.body.getElementsByTagName('table')[0]; | ||||
| 
 | ||||
| \n\ | ||||
|     /* call table_to_book on first table */ | ||||
|     var wb = XLSX.utils.table_to_book(table); | ||||
| 
 | ||||
| \n\ | ||||
|     /* generate XLSB and return binary string */ | ||||
|     return XLSX.write(wb, {type: "binary", bookType: "xlsb"}); | ||||
|   }); | ||||
| 
 | ||||
| \n\ | ||||
|   /* (4) write data to file */ | ||||
|   fs.writeFileSync("SheetJSPuppeteer.xlsb", bin, { encoding: "binary" }); | ||||
| 
 | ||||
| \n\ | ||||
|   await browser.close(); | ||||
| })(); | ||||
| ``` | ||||
| })();`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| This script will generate `SheetJSPuppeteer.xlsb` which can be opened in Excel. | ||||
| **Demo** | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 April 29 against Puppeteer 19.11.1. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Install SheetJS and Puppeteer: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz puppeteer@19.11.1`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 2) Save the `SheetJSPuppeteer.js` code snippet to `SheetJSPuppeteer.js`. | ||||
| 
 | ||||
| 3) Run `node SheetJSPuppeteer.js`. | ||||
| 
 | ||||
| When the script finishes, the file `SheetJSPuppeteer.xlsb` will be created. | ||||
| This file can be opened with Excel. | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="deno" label="Deno"> | ||||
| @ -140,55 +154,67 @@ Deno Puppeteer is a fork. It is not officially supported by the Puppeteer team. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Installation is straightforward: | ||||
| 
 | ||||
| ```bash | ||||
| env PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@14.1.1/install.ts | ||||
| ``` | ||||
| 
 | ||||
| Base64 strings are the favored data type.  They can be safely passed from the | ||||
| browser context to the automation script.  Deno can decode the Base64 strings | ||||
| and write the decoded `Uint8Array` data to file with `Deno.writeFileSync` | ||||
| 
 | ||||
| To run the example, after installing the packages, save the following script to | ||||
| `SheetJSPuppeteer.ts` and run `deno run -A --unstable SheetJSPuppeteer.js`. | ||||
| The key steps are commented below: | ||||
| 
 | ||||
| ```js title="SheetJSPuppeteer.ts" | ||||
| import puppeteer from "https://deno.land/x/puppeteer@14.1.1/mod.ts"; | ||||
| <CodeBlock language="ts" title="SheetJSPuppeteer.ts">{`\ | ||||
| import puppeteer from "https://deno.land/x/puppeteer@16.2.0/mod.ts"; | ||||
| import { decode } from "https://deno.land/std/encoding/base64.ts" | ||||
| 
 | ||||
| \n\ | ||||
| /* (1) Load the target page */ | ||||
| const browser = await puppeteer.launch(); | ||||
| const page = await browser.newPage(); | ||||
| page.on("console", msg => console.log("PAGE LOG:", msg.text())); | ||||
| await page.setViewport({width: 1920, height: 1080}); | ||||
| await page.goto('https://sheetjs.com/demos/table'); | ||||
| 
 | ||||
| \n\ | ||||
| /* (2) Load the standalone SheetJS build from the CDN */ | ||||
| await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js' }); | ||||
| 
 | ||||
| await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js' }); | ||||
| \n\ | ||||
| /* (3) Run the snippet in browser and return data */ | ||||
| const b64 = await page.evaluate(() => { | ||||
|   /* NOTE: this function will be evaluated in the browser context. | ||||
|      `page`, `fs` and `puppeteer` are not available. | ||||
|      `XLSX` will be available thanks to step 2 */ | ||||
| 
 | ||||
|      \`page\`, \`fs\` and \`puppeteer\` are not available. | ||||
|      \`XLSX\` will be available thanks to step 2 */ | ||||
| \n\ | ||||
|   /* find first table */ | ||||
|   var table = document.body.getElementsByTagName('table')[0]; | ||||
| 
 | ||||
| \n\ | ||||
|   /* call table_to_book on first table */ | ||||
|   var wb = XLSX.utils.table_to_book(table); | ||||
| 
 | ||||
| \n\ | ||||
|   /* generate XLSB and return binary string */ | ||||
|   return XLSX.write(wb, {type: "base64", bookType: "xlsb"}); | ||||
| }); | ||||
| /* (4) write data to file */ | ||||
| Deno.writeFileSync("SheetJSPuppeteer.xlsb", decode(b64)); | ||||
| \n\ | ||||
| await browser.close();`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| await browser.close(); | ||||
| **Demo** | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 April 29 against deno-puppeteer 16.2.0. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Install deno-puppeteer: | ||||
| 
 | ||||
| ```bash | ||||
| env PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@16.2.0/install.ts | ||||
| ``` | ||||
| 
 | ||||
| This script will generate `SheetJSPuppeteer.xlsb` which can be opened in Excel. | ||||
| 2) Save the `SheetJSPuppeteer.ts` code snippet to `SheetJSPuppeteer.ts`. | ||||
| 
 | ||||
| 3) Run `deno run -A --unstable SheetJSPuppeteer.ts`. | ||||
| 
 | ||||
| When the script finishes, the file `SheetJSPuppeteer.xlsb` will be created. | ||||
| This file can be opened with Excel. | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| @ -200,15 +226,9 @@ Playwright presents a unified scripting framework for Chromium, WebKit, and | ||||
| other browsers.  It draws inspiration from Puppeteer.  In fact, the example | ||||
| code is almost identical! | ||||
| 
 | ||||
| ```bash | ||||
| npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz playwright | ||||
| ``` | ||||
| Differences from the Puppeteer example are highlighted below: | ||||
| 
 | ||||
| To run the example, after installing the packages, save the following script to | ||||
| `SheetJSPlaywright.js` and run `node SheetJSPlaywright.js`.  Import divergences | ||||
| from the Puppeteer example are highlighted below: | ||||
| 
 | ||||
| ```js title="SheetJSPlaywright.js" | ||||
| <CodeBlock language="js" title="SheetJSPlaywright.js">{`\ | ||||
| const fs = require("fs"); | ||||
| // highlight-next-line | ||||
| const { webkit } = require('playwright'); // import desired browser | ||||
| @ -221,33 +241,53 @@ const { webkit } = require('playwright'); // import desired browser | ||||
|   // highlight-next-line | ||||
|   await page.setViewportSize({width: 1920, height: 1080}); // different name :( | ||||
|   await page.goto('https://sheetjs.com/demos/table'); | ||||
| 
 | ||||
| \n\ | ||||
|   /* (2) Load the standalone SheetJS build from the CDN */ | ||||
|   await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js' }); | ||||
| 
 | ||||
|   await page.addScriptTag({ url: 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js' }); | ||||
| \n\ | ||||
|   /* (3) Run the snippet in browser and return data */ | ||||
|   const bin = await page.evaluate(() => { | ||||
|     /* NOTE: this function will be evaluated in the browser context. | ||||
|        `page`, `fs` and the browser engine are not available. | ||||
|        `XLSX` will be available thanks to step 2 */ | ||||
| 
 | ||||
|        \`page\`, \`fs\` and the browser engine are not available. | ||||
|        \`XLSX\` will be available thanks to step 2 */ | ||||
| \n\ | ||||
|     /* find first table */ | ||||
|     var table = document.body.getElementsByTagName('table')[0]; | ||||
| 
 | ||||
| \n\ | ||||
|     /* call table_to_book on first table */ | ||||
|     var wb = XLSX.utils.table_to_book(table); | ||||
| 
 | ||||
| \n\ | ||||
|     /* generate XLSB and return binary string */ | ||||
|     return XLSX.write(wb, {type: "binary", bookType: "xlsb"}); | ||||
|   }); | ||||
| 
 | ||||
| \n\ | ||||
|   /* (4) write data to file */ | ||||
|   fs.writeFileSync("SheetJSPlaywright.xlsb", bin, { encoding: "binary" }); | ||||
| 
 | ||||
| \n\ | ||||
|   await browser.close(); | ||||
| })(); | ||||
| ``` | ||||
| })();`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| **Demo** | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 April 29 against Playwright 1.33.0. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Install SheetJS and Playwright: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz playwright@1.33.0`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 2) Save the `SheetJSPlaywright.js` code snippet to `SheetJSPlaywright.js`. | ||||
| 
 | ||||
| 3) Run `node SheetJSPlaywright.js`. | ||||
| 
 | ||||
| When the script finishes, the file `SheetJSPlaywright.xlsb` will be created. | ||||
| This file can be opened with Excel. | ||||
| 
 | ||||
| ## PhantomJS | ||||
| 
 | ||||
| @ -265,46 +305,40 @@ Binary strings are the favored data type.  They can be safely passed from the | ||||
| browser context to the automation script.  PhantomJS provides an API to write | ||||
| binary strings to file (`fs.write` using mode `wb`). | ||||
| 
 | ||||
| To run the example, save the following script to `SheetJSPhantom.js` in the same | ||||
| folder as `phantomjs.exe` or `phantomjs` and run | ||||
| 
 | ||||
| ``` | ||||
| ./phantomjs SheetJSPhantom.js     ## MacOS / Linux | ||||
| .\phantomjs.exe SheetJSPhantom.js ## windows | ||||
| ``` | ||||
| <details><summary><b>Integration Details and Demo</b> (click to show)</summary> | ||||
| 
 | ||||
| The steps are marked in the comments: | ||||
| 
 | ||||
| ```js title="SheetJSPhantom.js" | ||||
| <CodeBlock language="js" title="SheetJSPhantom.js">{`\ | ||||
| var page = require('webpage').create(); | ||||
| page.onConsoleMessage = function(msg) { console.log(msg); }; | ||||
| 
 | ||||
| \n\ | ||||
| /* (1) Load the target page */ | ||||
| page.open('https://sheetjs.com/demos/table', function() { | ||||
| 
 | ||||
| \n\ | ||||
|   /* (2) Load the standalone SheetJS build from the CDN */ | ||||
|   page.includeJs("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", function() { | ||||
| 
 | ||||
|   page.includeJs("https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js", function() { | ||||
| \n\ | ||||
|     /* (3) Run the snippet in browser and return data */ | ||||
|     var bin = page.evaluateJavaScript([ "function(){", | ||||
| 
 | ||||
| \n\ | ||||
|       /* find first table */ | ||||
|       "var table = document.body.getElementsByTagName('table')[0];", | ||||
| 
 | ||||
| \n\ | ||||
|       /* call table_to_book on first table */ | ||||
|       "var wb = XLSX.utils.table_to_book(table);", | ||||
| 
 | ||||
| \n\ | ||||
|       /* generate XLSB file and return binary string */ | ||||
|       "return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});", | ||||
|     "}" ].join("")); | ||||
| 
 | ||||
| \n\ | ||||
|     /* (4) write data to file */ | ||||
|     require("fs").write("SheetJSPhantomJS.xlsb", bin, "wb"); | ||||
| 
 | ||||
| \n\ | ||||
|     phantom.exit(); | ||||
|   }); | ||||
| }); | ||||
| ``` | ||||
| });`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| :::caution | ||||
| 
 | ||||
| @ -312,3 +346,28 @@ PhantomJS is very finicky and will hang if there are script errors.  It is | ||||
| strongly recommended to add verbose logging and to lint scripts before use. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| **Demo** | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 April 29 against PhantomJS 2.1.1 | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Download and unzip the PhantomJS release from the official website. | ||||
| 
 | ||||
| 2) Save the `SheetJSPhantom.js` code snippet to `SheetJSPhantom.js`. | ||||
| 
 | ||||
| 3) Run the command. | ||||
| 
 | ||||
| In macOS: | ||||
| 
 | ||||
| ```bash | ||||
| ./phantomjs-2.1.1-macosx/bin/phantomjs SheetJSPhantom.js | ||||
| ``` | ||||
| 
 | ||||
| When the script finishes, the file `SheetJSPhantomJS.xlsb` will be created. | ||||
| This file can be opened with Excel. | ||||
| 
 | ||||
| </details> | ||||
| @ -5,6 +5,7 @@ pagination_next: demos/mobile/index | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| @ -199,9 +200,9 @@ curl -LO https://docs.sheetjs.com/next/sheetjs.xlsx | ||||
| 
 | ||||
| 3) Install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz next@13.1.1 | ||||
| ``` | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz next@13.1.1`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 4) Download test scripts: | ||||
| 
 | ||||
|  | ||||
| @ -8,6 +8,7 @@ sidebar_custom_props: | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| The [NodeJS Module](/docs/getting-started/installation/nodejs) can be imported | ||||
| from the main entrypoint or any script in the project. | ||||
| @ -184,9 +185,9 @@ After adding the lines, the `npm install` command will succeed. | ||||
| 
 | ||||
| 3) Install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm install --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz | ||||
| ``` | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm install --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 4) Add `@ionic-native/file` to the module.  Differences highlighted below: | ||||
| 
 | ||||
|  | ||||
| @ -10,6 +10,7 @@ sidebar_custom_props: | ||||
| import current from '/version.js'; | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| The [Standalone scripts](/docs/getting-started/installation/standalone) can be | ||||
| referenced in a `SCRIPT` tag from the entry point HTML page. | ||||
| @ -114,7 +115,7 @@ This demo was tested against NW.js 0.73.0 on 2023 February 20. | ||||
| 
 | ||||
| 1) Create a `package.json` file that specifies the entry point: | ||||
| 
 | ||||
| ```json title="package.json" | ||||
| <CodeBlock language="json" title="package.json">{`\ | ||||
| { | ||||
|   "name": "sheetjs-nwjs", | ||||
|   "author": "sheetjs", | ||||
| @ -122,10 +123,10 @@ This demo was tested against NW.js 0.73.0 on 2023 February 20. | ||||
|   "main": "index.html", | ||||
|   "dependencies": { | ||||
|     "nw": "~0.73.0", | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz" | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz" | ||||
|   } | ||||
| } | ||||
| ``` | ||||
| }`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 2) Download [`index.html`](pathname:///nwjs/index.html) into the same folder. | ||||
| 
 | ||||
|  | ||||
| @ -7,8 +7,10 @@ sidebar_custom_props: | ||||
|   summary: Webview + Lightweight Extensions | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| The [Standalone build](/docs/getting-started/installation/standalone) can be added | ||||
| to the entry `index.html` | ||||
| @ -134,11 +136,12 @@ npx @neutralinojs/neu create sheetjs-neu | ||||
| cd sheetjs-neu | ||||
| ``` | ||||
| 
 | ||||
| 2) Download the standalone script and place in `resources/js/main.js`: | ||||
| 2) Download [Standalone build](/docs/getting-started/installation/standalone) | ||||
| and place in `resources/js/main.js`: | ||||
| 
 | ||||
| ```bash | ||||
| curl -L -o resources/js/xlsx.full.min.js https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js | ||||
| ``` | ||||
| <CodeBlock language="bash">{`\ | ||||
| curl -L -o resources/js/xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 3) Add the highlighted line to `neutralino.conf.json` in `nativeAllowList`: | ||||
| 
 | ||||
|  | ||||
| @ -11,6 +11,7 @@ sidebar_custom_props: | ||||
| </head> | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| AlaSQL is a pure JavaScript in-memory SQL database.  It has built-in support for | ||||
| SheetJS through the `XLSX` target operator. | ||||
| @ -265,19 +266,19 @@ cd alasql | ||||
| 
 | ||||
| 2) In the folder, create a stub `package.json` with the `xlsx` override: | ||||
| 
 | ||||
| ```json title="package.json" | ||||
| <CodeBlock language="json" title="package.json">{`\ | ||||
| { | ||||
|   "overrides": { | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz" | ||||
|     "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz" | ||||
|   } | ||||
| } | ||||
| ``` | ||||
| }`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 3) Install SheetJS and AlaSQL: | ||||
| 
 | ||||
| ```bash | ||||
| npm i --save alasql@3.1.0 https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz | ||||
| ``` | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save alasql@3.1.0 https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 4) Download the test file <https://sheetjs.com/pres.numbers> : | ||||
| 
 | ||||
|  | ||||
| @ -7,6 +7,7 @@ sidebar_custom_props: | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| MongoDB is a popular document-oriented database engine. | ||||
| 
 | ||||
| @ -73,12 +74,12 @@ in the foreground on Intel MacOS: | ||||
| 
 | ||||
| 2) Create base project and install the dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| <CodeBlock language="bash">{`\ | ||||
| mkdir sheetjs-mongo | ||||
| cd sheetjs-mongo | ||||
| npm init -y | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz mongodb@5.1.0 | ||||
| ``` | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz mongodb@5.1.0`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 3) Save the following to `SheetJSMongoCRUD.mjs` (the key step is highlighted): | ||||
| 
 | ||||
|  | ||||
| @ -6,6 +6,9 @@ sidebar_custom_props: | ||||
|   type: nosql | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| PouchDB is a pure JS database with built-in synchronization features. | ||||
| 
 | ||||
| ## Integration Details | ||||
| @ -63,14 +66,14 @@ cd getting-started-todo-master | ||||
| 
 | ||||
| 2) Edit `index.html` to reference the SheetJS library and add a button: | ||||
| 
 | ||||
| ```html title="index.html" | ||||
| <CodeBlock language="html" title="index.html">{`\ | ||||
|   <body> | ||||
| <!-- highlight-start --> | ||||
|     <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | ||||
|     <script src="https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"></script> | ||||
|     <button id="xport">Export!</button> | ||||
| <!-- highlight-end --> | ||||
|     <section id="todoapp"> | ||||
| ``` | ||||
|     <section id="todoapp">`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 3) Just before the end of `app.js`, add a `click` event listener: | ||||
| 
 | ||||
|  | ||||
| @ -6,6 +6,9 @@ sidebar_custom_props: | ||||
|   summary: Reading and writing files using various platform APIs | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| Reading and writing files require native platform support.  `XLSX.readFile` and | ||||
| `XLSX.writeFile` include support for some APIs. | ||||
| 
 | ||||
| @ -74,7 +77,8 @@ self.addEventListener('message', (e) => { | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ["User-Submitted File" example](/docs/demos/worker#user-submitted-file) has a live demo. | ||||
| ["User-Submitted File" example](/docs/demos/bigdata/worker#user-submitted-file) | ||||
| includes a live demo. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| @ -133,7 +137,8 @@ XLSX.writeFile(wb, "SheetJS.xlsx"); | ||||
| The workaround is to generate the file data from the Worker (using `XLSX.write`) | ||||
| and send the data back to the main context for the actual download action. | ||||
| 
 | ||||
| ["Creating a Local File" includes a live demo](/docs/demos/worker#creating-a-local-file). | ||||
| ["Creating a Local File"](/docs/demos/bigdata/worker#creating-a-local-file) | ||||
| includes a live demo. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -389,13 +394,13 @@ XLSX.writeFile(wb, "sheetjs.csv"); | ||||
| 
 | ||||
| `readFile` uses `Deno.readFileSync` and `writeFile` uses `Deno.writeFileSync`: | ||||
| 
 | ||||
| ```js | ||||
| // @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts" | ||||
| import * as XLSX from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs'; | ||||
| 
 | ||||
| const wb = XLSX.readFile("sheetjs.numbers"); | ||||
| XLSX.writeFile(wb, "sheetjs.xlsx"); | ||||
| ``` | ||||
| <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 wb: XLSX.WorkBook = XLSX.readFile("sheetjs.numbers"); | ||||
| XLSX.writeFile(wb, "sheetjs.xlsx");`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| :::caution Deno entitlements | ||||
| 
 | ||||
|  | ||||
| @ -136,12 +136,12 @@ cd SheetJSLambda | ||||
| curl -LO https://docs.sheetjs.com/aws/index.js | ||||
| ``` | ||||
| 
 | ||||
| 2) Install dependencies to the current directory; | ||||
| 2) Install dependencies in the project directory; | ||||
| 
 | ||||
| ```bash | ||||
| <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | ||||
| mkdir -p node_modules | ||||
| npm install https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz busboy | ||||
| ``` | ||||
| npm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz busboy`} | ||||
| </code></pre> | ||||
| 
 | ||||
| 3) Create a .zip package of the contents of the folder: | ||||
| 
 | ||||
|  | ||||
| @ -5,6 +5,7 @@ pagination_next: demos/extensions/index | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| Azure is a Cloud Services platform which includes traditional virtual machine | ||||
| support, "Serverless Functions", cloud storage and much more. | ||||
| @ -21,7 +22,7 @@ and the "Serverless Function" platform ("Azure Functions"). | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This was tested on 2022 August 21. | ||||
| This was tested on 2023 April 29. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -113,19 +114,18 @@ module.exports = (context, req) => { | ||||
| 
 | ||||
| ### Demo | ||||
| 
 | ||||
| <details><summary><b>Complete Example</b> (click to show)</summary> | ||||
| <details open><summary><b>Complete Example</b> (click to show)</summary> | ||||
| 
 | ||||
| 0) Review the quick start for JavaScript on Azure Functions.  This involves | ||||
| installing the Azure Functions Core Tools and other dependencies. | ||||
| 
 | ||||
| 1) Create a new project and install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| <CodeBlock language="bash">{`\ | ||||
| func init sheetjs-azure --worker-runtime node --language javascript | ||||
| cd sheetjs-azure | ||||
| npm i | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz formidable | ||||
| ``` | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz formidable`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 2) Create a new "HTTP Trigger" function: | ||||
| 
 | ||||
| @ -142,58 +142,10 @@ func new --template "Http Trigger" --name SheetJSAzure | ||||
|       "name": "req", | ||||
| ``` | ||||
| 
 | ||||
| 4) Replace `SheetJSAzure/index.js` with the following: | ||||
| 4) Download [`SheetJSAzure/index.js`](pathname:///aws/index.js): | ||||
| 
 | ||||
| ```js title="SheetJSAzure/index.js" | ||||
| /* sheetjs (C) 2013-present SheetJS -- https://sheetjs.com */ | ||||
| const XLSX = require('xlsx'); | ||||
| const formidable = require('formidable'); | ||||
| const Readable = require('stream').Readable; | ||||
| 
 | ||||
| /* formidable expects the request object to be a stream */ | ||||
| const streamify = (req) => { | ||||
|     if(typeof req.on !== 'undefined') return req; | ||||
|     const s = new Readable(); | ||||
|     s._read = ()=>{}; | ||||
|     s.push(Buffer.from(req.body)); | ||||
|     s.push(null); | ||||
|     Object.assign(s, req); | ||||
|     return s; | ||||
| }; | ||||
| 
 | ||||
| module.exports = (context, req) => { | ||||
|   if(req.method == "POST") { | ||||
|     const form = new formidable.IncomingForm(); | ||||
|     form.parse(streamify(req), (err, fields, files) => { | ||||
|       /* grab the first file */ | ||||
|       var f = files["upload"]; | ||||
|       if(!f) { | ||||
|         context.res = { status: 400, body: "Must submit a file for processing!" }; | ||||
|       } else { | ||||
|         /* file is stored in a temp directory, so we can point to that and read it */ | ||||
|         const wb = XLSX.read(f.filepath, {type:"file"}); | ||||
| 
 | ||||
|         /* generate CSV from first sheet */ | ||||
|         const csv = XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]); | ||||
|         context.res = { status: 200, body: csv }; | ||||
|       } | ||||
|       context.done(); | ||||
|     }); | ||||
|   } else if(req.method == "GET") { | ||||
|     var ws = XLSX.utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]); | ||||
|     var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Data"); | ||||
|     var buf = XLSX.write(wb, {type: "buffer", bookType: "xlsx"}); | ||||
|     context.res = { | ||||
|       status: 200, | ||||
|       headers: { "Content-Disposition": `attachment; filename="SheetJSAzure.xlsx";` }, | ||||
|       body: buf | ||||
|     }; | ||||
|     context.done(); | ||||
|   } else { | ||||
|     context.res = { status: 500, body: `Unsupported method ${req.method}` }; | ||||
|     context.done(); | ||||
|   } | ||||
| }; | ||||
| ```bash | ||||
| curl -L -o SheetJSAzure/index.js https://docs.sheetjs.com/azure/index.js | ||||
| ``` | ||||
| 
 | ||||
| 5) Test locally with `npm start` | ||||
| @ -201,6 +153,7 @@ module.exports = (context, req) => { | ||||
| To test uploads, download <https://sheetjs.com/pres.numbers> and run: | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://sheetjs.com/pres.numbers | ||||
| curl -X POST -F "upload=@pres.numbers" http://localhost:7071/api/SheetJSAzure | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
| @ -141,8 +141,8 @@ for further processing. | ||||
| :::note | ||||
| 
 | ||||
| For Chromium browsers, the File System Access API provides a modern worker-only | ||||
| approach. [The Web Workers demo](/docs/demos/worker#streaming-write) includes a | ||||
| live example of CSV streaming write. | ||||
| approach. [The Web Workers demo](/docs/demos/bigdata/worker#streaming-write) | ||||
| includes a live example of CSV streaming write. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -255,8 +255,8 @@ strm.resume(); | ||||
| #### Web Workers | ||||
| 
 | ||||
| For processing large files in the browser, it is strongly encouraged to use Web | ||||
| Workers. The [Worker demo](/docs/demos/worker#streaming-write) includes examples | ||||
| using the File System Access API. | ||||
| Workers. The [Worker demo](/docs/demos/bigdata/worker#streaming-write) includes | ||||
| examples using the File System Access API. | ||||
| 
 | ||||
| Typically, the file and stream processing occurs in the Web Worker.  CSV rows | ||||
| can be sent back to the main thread in the callback: | ||||
|  | ||||
| @ -6,6 +6,9 @@ sidebar_custom_props: | ||||
|   summary: Run large data flows without freezing the browser | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| Parsing and writing large spreadsheets takes time. During the process, if the | ||||
| SheetJS library is running in the web browser, the website may freeze. | ||||
| 
 | ||||
| @ -82,36 +85,36 @@ typically workers are written in separate JS files. | ||||
| 
 | ||||
| For example, an in-line worker like | ||||
| 
 | ||||
| ```js | ||||
|   const worker = new Worker(URL.createObjectURL(new Blob([`\ | ||||
| <CodeBlock language="js">{`\ | ||||
|   const worker = new Worker(URL.createObjectURL(new Blob([\`\\ | ||||
| /* load standalone script from CDN */ | ||||
| importScripts("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"); | ||||
| 
 | ||||
| importScripts("https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"); | ||||
| \n\ | ||||
| /* this callback will run once the main context sends a message */ | ||||
| self.addEventListener('message', (e) => { | ||||
|   /* Pass the version string back  */ | ||||
|   postMessage({ version: XLSX.version }); | ||||
| }, false); | ||||
|   `]))); | ||||
| ``` | ||||
|   \`])));`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| would typically be stored in a separate JS file like "worker.js": | ||||
| 
 | ||||
| ```js title="worker.js" | ||||
| <CodeBlock language="js" title="worker.js">{`\ | ||||
| /* load standalone script from CDN */ | ||||
| importScripts("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"); | ||||
| 
 | ||||
| importScripts("https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"); | ||||
| \n\ | ||||
| /* this callback will run once the main context sends a message */ | ||||
| self.addEventListener('message', (e) => { | ||||
|   /* Pass the version string back  */ | ||||
|   postMessage({ version: XLSX.version }); | ||||
| }, false); | ||||
| ``` | ||||
| }, false);`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| and the main script would pass a URL: | ||||
| and the main script would pass a URL to the `Worker` constructor: | ||||
| 
 | ||||
| ```js | ||||
|   const worker = new Worker("./worker.js"); | ||||
| const worker = new Worker("./worker.js"); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| @ -122,9 +125,9 @@ and the main script would pass a URL: | ||||
| 
 | ||||
| In all cases, `importScripts` in a Worker can load the [Standalone scripts](/docs/getting-started/installation/standalone) | ||||
| 
 | ||||
| ```js | ||||
| importScripts("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"); | ||||
| ``` | ||||
| <CodeBlock language="js">{`\ | ||||
| importScripts("https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js");`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| For production use, it is highly encouraged to download and host the script. | ||||
| 
 | ||||
| @ -141,9 +144,9 @@ For legacy browsers like Firefox and IE, `importScripts` should be used. | ||||
| 
 | ||||
| Browser ESM imports require a complete URL including the `.mjs` extension: | ||||
| 
 | ||||
| ```js | ||||
| import * as XLSX from "https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs"; | ||||
| ``` | ||||
| <CodeBlock language="js">{`\ | ||||
| import * as XLSX from "https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs";`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| When using Worker ESM, the Worker constructor must set the `type` option: | ||||
| 
 | ||||
|  | ||||
| @ -245,8 +245,8 @@ document.getElementById('file-object').addEventListener("change", function(e) { | ||||
| #### Browser is stuck! | ||||
| 
 | ||||
| By default, operations run in the main renderer context and block the browser | ||||
| from updating. [Web Workers](/docs/demos/worker) offload the hard work to separate | ||||
| contexts, freeing up the renderer to update. | ||||
| from updating. [Web Workers](/docs/demos/bigdata/worker) offload the hard work | ||||
| to separate contexts, freeing up the renderer to update. | ||||
| 
 | ||||
| #### Strange exported file names in the web browser | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										49
									
								
								docz/static/azure/index.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										49
									
								
								docz/static/azure/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| /* sheetjs (C) SheetJS -- https://sheetjs.com */ | ||||
| const XLSX = require('xlsx'); | ||||
| const formidable = require('formidable'); | ||||
| const Readable = require('stream').Readable; | ||||
| 
 | ||||
| /* formidable expects the request object to be a stream */ | ||||
| const streamify = (req) => { | ||||
|     if(typeof req.on !== 'undefined') return req; | ||||
|     const s = new Readable(); | ||||
|     s._read = ()=>{}; | ||||
|     s.push(Buffer.from(req.body)); | ||||
|     s.push(null); | ||||
|     Object.assign(s, req); | ||||
|     return s; | ||||
| }; | ||||
| 
 | ||||
| module.exports = (context, req) => { | ||||
|   if(req.method == "POST") { | ||||
|     const form = new formidable.IncomingForm(); | ||||
|     form.parse(streamify(req), (err, fields, files) => { | ||||
|       /* grab the first file */ | ||||
|       var f = files["upload"]; | ||||
|       if(!f) { | ||||
|         context.res = { status: 400, body: "Must submit a file for processing!" }; | ||||
|       } else { | ||||
|         /* file is stored in a temp directory, so we can point to that and read it */ | ||||
|         const wb = XLSX.read(f.filepath, {type:"file"}); | ||||
| 
 | ||||
|         /* generate CSV from first sheet */ | ||||
|         const csv = XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]); | ||||
|         context.res = { status: 200, body: csv }; | ||||
|       } | ||||
|       context.done(); | ||||
|     }); | ||||
|   } else if(req.method == "GET") { | ||||
|     var ws = XLSX.utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]); | ||||
|     var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Data"); | ||||
|     var buf = XLSX.write(wb, {type: "buffer", bookType: "xlsx"}); | ||||
|     context.res = { | ||||
|       status: 200, | ||||
|       headers: { "Content-Disposition": `attachment; filename="SheetJSAzure.xlsx";` }, | ||||
|       body: buf | ||||
|     }; | ||||
|     context.done(); | ||||
|   } else { | ||||
|     context.res = { status: 500, body: `Unsupported method ${req.method}` }; | ||||
|     context.done(); | ||||
|   } | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user