forked from sheetjs/docs.sheetjs.com
		
	Demo refresh
This commit is contained in:
		
							parent
							
								
									467af52e4f
								
							
						
					
					
						commit
						d953a625a2
					
				| @ -302,7 +302,7 @@ | ||||
|     <Cell><Data ss:Type="String">Rust</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell> | ||||
|  | ||||
| @ -99,7 +99,7 @@ | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✘</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String"> </Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String">✘</Data></Cell> | ||||
|     <Cell ss:StyleID="s16"><Data ss:Type="String"> </Data></Cell> | ||||
|    </Row> | ||||
|  | ||||
| @ -123,7 +123,7 @@ This demo was last tested in the following deployments: | ||||
| |:-------------|:---------|:-----------| | ||||
| | `darwin-x64` | `1.2.8`  | 2025-03-31 | | ||||
| | `darwin-arm` | `1.2.7`  | 2025-03-30 | | ||||
| | `win11-x64`  | `1.1.42` | 2024-12-22 | | ||||
| | `win11-x64`  | `1.2.8`  | 2025-04-17 | | ||||
| | `win11-arm`  | `1.2.3`  | 2025-02-23 | | ||||
| | `linux-x64`  | `1.1.40` | 2024-12-19 | | ||||
| | `linux-arm`  | `1.2.2`  | 2025-02-16 | | ||||
|  | ||||
| @ -35,7 +35,7 @@ This demo was tested in the following configurations: | ||||
| 
 | ||||
| | Platform                                                          | Architecture | Date       | | ||||
| |:------------------------------------------------------------------|:-------------|:-----------| | ||||
| | NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM)       | `win11-x64`  | 2025-03-06 | | ||||
| | NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM)       | `win11-x64`  | 2025-04-17 | | ||||
| | NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM)       | `linux-x64`  | 2025-01-28 | | ||||
| | AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM)       | `win11-x64`  | 2025-01-12 | | ||||
| | AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM)       | `linux-x64`  | 2025-01-29 | | ||||
| @ -853,7 +853,7 @@ npm i --save https://sheet.lol/balls/xlsx-${current}.tgz`} | ||||
| 4) Install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm i --save @langchain/core@0.3.42 langchain@0.3.19 @langchain/ollama@0.2.0 peggy@3.0.2 | ||||
| npm i --save @langchain/core@0.3.44 langchain@0.3.21 @langchain/ollama@0.2.0 peggy@3.0.2 | ||||
| ``` | ||||
| 
 | ||||
| :::note pass | ||||
| @ -862,7 +862,7 @@ In some test runs, there were error messages relating to dependency and peer | ||||
| dependency versions. The `--force` flag will suppress version mismatch errors: | ||||
| 
 | ||||
| ```bash | ||||
| npm i --save @langchain/core@0.3.42 langchain@0.3.19 @langchain/ollama@0.2.0 peggy@3.0.2 --force | ||||
| npm i --save @langchain/core@0.3.44 langchain@0.3.21 @langchain/ollama@0.2.0 peggy@3.0.2 --force | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
|  | ||||
| @ -295,7 +295,9 @@ This demo was tested in the following deployments: | ||||
| 
 | ||||
| | Architecture | Date       | | ||||
| |:-------------|:-----------| | ||||
| | `darwin-x64` | 2025-04-17 | | ||||
| | `darwin-arm` | 2024-10-15 | | ||||
| | `win11-x64`  | 2025-04-17 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
|  | ||||
| @ -127,11 +127,14 @@ That approach is not explored in this demo. | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| | NodeJS    | Date       | Dependencies                        | | ||||
| |:----------|:-----------|:------------------------------------| | ||||
| | `18.20.3` | 2024-06-30 | ExpressJS 4.19.2 + Formidable 2.1.2 | | ||||
| | `20.15.0` | 2024-06-30 | ExpressJS 4.19.2 + Formidable 2.1.2 | | ||||
| | `22.3.0`  | 2024-06-30 | ExpressJS 4.19.2 + Formidable 2.1.2 | | ||||
| | NodeJS    | Date       | ExpressJS | | ||||
| |:----------|:-----------|:----------| | ||||
| | `18.20.8` | 2025-04-17 | `5.1.0`   | | ||||
| | `20.18.0` | 2025-04-17 | `5.1.0`   | | ||||
| | `22.14.0` | 2025-04-17 | `5.1.0`   | | ||||
| | `18.20.8` | 2025-04-17 | `4.21.2`  | | ||||
| | `20.18.0` | 2025-04-17 | `4.21.2`  | | ||||
| | `22.14.0` | 2025-04-17 | `4.21.2`  | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
|  | ||||
| @ -49,10 +49,11 @@ flowchart LR | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| | SvelteJS         | Kit      | Date       | | ||||
| |:-----------------|:---------|:-----------| | ||||
| | `4.2.17`         | `2.5.10` | 2024-06-03 | | ||||
| | `5.0.0-next.149` | `2.5.10` | 2024-06-03 | | ||||
| | SvelteJS  | Kit      | Date       | | ||||
| |:----------|:---------|:-----------| | ||||
| | `5.27.2`  | `2.20.7` | 2025-04-17 | | ||||
| | `4.2.19`  | `2.5.10` | 2025-04-17 | | ||||
| | `3.59.2`  | `1.30.4` | 2025-04-17 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -189,7 +190,35 @@ When this demo was last tested, SvelteKit required NodeJS major version 20. | ||||
| 1) Create a new site: | ||||
| 
 | ||||
| ```bash | ||||
| npm create svelte@latest sheetjs-svelte | ||||
| mkdir -p sheetjs-svelte | ||||
| cd sheetjs-svelte | ||||
| npx sv create | ||||
| ``` | ||||
| 
 | ||||
| When prompted: | ||||
| 
 | ||||
