forked from sheetjs/docs.sheetjs.com
		
	CapacitorJS Mobile demo refresh
This commit is contained in:
		
							parent
							
								
									14bd6a4ed0
								
							
						
					
					
						commit
						fdde52dfde
					
				| @ -25,7 +25,7 @@ models and data flow strategies. | ||||
| This demo focuses on Svelte concepts. Other demos cover general deployments: | ||||
| 
 | ||||
| - [Static Site Generation powered by SvelteKit](/docs/demos/static/svelte) | ||||
| - [iOS applications powered by CapacitorJS](/docs/demos/mobile/capacitor) | ||||
| - [iOS and Android applications powered by CapacitorJS](/docs/demos/mobile/capacitor) | ||||
| - [Desktop application powered by Wails](/docs/demos/desktop/wails) | ||||
| 
 | ||||
| ::: | ||||
|  | ||||
| @ -222,6 +222,13 @@ const wb = XLSX.read(ab); | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device            | RN       | Date       | | ||||
| |:-----------|:------------------|:---------|:-----------| | ||||
| | iOS 15.1   | iPhone 12 Pro Max | `0.73.6` | 2024-03-13 | | ||||
| | Android 29 | NVIDIA Shield     | `0.73.6` | 2024-03-13 | | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device            | RN       | Dev Platform | Date       | | ||||
| @ -231,13 +238,6 @@ This demo was tested in the following environments: | ||||
| | Android 34 | Pixel 3a          | `0.73.5` | `win10-x64`  | 2024-03-05 | | ||||
| | Android 34 | Pixel 3a          | `0.73.7` | `linux-x64`  | 2024-04-29 | | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device            | RN       | Date       | | ||||
| |:-----------|:------------------|:---------|:-----------| | ||||
| | iOS 15.1   | iPhone 12 Pro Max | `0.73.6` | 2024-03-13 | | ||||
| | Android 29 | NVIDIA Shield     | `0.73.6` | 2024-03-13 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 0) Install React Native dependencies | ||||
| @ -1004,6 +1004,13 @@ try { | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device            | RN       | Date       | | ||||
| |:-----------|:------------------|:---------|:-----------| | ||||
| | iOS 15.5   | iPhone 13 Pro Max | `0.73.6` | 2024-03-31 | | ||||
| | Android 29 | NVIDIA Shield     | `0.73.6` | 2024-03-31 | | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device            | RN       | Dev Platform | Date       | | ||||
| @ -1013,13 +1020,6 @@ This demo was tested in the following environments: | ||||
| | Android 34 | Pixel 3a          | `0.73.6` | `win10-x64`  | 2024-03-31 | | ||||
| | Android 34 | Pixel 3a          | `0.73.6` | `linux-x64`  | 2024-03-31 | | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device            | RN       | Date       | | ||||
| |:-----------|:------------------|:---------|:-----------| | ||||
| | iOS 15.5   | iPhone 13 Pro Max | `0.73.6` | 2024-03-31 | | ||||
| | Android 29 | NVIDIA Shield     | `0.73.6` | 2024-03-31 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::danger pass | ||||
|  | ||||
| @ -52,6 +52,13 @@ Angular and TypeScript is assumed. | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device              | NS       | Date       | | ||||
| |:-----------|:--------------------|:---------|:-----------| | ||||
| | Android 30 | NVIDIA Shield       | `8.6.5`  | 2024-04-07 | | ||||
| | iOS 15.1   | iPad Pro            | `8.6.1`  | 2023-12-04 | | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device              | NS       | Dev Platform | Date       | | ||||
| @ -60,13 +67,6 @@ This demo was tested in the following environments: | ||||
| | iOS 17.0.1 | iPhone SE (3rd gen) | `8.6.1`  | `darwin-x64` | 2023-12-04 | | ||||
| | Android 34 | Pixel 3a            | `8.6.5`  | `win10-x64`  | 2024-04-07 | | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device              | NS       | Date       | | ||||
| |:-----------|:--------------------|:---------|:-----------| | ||||
| | Android 30 | NVIDIA Shield       | `8.6.5`  | 2024-04-07 | | ||||
| | iOS 15.1   | iPad Pro            | `8.6.1`  | 2023-12-04 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::danger Telemetry | ||||
|  | ||||
| @ -49,12 +49,21 @@ The [CapacitorJS demo](/docs/demos/mobile/capacitor) covers CapacitorJS apps. | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| **Simulators** | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device              | Config | Date       | | ||||
| |:-----------|:--------------------|:-------|:-----------| | ||||
| | Android 34 | Pixel 3a            | A      | 2023-12-04 | | ||||
| | iOS 17.0.1 | iPhone SE (3rd gen) | A      | 2023-12-04 | | ||||
| | Android 30 | NVIDIA Shield       | B      | 2024-05-30 | | ||||
| | iOS 15.1   | iPad Pro            | B      | 2024-05-30 | | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device              | Config | Dev Platform | Date       | | ||||
| |:-----------|:--------------------|:-------|:-------------|:-----------| | ||||
| | Android 34 | Pixel 3a            | A      | `darwin-x64` | 2023-12-04 | | ||||
| | iOS 17.0.1 | iPhone SE (3rd gen) | A      | `darwin-x64` | 2023-12-04 | | ||||
| | Android 34 | Pixel 3a            | B      | `darwin-arm` | 2024-05-30 | | ||||
| | iOS 17.5   | iPhone SE (3rd gen) | B      | `darwin-arm` | 2024-05-30 | | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Configurations</b> (click to show)</summary> | ||||
| @ -65,6 +74,12 @@ Configuration A: | ||||
| - Cordova: `cordova-lib@12.0.1`, `android 12.0.1, ios 7.0.1` | ||||
| - File Integration: `@awesome-cordova-plugins/file` version `6.4.0` | ||||
| 
 | ||||
| Configuration B: | ||||
| 
 | ||||
| - 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` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ::: | ||||
| @ -138,7 +153,18 @@ simplifies iteration over the array of arrays: | ||||
| 
 | ||||
| ### File Operations | ||||
| 
 | ||||
| `@awesome-cordova-plugins/file` reads and writes files on devices. | ||||
| The `cordova-plugin-file` plugin reads and writes files on devices. | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| For Android 30+, due to scoped storage rules, the standard file module writes | ||||
| private files that cannot be accessed from the Files app. | ||||
| 
 | ||||
| A Storage Access Framework plugin must be used to write external files. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| `@awesome-cordova-plugins/file` is a wrapper designed for Ionic + Angular apps. | ||||
| 
 | ||||
| :::info pass | ||||
| 
 | ||||
| @ -217,12 +243,29 @@ known location. After writing, an alert will display the location of the file. | ||||
| 
 | ||||
| 1) Follow the official instructions for iOS and Android development[^9]. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><b>Installation Notes</b> (click to show)</summary> | ||||
| 
 | ||||
| Ionic requires Java 17. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 2) Install required global dependencies: | ||||
| 
 | ||||
| ```bash | ||||
| npm i -g cordova cordova-res @angular/cli native-run @ionic/cli | ||||
| ``` | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| In some systems, the command must be run as the root user: | ||||
| 
 | ||||
| ```bash | ||||
| sudo npm i -g cordova cordova-res @angular/cli native-run @ionic/cli | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ### Base Project | ||||
| 
 | ||||
| 3) Create a new project: | ||||
| @ -239,9 +282,9 @@ If a prompt asks about creating an Ionic account, enter `N` to opt out. | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| Due to conflicts in the dependency tree, the command failed in the last test. | ||||
| Due to conflicts in the dependency tree, the command failed in some test runs. | ||||
| 
 | ||||
