forked from sheetjs/docs.sheetjs.com
CapacitorJS Mobile demo refresh
This commit is contained in:
parent
14bd6a4ed0
commit
fdde52dfde
docz
docs/03-demos
02-frontend
17-mobile
static/cap
@ -25,7 +25,7 @@ models and data flow strategies.
|
|||||||
This demo focuses on Svelte concepts. Other demos cover general deployments:
|
This demo focuses on Svelte concepts. Other demos cover general deployments:
|
||||||
|
|
||||||
- [Static Site Generation powered by SvelteKit](/docs/demos/static/svelte)
|
- [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)
|
- [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:
|
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**
|
**Simulators**
|
||||||
|
|
||||||
| OS | Device | RN | Dev Platform | Date |
|
| 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.5` | `win10-x64` | 2024-03-05 |
|
||||||
| Android 34 | Pixel 3a | `0.73.7` | `linux-x64` | 2024-04-29 |
|
| 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
|
0) Install React Native dependencies
|
||||||
@ -1004,6 +1004,13 @@ try {
|
|||||||
|
|
||||||
This demo was tested in the following environments:
|
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**
|
**Simulators**
|
||||||
|
|
||||||
| OS | Device | RN | Dev Platform | Date |
|
| 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` | `win10-x64` | 2024-03-31 |
|
||||||
| Android 34 | Pixel 3a | `0.73.6` | `linux-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
|
:::danger pass
|
||||||
|
@ -52,6 +52,13 @@ Angular and TypeScript is assumed.
|
|||||||
|
|
||||||
This demo was tested in the following environments:
|
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**
|
**Simulators**
|
||||||
|
|
||||||
| OS | Device | NS | Dev Platform | Date |
|
| 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 |
|
| 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 |
|
| 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
|
:::danger Telemetry
|
||||||
|
@ -49,12 +49,21 @@ The [CapacitorJS demo](/docs/demos/mobile/capacitor) covers CapacitorJS apps.
|
|||||||
|
|
||||||
This demo was tested in the following environments:
|
This demo was tested in the following environments:
|
||||||
|
|
||||||
**Simulators**
|
**Real Devices**
|
||||||
|
|
||||||
| OS | Device | Config | Date |
|
| OS | Device | Config | Date |
|
||||||
|:-----------|:--------------------|:-------|:-----------|
|
|:-----------|:--------------------|:-------|:-----------|
|
||||||
| Android 34 | Pixel 3a | A | 2023-12-04 |
|
| Android 30 | NVIDIA Shield | B | 2024-05-30 |
|
||||||
| iOS 17.0.1 | iPhone SE (3rd gen) | A | 2023-12-04 |
|
| 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>
|
<details>
|
||||||
<summary><b>Configurations</b> (click to show)</summary>
|
<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`
|
- Cordova: `cordova-lib@12.0.1`, `android 12.0.1, ios 7.0.1`
|
||||||
- File Integration: `@awesome-cordova-plugins/file` version `6.4.0`
|
- 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>
|
</details>
|
||||||
|
|
||||||
:::
|
:::
|
||||||
@ -138,7 +153,18 @@ simplifies iteration over the array of arrays:
|
|||||||
|
|
||||||
### File Operations
|
### 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
|
:::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].
|
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:
|
2) Install required global dependencies:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm i -g cordova cordova-res @angular/cli native-run @ionic/cli
|
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
|
### Base Project
|
||||||
|
|
||||||
3) Create a new 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
|
:::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
|
```bash
|
||||||
cd SheetJSIonic
|
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)
|
[^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`.
|
[^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)
|
[^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_prev: demos/static/index
|
||||||
pagination_next: demos/desktop/index
|
pagination_next: demos/desktop/index
|
||||||
sidebar_position: 5
|
sidebar_position: 5
|
||||||
@ -10,10 +11,17 @@ sidebar_custom_props:
|
|||||||
import current from '/version.js';
|
import current from '/version.js';
|
||||||
import CodeBlock from '@theme/CodeBlock';
|
import CodeBlock from '@theme/CodeBlock';
|
||||||
|
|
||||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
[CapacitorJS](https://capacitorjs.com/) is a mobile app runtime for building iOS
|
||||||
imported from any component or script in the app.
|
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>
|
<table><thead><tr>
|
||||||
<th><a href="#demo">iOS</a></th>
|
<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:
|
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**
|
**Real Devices**
|
||||||
|
|
||||||
| OS | Device | CapacitorJS + FS | Date |
|
| OS | Device | CapacitorJS + FS | Date |
|
||||||
|:-----------|:--------------------|:------------------|:-----------|
|
|:-----------|:--------------------|:------------------|:-----------|
|
||||||
| Android 29 | NVIDIA Shield | `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 | `5.5.1` / `5.1.4` | 2023-12-04 |
|
| 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
|
## 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
|
#### 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>
|
<script>
|
||||||
import { read, utils } from 'xlsx';
|
import { read, utils } from 'xlsx';
|
||||||
|
|
||||||
@ -99,28 +122,39 @@ async function importFile(evt) {
|
|||||||
|
|
||||||
#### Writing data
|
#### 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>
|
<script>
|
||||||
import { Filesystem, Directory } from '@capacitor/filesystem';
|
import { Filesystem, Directory } from '@capacitor/filesystem';
|
||||||
import { utils, writeXLSX } from 'xlsx';
|
import { utils, write } from 'xlsx';
|
||||||
|
|
||||||
let html = "";
|
let html = "";
|
||||||
let tbl;
|
let tbl;
|
||||||
|
|
||||||
/* get state data and export to XLSX */
|
/* get state data and export to XLSX */
|
||||||
async function exportFile() {
|
async function exportFile() {
|
||||||
|
/* generate workbook object from HTML table */
|
||||||
const elt = tbl.getElementsByTagName("TABLE")[0];
|
const elt = tbl.getElementsByTagName("TABLE")[0];
|
||||||
const wb = utils.table_to_book(elt);
|
const wb = utils.table_to_book(elt);
|
||||||
/* generate Base64 string for Capacitor */
|
|
||||||
// highlight-start
|
// 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({
|
await Filesystem.writeFile({
|
||||||
data,
|
data,
|
||||||
path: "SheetJSCap.xlsx",
|
path: "SheetJSCap.xlsx",
|
||||||
directory: Directory.Documents
|
directory: Directory.Documents
|
||||||
}); // write file
|
});
|
||||||
// highlight-end
|
// highlight-end
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,11 +166,45 @@ async function exportFile() {
|
|||||||
</main>
|
</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
|
## 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
|
### 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
|
and iOS targets
|
||||||
|
|
||||||
:::caution pass
|
:::caution pass
|
||||||
@ -189,7 +257,7 @@ npm run build
|
|||||||
|
|
||||||
:::note pass
|
:::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>
|
</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
|
### iOS
|
||||||
|
|
||||||
10) Create iOS app
|
11) Create iOS app
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm i --save @capacitor/ios
|
npm i --save @capacitor/ios
|
||||||
npx cap add 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`:
|
The following lines must be added to `ios/App/App/Info.plist`:
|
||||||
|
|
||||||
```xml title="ios/App/App/Info.plist (add to file)"
|
```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)
|
(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
|
```bash
|
||||||
npm run build
|
npm run build
|
||||||
@ -313,24 +390,45 @@ npx cap run ios
|
|||||||
|
|
||||||
If prompted to select a target device, select "iPhone 15 Pro Max (simulator)".
|
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.
|
Touch "Export XLSX" and a popup will be displayed.
|
||||||
|
|
||||||
To see the generated file, switch to the "Files" app in the simulator and look
|
To see the generated file, switch to the "Files" app in the simulator and look
|
||||||
for `SheetJSCap.xlsx` in "On My iPhone" > "`sheetjs-cap`"
|
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
|
### 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".
|
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
|
```bash
|
||||||
npm run build
|
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
|
If the Android emulators are closed and an Android device is connected, the last
|
||||||
command will build an APK and install on the device.
|
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
|
:::caution pass
|
||||||
|
|
||||||
For real devices running API level 29 or below, the following line must be added
|
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
|
### 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
|
```bash
|
||||||
npm run build
|
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.
|
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.
|
[^1]: See [`read` in "Reading Files"](/docs/api/parse-options)
|
||||||
[^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`
|
[^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:
|
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**
|
**Real Devices**
|
||||||
|
|
||||||
| OS | Device | Dart | Flutter | Date |
|
| 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 |
|
| 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 |
|
| 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
|
:::danger Telemetry
|
||||||
|
@ -18,9 +18,19 @@ onMount(async() => {
|
|||||||
async function exportFile() {
|
async function exportFile() {
|
||||||
const elt = tbl.getElementsByTagName("TABLE")[0];
|
const elt = tbl.getElementsByTagName("TABLE")[0];
|
||||||
const wb = utils.table_to_book(elt);
|
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" });
|
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({
|
await Filesystem.writeFile({
|
||||||
path: "SheetJSCap.xlsx",
|
path: "SheetJSCap.xlsx",
|
||||||
data,
|
data,
|
||||||
|
Binary file not shown.
Before ![]() (image error) Size: 89 KiB After ![]() (image error) Size: 80 KiB ![]() ![]() |
Binary file not shown.
Before ![]() (image error) Size: 98 KiB After ![]() (image error) Size: 89 KiB ![]() ![]() |
Loading…
Reference in New Issue
Block a user