| - `Where would you like your project to be created?`: press <kbd>Enter</kbd> | ||||
| - `Which template would you like?` select `SvelteKit minimal` | ||||
| - `Add type checking with TypeScript?` select `Yes, using JavaScript with JSDoc` | ||||
| - `What would you like to add to your project?` press <kbd>Enter</kbd> (do not select options) | ||||
| - `Which package manager do you want to install dependencies with?`: select `npm` and press <kbd>Enter</kbd> | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Older SvelteJS versions</b> (click to show)</summary> | ||||
| 
 | ||||
| The following commands create SvelteJS projects for older versions: | ||||
| 
 | ||||
| **SvelteJS 3.x** | ||||
| 
 | ||||
| ```bash | ||||
| npm create svelte@4 sheetjs-svelte | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
| **SvelteJS 4.x** | ||||
| 
 | ||||
| ```bash | ||||
| npm create svelte@6 sheetjs-svelte | ||||
| ``` | ||||
| 
 | ||||
| When prompted: | ||||
| @ -198,19 +227,21 @@ When prompted: | ||||
| - `Add type checking with TypeScript?` select `Yes, using JavaScript with JSDoc` | ||||
| - `Select additional options` press <kbd>Enter</kbd> (do not select options) | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| To test the Svelte 5 beta, select `Try the Svelte 5 preview (unstable!)` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 2) Enter the project folder and install dependencies: | ||||
| After creating the project, enter the project folder and install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| cd sheetjs-svelte | ||||
| npm i | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 2) Install dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm i | ||||
| ``` | ||||
| 
 | ||||
| 3) Fetch the example file [`pres.xlsx`](https://docs.sheetjs.com/pres.xlsx) and | ||||
| move to a `data` subdirectory in the root of the project: | ||||
| 
 | ||||
| @ -311,6 +342,14 @@ observe that the data from the spreadsheet is displayed in the page. | ||||
| 11) In the spreadsheet, set cell A7 to `SheetJS Dev` and cell B7 to `47`.  Save | ||||
| the file.  After saving, the browser should automatically refresh with new data. | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| **Live reloading may not work in newer projects!** | ||||
| 
 | ||||
| If the page does not reload, manually refresh the page. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Static Site | ||||
| 
 | ||||
| 12) Stop the development server and install the static adapter: | ||||
|  | ||||
| @ -45,16 +45,16 @@ This demo was tested in the following environments: | ||||
| 
 | ||||
| | OS         | Device              | Quasar   | Date       | | ||||
| |:-----------|:--------------------|:---------|:-----------| | ||||
| | Android 30 | NVIDIA Shield       | `2.16.4` | 2024-06-09 | | ||||
| | iOS 15.1   | iPad Pro            | `2.16.4` | 2024-06-09 | | ||||
| | Android 34 | NVIDIA Shield       | `2.18.1` | 2025-04-17 | | ||||
| | iOS 15.1   | iPad Pro            | `2.18.1` | 2025-04-17 | | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device              | Quasar   | Dev Platform | Date       | | ||||
| |:-----------|:--------------------|:---------|:-------------|:-----------| | ||||
| | Android 34 | Pixel 3a            | `2.16.4` | `darwin-arm` | 2024-06-09 | | ||||
| | iOS 17.5   | iPhone SE (3rd gen) | `2.16.4` | `darwin-arm` | 2024-06-09 | | ||||
| | Android 35 | Pixel 3a            | `2.16.9` | `win11-x64`  | 2024-08-20 | | ||||
| | Android 35 | Pixel 9 Pro XL      | `2.18.1` | `darwin-arm` | 2025-04-17 | | ||||
| | iOS 18.2   | iPhone 16 Pro Max   | `2.18.1` | `darwin-arm` | 2025-04-17 | | ||||
| | Android 36 | Pixel 9 Pro XL      | `2.18.1` | `win11-x64`  | 2025-04-17 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -167,13 +167,23 @@ window.requestFileSystem(window.PERSISTENT, 0, function(fs) { | ||||
| The demo draws from the ViteJS example.  Familiarity with VueJS and TypeScript | ||||
| is assumed. | ||||
| 
 | ||||
| ### Platform Setup | ||||
| 
 | ||||
| 0) Ensure all of the dependencies are installed.  Install the CLI globally: | ||||
| 
 | ||||
| ```bash | ||||
| npm i -g @quasar/cli cordova | ||||
| ``` | ||||
| 
 | ||||
| (you may need to run `sudo npm i -g` if there are permission issues) | ||||
| :::note pass | ||||
| 
 | ||||
| In some systems, the command must be run as the root user: | ||||
| 
 | ||||
| ```bash | ||||
| sudo npm i -g @quasar/cli cordova | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Installation Notes</b> (click to show)</summary> | ||||
| @ -182,6 +192,8 @@ Quasar requires Java 17 | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Base Project | ||||
| 
 | ||||
| 1) Create a new app: | ||||
| 
 | ||||
| ```bash | ||||
| @ -194,14 +206,12 @@ When prompted: | ||||
| 
 | ||||
| - "What would you like to build?": `App with Quasar CLI, let's go!` | ||||
| - "Project folder": `SheetJSQuasar` | ||||
| - "Pick Quasar version": `Quasar v2 (Vue 3 | latest and greatest)` | ||||
| - "Pick script type": `Typescript` | ||||
| - "Pick Quasar App CLI variant": `Quasar App CLI with Vite 2 (stable | v1)` | ||||
| - "Pick Quasar App CLI variant": `Quasar App CLI with Vite` | ||||
| - "Package name": (press <kbd>Enter</kbd>, it will use the default `sheetjsquasar`) | ||||
| - "Project product name": `SheetJSQuasar` | ||||
| - "Project description": `SheetJS + Quasar` | ||||
| - "Author": (press <kbd>Enter</kbd>, it will use Git settings) | ||||
| - "Pick a Vue component style": `Composition API` | ||||
| - "Pick a Vue component style": `Composition API with <script setup>` | ||||
| - "Pick your CSS preprocessor": `None` | ||||
| - "Check the features needed for your project": Deselect everything (scroll down to each selected item and press <kbd>Space</kbd>) | ||||
| - "Install project dependencies": `Yes, use npm` | ||||
| @ -221,17 +231,96 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| ```bash | ||||
| npx cordova telemetry off | ||||
| npx quasar mode add cordova | ||||
| npx quasar mode remove capacitor | ||||
| ``` | ||||
| 
 | ||||
| When prompted, enter the app id `org.sheetjs.quasar`. | ||||
| 
 | ||||
| It will create a new `src-cordova` folder. Continue in that folder: | ||||
| 4) Add the Dialog plugin to the `plugins` array in `quasar.config.ts`: | ||||
| 
 | ||||