| The fix is to force install all modules: | ||||
| If the package installation fails, forcefully install all modules: | ||||
| 
 | ||||
| ```bash | ||||
| cd SheetJSIonic | ||||
| @ -494,4 +537,5 @@ However, the generated files were not externally visible from the Files app. | ||||
| [^6]: See [`aoa_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-arrays-input) | ||||
| [^7]: See ["Workbook Helpers" in "Utilities"](/docs/api/utilities/wb) for details on `book_new` and `book_append_sheet`. | ||||
| [^8]: See [`write` in "Writing Files"](/docs/api/write-options) | ||||
| [^9]: See ["Developing for iOS"](https://ionicframework.com/docs/v6/developing/ios) and ["Developing for Android"](https://ionicframework.com/docs/v6/developing/android) in the v6 Ionic framework documentation. | ||||
| [^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. | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| --- | ||||
| title: CapacitorJS | ||||
| title: Storing Sheets with CapacitorJS | ||||
| sidebar_label: CapacitorJS | ||||
| pagination_prev: demos/static/index | ||||
| pagination_next: demos/desktop/index | ||||
| sidebar_position: 5 | ||||
| @ -10,10 +11,17 @@ sidebar_custom_props: | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be | ||||
| imported from any component or script in the app. | ||||
| [CapacitorJS](https://capacitorjs.com/) is a mobile app runtime for building iOS | ||||
| and Android apps. | ||||
| 
 | ||||
| The "Complete Example" creates an app that looks like the screenshots below: | ||||
| [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing | ||||
| data from spreadsheets. | ||||
| 
 | ||||
| This demo uses CapacitorJS and SheetJS to process data and export spreadsheets. | ||||
| We'll explore how to load SheetJS in an CapacitorJS app and use APIs and plugins | ||||
| to extract data from, and write data to, spreadsheet files on the device. | ||||
| 
 | ||||
| The ["Demo"](#demo) creates an app that looks like the screenshots below: | ||||
| 
 | ||||
| <table><thead><tr> | ||||
|   <th><a href="#demo">iOS</a></th> | ||||
| @ -32,20 +40,22 @@ The "Complete Example" creates an app that looks like the screenshots below: | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device              | CapacitorJS + FS  | Dev Platform | Date       | | ||||
| |:-----------|:--------------------|:------------------|:-------------|:-----------| | ||||
| | Android 34 | Pixel 3a            | `5.5.1` / `5.1.4` | `darwin-x64` | 2023-12-04 | | ||||
| | iOS 17.0.1 | iPhone 15 Pro Max   | `5.5.1` / `5.1.4` | `darwin-x64` | 2023-12-04 | | ||||
| | Android 34 | Pixel 3a            | `6.0.0` / `6.0.0` | `win10-x64`  | 2024-05-28 | | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device              | CapacitorJS + FS  | Date       | | ||||
| |:-----------|:--------------------|:------------------|:-----------| | ||||
| | Android 29 | NVIDIA Shield       | `5.5.1` / `5.1.4` | 2023-12-04 | | ||||
| | iOS 15.1   | iPad Pro            | `5.5.1` / `5.1.4` | 2023-12-04 | | ||||
| | Android 30 | NVIDIA Shield       | `6.0.0` / `6.0.0` | 2024-06-02 | | ||||
| | iOS 15.1   | iPad Pro            | `6.0.0` / `6.0.0` | 2024-06-02 | | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device              | CapacitorJS + FS  | Dev Platform | Date       | | ||||
| |:-----------|:--------------------|:------------------|:-------------|:-----------| | ||||
| | Android 34 | Pixel 3a            | `6.0.0` / `6.0.0` | `darwin-x64` | 2024-06-02 | | ||||
| | iOS 17.5   | iPhone 15 Pro Max   | `6.0.0` / `6.0.0` | `darwin-x64` | 2024-06-02 | | ||||
| | Android 34 | Pixel 3a            | `6.0.0` / `6.0.0` | `darwin-arm` | 2024-06-02 | | ||||
| | iOS 17.5   | iPhone 15 Pro Max   | `6.0.0` / `6.0.0` | `darwin-arm` | 2024-06-02 | | ||||
| | Android 34 | Pixel 3a            | `6.0.0` / `6.0.0` | `win10-x64`  | 2024-05-28 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -67,13 +77,26 @@ npx @capacitor/cli telemetry | ||||
| 
 | ||||
| ## Integration Details | ||||
| 
 | ||||
| This example uses Svelte, but the same principles apply to other frameworks. | ||||
| The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be | ||||
| imported from any component or script in the app. | ||||
| 
 | ||||
| This demo uses [SvelteJS](/docs/demos/frontend/svelte), but the same principles | ||||
| apply to other frameworks. | ||||
| 
 | ||||
| #### Reading data | ||||
| 
 | ||||
| The standard HTML5 File Input element logic works in CapacitorJS: | ||||
| The standard [HTML5 File Input](/docs/demos/local/file#file-api) API works as | ||||
| expected in CapacitorJS. | ||||
| 
 | ||||
| ```html | ||||
| Apps will typically include an `input type="file"` element. When the element is | ||||
| activated, CapacitorJS will show a file picker. After the user selects a file, | ||||
| the element will receive a `change` event. | ||||
| 
 | ||||
| The following example parses the selected file using the SheetJS `read`[^1] | ||||
| method, generates a HTML table from the first sheet using `sheet_to_html`[^2], | ||||
| and displays the table by setting the `innerHTML` attribute of a `div` element: | ||||
| 
 | ||||
| ```html title="Sample component for data import" | ||||
| <script> | ||||
| import { read, utils } from 'xlsx'; | ||||
| 
 | ||||
| @ -99,28 +122,39 @@ async function importFile(evt) { | ||||
| 
 | ||||
| #### Writing data | ||||
| 
 | ||||
| `@capacitor/filesystem` can write Base64 strings: | ||||
| Starting from a SheetJS workbook object[^3], the `write` method with the option | ||||
| `type: "base64"`[^4] will generate Base64-encoded files. | ||||
| 
 | ||||
| ```html | ||||
| The `@capacitor/filesystem` plugin can write Base64 strings to the device. | ||||
| 
 | ||||
| The following example uses the SheetJS `table_to_book` method[^5] to create a | ||||
| workbook object from a HTML table. The workbook object is exported to the XLSX | ||||
| format and written to the device. | ||||
| 
 | ||||
| ```html title="Sample component for data export" | ||||
| <script> | ||||
| import { Filesystem, Directory } from '@capacitor/filesystem'; | ||||
| import { utils, writeXLSX } from 'xlsx'; | ||||
| import { utils, write } from 'xlsx'; | ||||
| 
 | ||||
| let html = ""; | ||||
| let tbl; | ||||
| 
 | ||||
| /* get state data and export to XLSX */ | ||||
| async function exportFile() { | ||||
|   /* generate workbook object from HTML table */ | ||||
|   const elt = tbl.getElementsByTagName("TABLE")[0]; | ||||
|   const wb = utils.table_to_book(elt); | ||||
|   /* generate Base64 string for Capacitor */ | ||||
| 
 | ||||
|   // highlight-start | ||||
|   const data = writeXLSX(wb, { type: "base64" }); | ||||
|   /* export to XLSX encoded in a Base64 string  */ | ||||
|   const data = write(wb, { bookType: "xlsx", type: "base64" }); | ||||
| 
 | ||||
|   /* attempt to write to the device */ | ||||
|   await Filesystem.writeFile({ | ||||
|     data, | ||||
|     path: "SheetJSCap.xlsx", | ||||
|     directory: Directory.Documents | ||||
|   }); // write file | ||||
|   }); | ||||
|   // highlight-end | ||||
| } | ||||
| 
 | ||||
| @ -132,11 +166,45 @@ async function exportFile() { | ||||
| </main> | ||||
| ``` | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| `Filesystem.writeFile` cannot overwrite existing files. Production apps should | ||||
| attempt to delete the file before writing: | ||||
| 
 | ||||
| ```js | ||||
|   /* attempt to delete file first */ | ||||
|   try { | ||||
|     await Filesystem.deleteFile({ | ||||
|       path: "SheetJSCap.xlsx", | ||||
|       directory: Directory.Documents | ||||
|     }); | ||||
|   } catch(e) {} | ||||
|   /* attempt to write to the device */ | ||||
|   await Filesystem.writeFile({ | ||||
|     data, | ||||
|     path: "SheetJSCap.xlsx", | ||||
|     directory: Directory.Documents | ||||
|   }); | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Demo | ||||
| 
 | ||||
| The app in this demo will display data in a table. | ||||
| 
 | ||||
| When the app is launched, a [test file](https://docs.sheetjs.com/pres.numbers) | ||||
| will be fetched and processed. | ||||
| 
 | ||||
| When a document is selected with the file picker, it will be processed and the | ||||
| table will refresh to show the contents. | ||||
| 
 | ||||
| "Export XLSX" will attempt to export the table data to `SheetJSCap.xlsx` in the | ||||
| app Documents folder. An alert will display the location of the file. | ||||
| 
 | ||||
| ### Base Project | ||||
| 
 | ||||
| 0) Follow the official "Environment Setup"[^1] instructions to set up Android | ||||
| 0) Follow the official "Environment Setup"[^6] instructions to set up Android | ||||
| and iOS targets | ||||
| 
 | ||||
| :::caution pass | ||||
| @ -189,7 +257,7 @@ npm run build | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| If prompted to create an Ionic account, type `N` and press Enter. | ||||
| If prompted to create an Ionic account, type `N` and press <kbd>Enter</kbd>. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| @ -277,16 +345,25 @@ adb pull "/data/media/0/Documents/SheetJSCap.xlsx" SheetJSCap.xlsx | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 10) Test the import functionality. | ||||
| 
 | ||||
| Create a spreadsheet or find an existing file. Click and drag the file into the | ||||
| Android emulator window. The file will be uploaded to a Downloads folder in the | ||||
| emulator. | ||||
| 
 | ||||
| Tap on "Choose File" in the app. In the selector, tap `≡` and select "Downloads" | ||||
| to find the uploaded file. After selecting the file, the table will refresh. | ||||
| 
 | ||||
| ### iOS | ||||
| 
 | ||||
| 10) Create iOS app | ||||
| 11) Create iOS app | ||||
| 
 | ||||
| ```bash | ||||
| npm i --save @capacitor/ios | ||||
| npx cap add ios | ||||
| ``` | ||||
| 
 | ||||
| 11) Enable file sharing and make the documents folder visible in the iOS app. | ||||
| 12) Enable file sharing and make the documents folder visible in the iOS app. | ||||
| The following lines must be added to `ios/App/App/Info.plist`: | ||||
| 
 | ||||