| ```js title="quasar.config.ts (edit highlighted line)" | ||||
|       // Quasar plugins | ||||
|       // highlight-next-line | ||||
|       plugins: ['Dialog'] | ||||
| ``` | ||||
| 
 | ||||
| 5) Download [`IndexPage.vue`](pathname:///quasar/IndexPage.vue) and replace the | ||||
| existing page script `src/pages/IndexPage.vue`: | ||||
| 
 | ||||
| ```bash | ||||
| curl -L -o src/pages/IndexPage.vue https://docs.sheetjs.com/quasar/IndexPage.vue | ||||
| ``` | ||||
| 
 | ||||
| ### Android | ||||
| 
 | ||||
| 6) Create the Android project: | ||||
| 
 | ||||
| ```bash | ||||
| cd src-cordova | ||||
| npx cordova platform add android | ||||
| npx cordova plugin add cordova-plugin-wkwebview-engine | ||||
| npx cordova plugin add cordova-plugin-file | ||||
| cd .. | ||||
| ``` | ||||
| 
 | ||||
| 7) Start the simulator: | ||||
| 
 | ||||
| ```bash | ||||
| npx quasar dev -m cordova -T android | ||||
| ``` | ||||
| 
 | ||||
| If prompted to select an external IP, press <kbd>Enter</kbd>. | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| If the app is blank or not refreshing, delete the app and close the simulator, | ||||
| then restart the development process. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::info pass | ||||
| 
 | ||||
| In some test runs, the command failed with a Gradle error | ||||
| 
 | ||||
| ``` | ||||
| Could not find an installed version of Gradle either in Android Studio, | ||||
| or on your system to install the gradle wrapper. Please include gradle | ||||
| in your path, or install Android Studio | ||||
| ``` | ||||
| 
 | ||||
| [Gradle](https://gradle.org/) (the complete version) must be extracted and the | ||||
| `bin` folder must be added to the user PATH variable. After adding to PATH, | ||||
| launch a new PowerShell or Command Prompt window and run the command. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| To test that reading works: | ||||
| 
 | ||||
| - Download https://docs.sheetjs.com/pres.numbers | ||||
| - Open the Downloads folder in Finder or Explorer | ||||
| - Click and drag `pres.numbers` from the window into the simulator. | ||||
| - Tap "Load File", tap the `≡` icon, tap "Downloads" and select `pres.numbers`. | ||||
| 
 | ||||
| To test that writing works: | ||||
| 
 | ||||
| - Tap "Save File".  You will see a popup with a location. | ||||
| - Pull the file from the simulator and verify the contents: | ||||
| 
 | ||||
| ```bash | ||||
| adb exec-out run-as org.sheetjs.quasar cat files/files/SheetJSQuasar.xlsx > /tmp/SheetJSQuasar.xlsx | ||||
| npx xlsx-cli /tmp/SheetJSQuasar.xlsx | ||||
| ``` | ||||
| 
 | ||||
| ### iOS | ||||
| 
 | ||||
| 8) Create the iOS project: | ||||
| 
 | ||||
| ```bash | ||||
| cd src-cordova | ||||
| npx cordova platform add ios | ||||
| npx cordova plugin add cordova-plugin-wkwebview-engine | ||||
| npx cordova plugin add cordova-plugin-file | ||||
| cd .. | ||||
| ``` | ||||
| 
 | ||||
| :::note pass | ||||
| @ -246,13 +335,7 @@ npx cordova plugin add cordova-plugin-file | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Return to the project directory: | ||||
| 
 | ||||
| ```bash | ||||
| cd .. | ||||
| ``` | ||||
| 
 | ||||
| 4) Enable file sharing and make the documents folder visible in the iOS app. | ||||
| 9) Enable file sharing and make the documents folder visible in the iOS app. | ||||
| The following lines must be added to `src-cordova/platforms/ios/SheetJSQuasar/SheetJSQuasar-Info.plist`: | ||||
| 
 | ||||
| ```xml title="src-cordova/platforms/ios/SheetJSQuasar/SheetJSQuasar-Info.plist (add to file)" | ||||
| @ -270,10 +353,10 @@ The following lines must be added to `src-cordova/platforms/ios/SheetJSQuasar/Sh | ||||
| (The root element of the document is `plist` and it contains one `dict` child) | ||||
| 
 | ||||
| 
 | ||||
| 5) Start the development server: | ||||
| 10) Start the development server: | ||||
| 
 | ||||
| ```bash | ||||
| npx quasar dev -m ios | ||||
| npx quasar dev -m cordova -T ios | ||||
| ``` | ||||
| 
 | ||||
| If prompted to select an external IP, press <kbd>Enter</kbd>. | ||||
| @ -285,52 +368,6 @@ then restart the development process. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 6) Add the Dialog plugin to `quasar.config.js`: | ||||
| 
 | ||||
| ```js title="quasar.config.js (add highlighted line)" | ||||
|     framework: { | ||||
|       config: {}, | ||||
| // ... | ||||
|       // Quasar plugins | ||||
|       // highlight-next-line | ||||
|       plugins: ['Dialog'] | ||||
|     }, | ||||
| ``` | ||||
| 
 | ||||
| 7) In the template section of `src/pages/IndexPage.vue`, replace the example | ||||
|    with a Table, Save button and Load file picker component: | ||||
| 
 | ||||
| ```html title="src/pages/IndexPage.vue (change highlighted lines)" | ||||
| <template> | ||||
|   <q-page class="row items-center justify-evenly"> | ||||
|     <!-- highlight-start --> | ||||
|     <q-table :rows="todos" /> | ||||
|     <q-btn-group> | ||||
|       <q-file label="Load File" filled label-color="orange" @input="updateFile"/> | ||||
|       <q-btn label="Save File" @click="saveFile" /> | ||||
|     </q-btn-group> | ||||
|     <!-- highlight-end --> | ||||
|   </q-page> | ||||
| </template> | ||||
| ``` | ||||
| 
 | ||||
| This uses two functions that should be added to the component script: | ||||
| 
 | ||||
| ```ts title="src/pages/IndexPage.vue (add highlighted lines)" | ||||
|     const meta = ref<Meta>({ | ||||
|       totalCount: 1200 | ||||
|     }); | ||||
| // highlight-start | ||||
|     function saveFile() { | ||||
|     } | ||||
|     async function updateFile(v: Event) { | ||||
|     } | ||||
|     return { todos, meta, saveFile, updateFile }; | ||||
| // highlight-end | ||||
|   } | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| The app should now show two buttons at the bottom: | ||||
| 
 | ||||
|  | ||||
| @ -342,38 +379,6 @@ then restart the development process. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 8) Wire up the `updateFile` function: | ||||
| 
 | ||||
| ```ts title="src/pages/IndexPage.vue (add highlighted lines)" | ||||
| import { defineComponent, ref } from 'vue'; | ||||
| // highlight-start | ||||
| import { read, write, utils } from 'xlsx'; | ||||
| import { useQuasar } from 'quasar'; | ||||
| // highlight-end | ||||
| 
 | ||||
| export default defineComponent({ | ||||
| // ... | ||||
| // highlight-start | ||||
|     const $q = useQuasar(); | ||||
|     function dialogerr(e: Error) { $q.dialog({title: "Error!", message: e.message || String(e)}); } | ||||
| // highlight-end | ||||
|     function saveFile() { | ||||
|     } | ||||
|     async function updateFile(v: Event) { | ||||
| // highlight-start | ||||
|       try { | ||||
|         const files = (v.target as HTMLInputElement).files; | ||||
|         if(!files || files.length == 0) return; | ||||
| 
 | ||||
|         const wb = read(await files[0].arrayBuffer()); | ||||
| 
 | ||||
|         const data = utils.sheet_to_json<any>(wb.Sheets[wb.SheetNames[0]]); | ||||
|         todos.value = data.map(row => ({id: row.Index, content: row.Name})); | ||||
|       } catch(e) { dialogerr(e); } | ||||
| // highlight-end | ||||
|     } | ||||
| ``` | ||||
| 
 | ||||
| To test that reading works: | ||||
| 
 | ||||
| - Download https://docs.sheetjs.com/pres.numbers | ||||
| @ -391,46 +396,11 @@ To test that reading works: | ||||
| 
 | ||||
| Once selected, the screen should refresh with new contents. | ||||
| 
 | ||||
| 9) Wire up the `saveFile` function: | ||||
| 
 | ||||
| ```ts title="src/pages/IndexPage.vue (add highlighted lines)" | ||||
|     function saveFile() { | ||||
| // highlight-start | ||||
|       /* generate workbook from state */ | ||||
|       const ws = utils.json_to_sheet(todos.value); | ||||
|       const wb = utils.book_new(); | ||||
|       utils.book_append_sheet(wb, ws, "SheetJSQuasar"); | ||||
|       const u8: Uint8Array = write(wb, {bookType: "xlsx", type: "buffer"}); | ||||
|       const dir: string = $q.cordova.file.documentsDirectory || $q.cordova.file.externalApplicationStorageDirectory; | ||||
| 
 | ||||
|       /* save to file */ | ||||
|       window.requestFileSystem(window.PERSISTENT, 0, function(fs) { | ||||
|         try { | ||||
|           fs.root.getFile("SheetJSQuasar.xlsx", {create: true}, entry => { | ||||
|             const msg = `File stored at ${dir} ${entry.fullPath}`; | ||||
|             entry.createWriter(writer => { | ||||
|               try { | ||||
|                 const data = new Blob([u8], {type: "application/vnd.ms-excel"}); | ||||
|                 writer.onwriteend = () => { | ||||
|                   try { | ||||
|                     $q.dialog({title: "Success!", message: msg}); | ||||
|                   } catch(e) { dialogerr(e); } | ||||
|                 }; | ||||
|                 writer.onerror = dialogerr; | ||||
|                 writer.write(data); | ||||
|               } catch(e) { dialogerr(e); } | ||||
|             }, dialogerr); | ||||
|           }, dialogerr); | ||||
|         } catch(e) { dialogerr(e) } | ||||
|       }, dialogerr); | ||||
| // highlight-end | ||||
|     } | ||||
| ``` | ||||
| 
 | ||||
| The page should revert to the old contents. | ||||
| 
 | ||||
| To test that writing works: | ||||
| 
 | ||||
| - Close the app in the simulator and re-launch the app. | ||||
| 
 | ||||
| - Click "Save File".  You will see a popup with a location: | ||||
| 
 | ||||
|  | ||||
| @ -475,121 +445,23 @@ id,content | ||||
| 46,Joseph Biden | ||||
| ``` | ||||
| 
 | ||||
| **Android** | ||||
| ### Android Device | ||||
| 
 | ||||
| 10) Create the Android project: | ||||
| 11) Close all open emulators and simulators. | ||||
| 
 | ||||
| 12) Disconnect any iOS or Android devices connected to the computer. | ||||
| 
 | ||||
| 13) Connect the Android device to the computer. | ||||
| 
 | ||||