| ```xml title="ios/App/App/Info.plist (add to file)" | ||||
| @ -303,7 +380,7 @@ The following lines must be added to `ios/App/App/Info.plist`: | ||||
| 
 | ||||
| (The root element of the document is `plist` and it contains one `dict` child) | ||||
| 
 | ||||
| 12) Run the app in the simulator | ||||
| 13) Run the app in the simulator | ||||
| 
 | ||||
| ```bash | ||||
| npm run build | ||||
| @ -313,24 +390,45 @@ npx cap run ios | ||||
| 
 | ||||
| If prompted to select a target device, select "iPhone 15 Pro Max (simulator)". | ||||
| 
 | ||||
| 13) Test the app | ||||
| The app should look like the screenshot at the top of the page. | ||||
| 
 | ||||
| Open the app and observe that presidents are listed in the table. | ||||
| 14) Test the export functionality. | ||||
| 
 | ||||
| Touch "Export XLSX" and a popup will be displayed. | ||||
| 
 | ||||
| To see the generated file, switch to the "Files" app in the simulator and look | ||||
| for `SheetJSCap.xlsx` in "On My iPhone" > "`sheetjs-cap`" | ||||
| 
 | ||||
| <details open> | ||||
|   <summary><b>Downloading the generated file</b> (click to hide)</summary> | ||||
| 
 | ||||