| 14) Start the dev process: | ||||
| 
 | ||||
| ```bash | ||||
| cd src-cordova | ||||
| cordova platform add android | ||||
| cd .. | ||||
| ``` | ||||
| 
 | ||||
| 11) Start the simulator: | ||||
| 
 | ||||
| ```bash | ||||
| quasar dev -m android | ||||
| npx quasar dev -m cordova -T android | ||||
| ``` | ||||
| 
 | ||||
| If prompted to select an external IP, press <kbd>Enter</kbd>. | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| If the app is blank or not refreshing, delete the app and close the simulator, | ||||
| then restart the development process. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::warning pass | ||||
| 
 | ||||
| On Windows, the command failed with a Gradle error | ||||
| 
 | ||||
| ``` | ||||
| Could not find an installed version of Gradle either in Android Studio, | ||||
| or on your system to install the gradle wrapper. Please include gradle | ||||
| in your path, or install Android Studio | ||||
| ``` | ||||
| 
 | ||||
| [Gradle](https://gradle.org/) (the complete version) must be extracted and the | ||||
| `bin` folder must be added to the user PATH variable. After adding to PATH, | ||||
| launch a new PowerShell or Command Prompt window and run the command. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| To test that reading works: | ||||
| 
 | ||||
| - Click and drag `pres.numbers` from a Finder window into the simulator. | ||||
| - Tap "Load", tap the `≡` icon, tap "Downloads" and select `pres.numbers`. | ||||
| 
 | ||||
| To test that writing works: | ||||
| 
 | ||||
| - Tap "Save File".  You will see a popup with a location. | ||||
| 
 | ||||
| - Pull the file from the simulator and verify the contents: | ||||
| 
 | ||||
| ```bash | ||||
| adb exec-out run-as org.sheetjs.quasar cat files/files/SheetJSQuasar.xlsx > /tmp/SheetJSQuasar.xlsx | ||||
| npx xlsx-cli /tmp/SheetJSQuasar.xlsx | ||||
| ``` | ||||
| 
 | ||||
| **iOS Device** | ||||
| 
 | ||||
| 12) Close all open emulators and simulators. | ||||
| 
 | ||||
| 13) Disconnect any iOS or Android devices connected to the computer. | ||||
| 
 | ||||
| 14) Connect the iOS device to the computer. | ||||
| 
 | ||||
| 15) Open the Xcode project: | ||||
| 
 | ||||
| ```bash | ||||
| open src-cordova/platforms/ios/SheetJSQuasar.xcodeproj | ||||
| ``` | ||||
| 
 | ||||
| Select "SheetJSQuasar" in the Navigator. In the main pane, select "Signing & | ||||
| Capabilities" and ensure a Team is selected. Save and close the project. | ||||
| 
 | ||||
| 16) Start the dev process: | ||||
| 
 | ||||
| ```bash | ||||
| quasar dev -m ios | ||||
| ``` | ||||
| 
 | ||||
| If prompted to select an external IP, press <kbd>Enter</kbd>. | ||||
| 
 | ||||
| 17) Test the application: | ||||
| 
 | ||||
| - Press the Home button (or swipe up with one finger) and switch to Safari. | ||||
| - Download https://docs.sheetjs.com/pres.numbers | ||||
| - Press the Home button (or swipe up with one finger) and select the `SheetJSQuasar` app | ||||
| - Tap the "Load" button, then select "Choose File" and select the downloaded `pres.numbers` | ||||
| 
 | ||||
| The table will update with new data. | ||||
| 
 | ||||
| - Tap "Save File" | ||||
| - Press the Home button (or swipe up with one finger) and switch to Files. | ||||
| - Tap `<` until the main "Browse" window is displayed, then select "On My iPhone" | ||||
| - Look for the "SheetJSQuasar" folder and tap `SheetJSQuasar.xlsx`. | ||||
| 
 | ||||
| If Numbers is installed on the device, it will display the contents of the new file. | ||||
| 
 | ||||
| **Android Device** | ||||
| 
 | ||||
| 18) Close all open emulators and simulators. | ||||
| 
 | ||||
| 19) Disconnect any iOS or Android devices connected to the computer. | ||||
| 
 | ||||
| 20) Connect the Android device to the computer. | ||||
| 
 | ||||
| 21) Start the dev process: | ||||
| 
 | ||||
| ```bash | ||||
| quasar dev -m android | ||||
| ``` | ||||
| 
 | ||||
| If prompted to select an external IP, press <kbd>Enter</kbd>. | ||||
| 
 | ||||
| 22) Test the application: | ||||
| 15) Test the application: | ||||
| 
 | ||||
| - Press the Home button (or swipe up with one finger) and switch to Browser. | ||||
| - Download https://docs.sheetjs.com/pres.numbers | ||||
| @ -606,6 +478,48 @@ methods ("Storage Access Framework") that are not implemented in Quasar. | ||||
| ::: | ||||
| 
 | ||||
| 
 | ||||
| ### iOS Device | ||||
| 
 | ||||
| 16) Close all open emulators and simulators. | ||||
| 
 | ||||
| 17) Disconnect any iOS or Android devices connected to the computer. | ||||
| 
 | ||||
| 18) Connect the iOS device to the computer. | ||||
| 
 | ||||
| 19) Open the Xcode project: | ||||
| 
 | ||||
| ```bash | ||||
| open src-cordova/platforms/ios/SheetJSQuasar.xcodeproj | ||||
| ``` | ||||
| 
 | ||||
| Select "SheetJSQuasar" in the Navigator. In the main pane, select "Signing & | ||||
| Capabilities" and ensure a Team is selected. Save and close the project. | ||||
| 
 | ||||
| 20) Start the dev process: | ||||
| 
 | ||||
| ```bash | ||||
| npx quasar dev -m cordova -T ios | ||||
| ``` | ||||
| 
 | ||||
| If prompted to select an external IP, press <kbd>Enter</kbd>. | ||||
| 
 | ||||