| The app files are available in the filesystem in `~/Library/Developer`. Open a | ||||
| terminal and run the following command to find the file: | ||||
| 
 | ||||
| ```bash | ||||
| find ~/Library/Developer -name SheetJSCap.xlsx | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| 15) Test the import functionality. | ||||
| 
 | ||||
| Create a spreadsheet or find an existing file. Click and drag the file into the | ||||
| iOS simulator window. The simulator will show a picker for saving the file. | ||||
| Select the `sheetjs-cap` folder and tap "Save". | ||||
| 
 | ||||
| Tap on "Choose File" in the app and "Choose File" in the popup. In the picker, | ||||
| tap "Recents" and select the new file. After selecting the file, the table will refresh. | ||||
| 
 | ||||
| ### Android Device | ||||
| 
 | ||||
| 14) Connect an Android device using a USB cable. | ||||
| 16) Connect an Android device using a USB cable. | ||||
| 
 | ||||
| If the device asks to allow USB debugging, tap "Allow". | ||||
| 
 | ||||
| 15) Close any Android / iOS emulators. | ||||
| 17) Close any Android / iOS emulators. | ||||
| 
 | ||||
| 16) Build APK and run on device: | ||||
| 18) Build APK and run on device: | ||||
| 
 | ||||
| ```bash | ||||
| npm run build | ||||
| @ -341,6 +439,13 @@ npx cap run android | ||||
| If the Android emulators are closed and an Android device is connected, the last | ||||
| command will build an APK and install on the device. | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| In some tests, the last command asked for a target device. Select the Android | ||||
| device in the list and press <kbd>Enter</kbd> | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| For real devices running API level 29 or below, the following line must be added | ||||
| @ -362,13 +467,17 @@ to the `application` open tag in `android/app/src/main/AndroidManifest.xml`: | ||||
| 
 | ||||