| 11) Test the application: | ||||
| 
 | ||||
| - Press the Home button (or swipe up with one finger) and switch to Safari. | ||||
| - Download https://docs.sheetjs.com/pres.numbers | ||||
| - Press the Home button (or swipe up with one finger) and select the `SheetJSQuasar` app | ||||
| - Tap the "Load" button, then select "Choose File" and select the downloaded `pres.numbers` | ||||
| 
 | ||||
| The table will update with new data. | ||||
| 
 | ||||
| - Tap "Save File" | ||||
| - Press the Home button (or swipe up with one finger) and switch to Files. | ||||
| - Tap `<` until the main "Browse" window is displayed, then select "On My iPhone" | ||||
| - Look for the "SheetJSQuasar" folder and tap `SheetJSQuasar.xlsx`. | ||||
| 
 | ||||
| If Numbers is installed on the device, it will display the contents of the new file. | ||||
| 
 | ||||
| 
 | ||||
| [^1]: See ["File Picker"](https://quasar.dev/vue-components/file-picker) in the Quasar documentation. | ||||
| [^2]: See [`read` in "Reading Files"](/docs/api/parse-options) | ||||
| [^3]: See ["SheetJS Data Model"](/docs/csf/) for more details on workbooks, worksheets, and other concepts. | ||||
|  | ||||
| @ -62,15 +62,16 @@ This demo was tested in the following environments: | ||||
| |:-----------|:--------------------|:-------|:-------------|:-----------| | ||||
| | Android 34 | Pixel 3a            | B      | `darwin-arm` | 2025-03-30 | | ||||
| | iOS 18.2   | iPhone SE (3rd gen) | B      | `darwin-arm` | 2025-03-30 | | ||||
| | Android 36 | Pixel 9 Pro XL      | A      | `win11-x64`  | 2025-04-17 | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Configurations</b> (click to show)</summary> | ||||
| 
 | ||||
| Configuration A: | ||||
| 
 | ||||
| - Ionic: `@ionic/angular 8.2.0`, `@ionic/angular-toolkit 11.0.1` | ||||
| - Cordova: `cordova-lib@12.0.1`, `android 13.0.0, ios 7.1.0` | ||||
| - File Integration: `@awesome-cordova-plugins/file` version `6.7.0` | ||||
| - Ionic: `@ionic/angular 8.5.2`, `@ionic/angular-toolkit 12.1.1` | ||||
| - Cordova: `cordova-lib@12.0.2`, `android 14.0.0` | ||||
| - File Integration: `@awesome-cordova-plugins/file` version `6.16.0` | ||||
| 
 | ||||
| Configuration B: | ||||
| 
 | ||||
| @ -394,6 +395,11 @@ In the `application` tag, add the attribute `android:requestLegacyExternalStorag | ||||
| ionic cordova emulate android | ||||
| ``` | ||||
| 
 | ||||
| If prompted to share pseudonymous usage data with Google, type <kbd>N</kbd> and | ||||
| press <kbd>Enter</kbd> to opt out. | ||||
| 
 | ||||
| If prompted to share anonymous usage data with Cordova, type <kbd>N</kbd>. | ||||
| 
 | ||||
| When the app is loaded, a list of Presidents should be displayed. This list is | ||||
| dynamically generated by fetching and parsing a test file. | ||||
| 
 | ||||
| @ -433,7 +439,7 @@ In a test run, the output showed a Pixel 3a with the following details: | ||||
| // highlight-next-line | ||||
|     Name: Pixel_3a_API_34 | ||||
|   Device: pixel_3a (Google) | ||||
|     Path: /Users/SheetJS/.android/avd/Pixel_4_API_33.avd | ||||
|     Path: /Users/SheetJS/.android/avd/Pixel_3a_API_34.avd | ||||
| ``` | ||||
| 
 | ||||
| The Ionic command accepts a `--target` flag. Pass the emulator name: | ||||
| @ -460,6 +466,8 @@ On macOS, this issue was resolved by installing Gradle with Homebrew manager: | ||||
| brew install gradle | ||||
| ``` | ||||
| 
 | ||||
| In Windows, Gradle must be installed manually[^11] | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::danger pass | ||||
| @ -681,3 +689,4 @@ the file with the new line. | ||||
| [^8]: See [`write` in "Writing Files"](/docs/api/write-options) | ||||
| [^9]: See ["Developing for iOS"](https://ionic-docs-o31kiyk8l-ionic1.vercel.app/docs/v6/developing/ios) and ["Developing for Android"](https://ionic-docs-o31kiyk8l-ionic1.vercel.app/docs/v6/developing/android). The Ionic team removed these pages from the official docs site and recommend the `vercel.app` docs site. | ||||
| [^10]: See the [JDK Archive](https://jdk.java.net/archive/) for Java 17 JDK download links. | ||||
| [^11]: See ["Installing manually"](https://gradle.org/install/#manually) in the Gradle documentation. | ||||
| @ -39,6 +39,7 @@ This demo was tested in the following deployments: | ||||
| 
 | ||||
| | OS and Version | Architecture | Excel      | Date       | | ||||
| |:---------------|:-------------|:-----------|:-----------| | ||||
| | macOS 15.3     | `darwin-x64` | 16.95.4    | 2025-04-17 | | ||||
| | macOS 14.5     | `darwin-arm` | 16.81      | 2024-12-22 | | ||||
| | Windows 11     | `win11-x64`  | 365 (2501) | 2025-01-19 | | ||||
| 
 | ||||
| @ -57,13 +58,7 @@ Excel 365 before running the demo. | ||||
| The Office Add-in CLI collects telemetry by default. It can be disabled: | ||||
| 
 | ||||
| ```js | ||||
| npx office-addin-usage-data off | ||||
| ``` | ||||
| 
 | ||||
| The setting can be verified by running: | ||||
| 
 | ||||
| ```js | ||||
| npx office-addin-usage-data list | ||||
| npx -y office-addin-usage-data off | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| @ -156,7 +151,7 @@ after testing is finished. | ||||
| 3) Disable telemetry: | ||||
| 
 | ||||
| ```bash | ||||
| npx office-addin-usage-data off | ||||
| npx -y office-addin-usage-data off | ||||
| ``` | ||||
| 
 | ||||
| 4) Install dependencies: | ||||
| @ -165,21 +160,31 @@ npx office-addin-usage-data off | ||||
| npm i -g yo bower generator-office | ||||
| ``` | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| In some systems, the command must be run with the root user: | ||||
| 
 | ||||
| ```bash | ||||
| sudo npm i -g yo bower generator-office | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Creating a new Add-in | ||||
| 
 | ||||
| 5) Run the generator: | ||||
| 
 | ||||
| ```bash | ||||
| npx yo office | ||||
| npx -y yo office | ||||
| ``` | ||||
| 
 | ||||
| The generator will ask a few questions: | ||||
| 
 | ||||
| - "Choose a project type": "Excel Custom Functions using a Shared Runtime" | ||||
| - "Choose a project type": Select `Excel Custom Functions using a Shared Runtime` | ||||
| 
 | ||||
| - "Choose a script type": "JavaScript", | ||||
| - "Choose a script type": Select `JavaScript` | ||||
| 
 | ||||
| - "What do you want to name your add-in?": "SheetJSImport" | ||||
| - "What do you want to name your add-in?": Type `SheetJSImport` and press <kbd>Enter</kbd> | ||||
| 
 | ||||
| The generator will create the project and install dependencies. | ||||
| 
 | ||||
| @ -237,7 +242,7 @@ npm start | ||||
| 
 | ||||
| ### Integrating the SheetJS Library | ||||
| 
 | ||||
| 10) Install the SheetJS library in the project | ||||
| 10) Install the SheetJS library in the project: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
|  | ||||
| @ -25,9 +25,10 @@ library to export a bitfield table from Apple Numbers to a XLSX workbook. | ||||
| 
 | ||||
| This demo was tested by SheetJS users in the following deployments: | ||||
| 
 | ||||
| | Architecture | Ghidra   | Date       | | ||||
| |:-------------|:---------|:-----------| | ||||
| | `darwin-arm` | `11.13.1`| 2025-03-17 | | ||||
| | Architecture | Ghidra    | Date       | | ||||
| |:-------------|:----------|:-----------| | ||||
| | `darwin-x64` | `11.13.1` | 2025-04-17 | | ||||
| | `darwin-arm` | `11.13.1` | 2025-03-17 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -229,7 +230,7 @@ const src = decomp.getDecompiledFunction().getC(); | ||||
| ## Complete Demo | ||||
| 
 | ||||
| In this demo, we will inspect the `_TSTCellToCellStorage` method within the | ||||
| `TSTables` framework of Apple Numbers 14.2. This particular method handles | ||||
| `TSTables` framework of Apple Numbers 14.4. This particular method handles | ||||
| serialization of cells to the NUMBERS file format. | ||||
| 
 | ||||
| The implementation has a number of blocks which look like the following script: | ||||
|  | ||||
| @ -1114,6 +1114,7 @@ This demo was tested in the following deployments: | ||||
| |:-------------|:--------|:-----------| | ||||
| | `darwin-x64` | `2.2.1` | 2025-03-31 | | ||||
| | `darwin-arm` | `2.2.1` | 2025-03-31 | | ||||
| | `win11-x64`  | `2.2.1` | 2025-04-17 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
|  | ||||
| @ -78,7 +78,7 @@ Spreadsheet applications commonly display file properties in separate windows: | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| When this demo was last tested, Apple Numbers 14.2 did not support file | ||||
| When this demo was last tested, Apple Numbers 14.4 did not support file | ||||
| properties in the XLSX import and export codecs. | ||||
| 
 | ||||
| ::: | ||||
|  | ||||
| @ -66,7 +66,7 @@ format has a limit of 2048 rows, so data after the 2048th row will not be saved. | ||||
| |:------------------------------------------|:-----------|---------:|---------:| | ||||
| | Excel 2007+ XML Formats (XLSX/XLSM)       |`XFD1048576`|    16384 |  1048576 | | ||||
| | Excel 2007+ Binary Format (XLSB BIFF12)   |`XFD1048576`|    16384 |  1048576 | | ||||
| | Numbers 14.2 (NUMBERS)                    |`ALL1000000`|     1000 |  1000000 | | ||||
| | Numbers 14.4 (NUMBERS)                    |`ALL1000000`|     1000 |  1000000 | | ||||
| | Quattro Pro 9+ (QPW)                      |`IV1000000 `|      256 |  1000000 | | ||||
| | Excel 97-2004 (XLS BIFF8)                 |`IV65536   `|      256 |    65536 | | ||||
| | Excel 5.0/95 (XLS BIFF5)                  |`IV16384   `|      256 |    16384 | | ||||
| @ -202,7 +202,7 @@ XLR also includes a `WksSSWorkBook` stream similar to Lotus FM3/FMT files. | ||||
| 
 | ||||
| iWork 2013 (Numbers 3.0 / Pages 5.0 / Keynote 6.0) switched from a proprietary | ||||
| XML-based format to the current file format based on the iWork Archive (IWA). | ||||
| This format has been used up through the current release (Numbers 14.2) as well | ||||
| This format has been used up through the current release (Numbers 14.4) as well | ||||
| as the iCloud.com web interface to Numbers. | ||||
| 
 | ||||
| The parser focuses on extracting raw data from tables.  Numbers technically | ||||
|  | ||||
| @ -60,7 +60,7 @@ src.split(/[\r\n]+/).reduce((acc,row,i) => { | ||||
| const aoo = offset.map((name, idx) => ({ | ||||
|   Mask: "0x" + (1 << idx).toString(16), | ||||
|   "Internal Name": name.replace(/^PTR_s_|_[0-9a-f]*$/g,"").replace(/[A-Z]/g, " $&").toLowerCase().replace(/ i d/, " ID") | ||||
| })); | ||||
| })).filter(x => x); | ||||
| 
 | ||||
| /* create worksheet */ | ||||
| const ws = json_to_sheet(aoo); | ||||
|  | ||||
							
								
								
									
										68
									
								
								docz/static/quasar/IndexPage.vue
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										68
									
								
								docz/static/quasar/IndexPage.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| <template> | ||||
|   <q-page class="row items-center justify-evenly"> | ||||
|     <q-table :rows="todos" /> | ||||
|     <q-btn-group> | ||||
|       <q-file v-model="file" label="Load File" filled label-color="orange" @input="updateFile"/> | ||||
|       <q-btn label="Save File" @click="saveFile" /> | ||||
|     </q-btn-group> | ||||
|   </q-page> | ||||
| </template> | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| import { ref } from 'vue'; | ||||
| import { read, write, utils } from 'xlsx'; | ||||
| import { useQuasar } from 'quasar'; | ||||
| import type { Todo } from 'components/models'; | ||||
| 
 | ||||
| const $q = useQuasar(); | ||||
| 
 | ||||
| const todos = ref<Todo[]>([ | ||||
|   { id: 1, content: 'ct1' }, | ||||
|   { id: 2, content: 'ct2' }, | ||||
|   { id: 3, content: 'ct3' }, | ||||
|   { id: 4, content: 'ct4' }, | ||||
|   { id: 5, content: 'ct5' } | ||||
| ]); | ||||
| const file = ref<File>(); | ||||
| 
 | ||||
| function dialogerr(e: any) { $q.dialog({title: "Error!", message: e?.message || String(e)}); } | ||||
| function saveFile() { | ||||
|   /* generate workbook from state */ | ||||
|   const ws = utils.json_to_sheet(todos.value); | ||||
|   const wb = utils.book_new(ws, "SheetJSQuasar"); | ||||
|   const u8: Uint8Array = write(wb, {bookType: "xlsx", type: "buffer"}); | ||||
|   const dir: string = $q.cordova.file.documentsDirectory || $q.cordova.file.externalApplicationStorageDirectory; | ||||
| 
 | ||||
|   /* save to file */ | ||||
|   window.requestFileSystem(window.PERSISTENT, 0, function(fs) { | ||||
|     try { | ||||
|       fs.root.getFile("SheetJSQuasar.xlsx", {create: true}, entry => { | ||||
|         const msg = `File stored at ${dir} ${entry.fullPath}`; | ||||
|         entry.createWriter(writer => { | ||||
|           try { | ||||
|             const data = new Blob([u8], {type: "application/vnd.ms-excel"}); | ||||
|             writer.onwriteend = () => { | ||||
|               try { | ||||
|                 $q.dialog({title: "Success!", message: msg}); | ||||
|               } catch(e) { dialogerr(e); } | ||||
|             }; | ||||
|             writer.onerror = dialogerr; | ||||
|             writer.write(data); | ||||
|           } catch(e) { dialogerr(e); } | ||||
|         }, dialogerr); | ||||
|       }, dialogerr); | ||||
|     } catch(e) { dialogerr(e) } | ||||
|   }, dialogerr); | ||||
| } | ||||
| async function updateFile(v: Event) { | ||||
|   try { | ||||
|     const files = (v.target as HTMLInputElement).files; | ||||
|     if(!files || files.length == 0 || !files[0]) return; | ||||
| 
 | ||||
|     const wb = read(await files[0].arrayBuffer()); | ||||
| 
 | ||||
|     const data = utils.sheet_to_json<any>(wb.Sheets[wb.SheetNames[0]!]!); | ||||
|     todos.value = data.map(row => ({id: row.Index, content: row.Name})); | ||||
|   } catch(e) { dialogerr(e); } | ||||
| } | ||||
| </script> | ||||
| @ -3,13 +3,12 @@ | ||||
| 
 | ||||
| cd /tmp | ||||
| rm -rf sheetjs-worker | ||||
| . ~/.bashrc ## This is apparently needed in macos | ||||
| 
 | ||||
| mkdir sheetjs-worker | ||||
| cd sheetjs-worker | ||||
| echo '{ "type": "module" }' > package.json | ||||
| 
 | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz express@4.18.2 formidable@2.1.2 | ||||
| 
 | ||||
| cat >worker.js <<EOF | ||||
| /* load the worker_threads module */ | ||||
| import { parentPort } from 'node:worker_threads'; | ||||
| @ -70,11 +69,16 @@ app.post('/', (req, res, next) => { | ||||
| app.listen(7262, () => { console.log(\`Example app listening on port 7262\`); }); | ||||
| EOF | ||||
| 
 | ||||
| # this version uses `n` to cycle through node versions | ||||
| for n in 18 20 22; do | ||||
|   sudo n $n | ||||
|   node --version | ||||
|   npx -y concurrently -k 'node main.mjs' 'sleep 2; curl -X POST -F upload=@pres.numbers http://localhost:7262/ -J -O' | ||||
|   npx -y xlsx-cli SheetJSPool.xlsx | ||||
|   rm -f SheetJSPool.xlsx | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz formidable@2.1.2 | ||||
| for express in 4.21.2 5.1.0; do | ||||
|   npm i --save express@$express | ||||
|   npm ls | grep express | ||||
|   # this version uses `nvm` to cycle through node versions | ||||
|   for n in 18 20 22; do | ||||
|     nvm use $n | ||||
|     node --version | ||||
|     npx -y concurrently -k 'node main.mjs' 'sleep 2; curl -X POST -F upload=@pres.numbers http://localhost:7262/ -J -O' | ||||
|     npx -y xlsx-cli SheetJSPool.xlsx | ||||
|     rm -f SheetJSPool.xlsx | ||||
|   done | ||||
| done | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user