| ### iOS Device | ||||
| 
 | ||||
| 17) Connect an iOS device using a USB cable | ||||
| 19) Connect an iOS device using a USB cable | ||||
| 
 | ||||
| 18) Close any Android / iOS emulators. | ||||
| 20) Close any Android / iOS emulators. | ||||
| 
 | ||||
| 19) Enable developer code signing certificates[^2] | ||||
| 21) Enable developer code signing certificates. | ||||
| 
 | ||||
| 19) Run on device: | ||||
| Open `ios/App/App.xcworkspace` in Xcode. Select the "Project Navigator" and | ||||
| select the "App" project. In the main view, select "Signing & Capabilities". | ||||
| Under "Signing", select a team in the dropdown menu. | ||||
| 
 | ||||
| 22) Run on device: | ||||
| 
 | ||||
| ```bash | ||||
| npm run build | ||||
| @ -378,5 +487,9 @@ npx cap run ios | ||||
| 
 | ||||
| When prompted to select a target device, select the real device in the list. | ||||
| 
 | ||||
| [^1]: See ["Environment Setup"](https://capacitorjs.com/docs/getting-started/environment-setup) in the CapacitorJS documentation. | ||||
| [^2]: The [Flutter documentation](https://docs.flutter.dev/get-started/install/macos?tab=ios15#enable-developer-code-signing-certificates) covers the instructions in more detail. The correct workspace is `ios/App/App.xcworkspace` | ||||
| [^1]: See [`read` in "Reading Files"](/docs/api/parse-options) | ||||
| [^2]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output) | ||||
| [^3]: See ["Workbook Object"](/docs/csf/book) | ||||
| [^4]: See [the "base64" type in "Writing Files"](/docs/api/write-options#input-type) | ||||
| [^5]: See [`table_to_book` in "HTML" Utilities](/docs/api/utilities/html#create-new-sheet) | ||||
| [^6]: See ["Environment Setup"](https://capacitorjs.com/docs/getting-started/environment-setup) in the CapacitorJS documentation. | ||||
| @ -41,13 +41,6 @@ The "Demo" creates an app that looks like the screenshots below: | ||||
| 
 | ||||
| This demo was tested in the following environments: | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device            | Dart    | Flutter  | Dev Platform | Date       | | ||||
| |:-----------|:------------------|:--------|:---------|:-------------|:-----------| | ||||
| | Android 34 | Pixel 3a          | `3.2.2` | `3.16.2` | `darwin-x64` | 2023-12-04 | | ||||
| | iOS 17.0.1 | iPhone 15 Pro Max | `3.2.2` | `3.16.2` | `darwin-x64` | 2023-12-04 | | ||||
| 
 | ||||
| **Real Devices** | ||||
| 
 | ||||
| | OS         | Device            | Dart    | Flutter  | Date       | | ||||
| @ -55,6 +48,13 @@ This demo was tested in the following environments: | ||||
| | Android 29 | NVIDIA Shield     | `3.2.2` | `3.16.2` | 2023-12-04 | | ||||
| | iOS 15.1   | iPad Pro          | `3.2.2` | `3.16.2` | 2023-12-04 | | ||||
| 
 | ||||
| **Simulators** | ||||
| 
 | ||||
| | OS         | Device            | Dart    | Flutter  | Dev Platform | Date       | | ||||
| |:-----------|:------------------|:--------|:---------|:-------------|:-----------| | ||||
| | Android 34 | Pixel 3a          | `3.2.2` | `3.16.2` | `darwin-x64` | 2023-12-04 | | ||||
| | iOS 17.0.1 | iPhone 15 Pro Max | `3.2.2` | `3.16.2` | `darwin-x64` | 2023-12-04 | | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::danger Telemetry | ||||
|  | ||||
| @ -18,9 +18,19 @@ onMount(async() => { | ||||
| async function exportFile() { | ||||
|   const elt = tbl.getElementsByTagName("TABLE")[0]; | ||||
|   const wb = utils.table_to_book(elt); | ||||
|   /* generate Base64 string for Capacitor */ | ||||
| 
 | ||||
|   /* export to XLSX encoded in a Base64 string  */ | ||||
|   const data = writeXLSX(wb, { type: "base64" }); | ||||
|   /* write */ | ||||
| 
 | ||||
|   /* `writeFile` cannot overwrite, so try to delete file first */ | ||||
|   try { | ||||
|     await Filesystem.deleteFile({ | ||||
|       path: "SheetJSCap.xlsx", | ||||
|       directory: Directory.Documents | ||||
|     }); | ||||
|   } catch(e) { /* ignore error */ } | ||||
| 
 | ||||
|   /* attempt to write to the device */ | ||||
|   await Filesystem.writeFile({ | ||||
|     path: "SheetJSCap.xlsx", | ||||
|     data, | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 80 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 89 KiB | 
		Loading…
	
		Reference in New Issue
	
	Block a user