2023-01-05 23:33:49 +00:00
---
title: CapacitorJS
2023-02-28 11:40:44 +00:00
pagination_prev: demos/static/index
2023-01-05 23:33:49 +00:00
pagination_next: demos/desktop/index
sidebar_position: 5
sidebar_custom_props:
summary: JS + Web View
---
2023-04-27 09:12:19 +00:00
import current from '/version.js';
2023-05-07 13:58:36 +00:00
import CodeBlock from '@theme/CodeBlock';
2023-04-27 09:12:19 +00:00
2023-09-22 06:32:55 +00:00
The [SheetJS NodeJS Module ](/docs/getting-started/installation/nodejs ) can be
imported from any component or script in the app.
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
The "Complete Example" creates an app that looks like the screenshots below:
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
< table > < thead > < tr >
< th > < a href = "#demo" > iOS< / a > < / th >
< th > < a href = "#demo" > Android< / a > < / th >
< / tr > < / thead > < tbody > < tr > < td >
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
![iOS screenshot ](pathname:///cap/ios.png )
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
< / td > < td >
![Android screenshot ](pathname:///cap/and.png )
< / td > < / tr > < / tbody > < / table >
2023-01-05 23:33:49 +00:00
2023-12-05 03:46:54 +00:00
:::note Tested Deployments
This demo was tested in the following environments:
2024-04-30 04:29:40 +00:00
**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 |
2024-05-28 05:20:05 +00:00
| Android 34 | Pixel 3a | `6.0.0` / `6.0.0` | `win10-x64` | 2024-05-28 |
2024-04-30 04:29:40 +00:00
**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 |
2023-12-05 03:46:54 +00:00
:::
2024-04-14 07:40:38 +00:00
:::danger Telemetry
2023-01-05 23:33:49 +00:00
Before starting this demo, manually disable telemetry. On Linux and MacOS:
```bash
npx @capacitor/cli telemetry off
```
To verify telemetry was disabled:
```bash
npx @capacitor/cli telemetry
```
:::
2023-04-01 20:13:16 +00:00
## Integration Details
2023-01-05 23:33:49 +00:00
This example uses Svelte, but the same principles apply to other frameworks.
#### Reading data
The standard HTML5 File Input element logic works in CapacitorJS:
```html
< script >
import { read, utils } from 'xlsx';
let html = "";
/* show file picker, read file, load table */
async function importFile(evt) {
// highlight-start
const f = evt.target.files[0];
const wb = read(await f.arrayBuffer());
// highlight-end
const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
html = utils.sheet_to_html(ws); // generate HTML and update state
}
< / script >
< main >
<!-- highlight - next - line -->
< input type = "file" on:change = {importFile}/ >
< div bind:this = {tbl} > {@html html}< / div >
< / main >
```
#### Writing data
`@capacitor/filesystem` can write Base64 strings:
```html
< script >
import { Filesystem, Directory } from '@capacitor/filesystem';
import { utils, writeXLSX } from 'xlsx';
let html = "";
let tbl;
/* get state data and export to XLSX */
async function exportFile() {
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" });
await Filesystem.writeFile({
data,
path: "SheetJSCap.xlsx",
directory: Directory.Documents
}); // write file
// highlight-end
}
< / script >
< main >
< button on:click = {exportFile} > Export XLSX< / button >
< div bind:this = {tbl} > {@html html}< / div >
< / main >
```
2023-04-01 20:13:16 +00:00
## Demo
### Base Project
2023-01-05 23:33:49 +00:00
2023-09-05 18:04:23 +00:00
0) Follow the official "Environment Setup"[^1] instructions to set up Android
and iOS targets
:::caution pass
iOS development is only supported on macOS.
:::
2024-04-08 04:47:04 +00:00
< details >
< summary > < b > Installation Notes< / b > (click to show)< / summary >
2023-09-05 18:04:23 +00:00
CapacitorJS requires Java 17.
< / details >
2023-04-01 20:13:16 +00:00
1) Disable telemetry.
```bash
npx @capacitor/cli telemetry off
```
Verify that telemetry is disabled by running
```bash
npx @capacitor/cli telemetry
```
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
(it should print `Telemetry is off` )
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
2) Create a new Svelte project:
2023-01-05 23:33:49 +00:00
```bash
npm create vite@latest sheetjs-cap -- --template svelte
cd sheetjs-cap
```
2023-04-01 20:13:16 +00:00
3) Install dependencies:
2023-01-05 23:33:49 +00:00
2023-05-07 13:58:36 +00:00
< CodeBlock language = "bash" > {`\
2023-04-27 09:12:19 +00:00
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
npm i --save @capacitor/core @capacitor/cli @capacitor/filesystem `}
2023-05-07 13:58:36 +00:00
< / CodeBlock >
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
4) Create CapacitorJS structure:
2023-01-05 23:33:49 +00:00
```bash
npx cap init sheetjs-cap com.sheetjs.cap --web-dir=dist
2023-04-01 20:13:16 +00:00
npm run build
```
2024-01-03 06:47:00 +00:00
:::note pass
2023-12-05 03:46:54 +00:00
If prompted to create an Ionic account, type `N` and press Enter.
:::
2023-04-01 20:13:16 +00:00
5) Download [`src/App.svelte` ](pathname:///cap/App.svelte ) and replace:
```bash
curl -o src/App.svelte -L https://docs.sheetjs.com/cap/App.svelte
```
2023-09-05 18:04:23 +00:00
### Android
2023-04-01 20:13:16 +00:00
2023-09-05 18:04:23 +00:00
6) Create Android app
2023-04-01 20:13:16 +00:00
```bash
2023-09-05 18:04:23 +00:00
npm i --save @capacitor/android
npx cap add android
2023-01-05 23:33:49 +00:00
```
2023-09-05 18:04:23 +00:00
7) Enable file reading and writing in the Android app.
2023-12-05 03:46:54 +00:00
Add the highlighted lines to `android/app/src/main/AndroidManifest.xml` after
the `Permissions` comment:
2023-09-05 18:04:23 +00:00
```xml title="android/app/src/main/AndroidManifest.xml (add to file)"
<!-- Permissions -->
2023-04-01 20:13:16 +00:00
<!-- highlight - start -->
2023-09-05 18:04:23 +00:00
< uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" / >
2023-09-11 04:44:15 +00:00
< uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" / >
2023-04-01 20:13:16 +00:00
<!-- highlight - end -->
2023-01-05 23:33:49 +00:00
2023-09-05 18:04:23 +00:00
< uses-permission android:name = "android.permission.INTERNET" / >
```
2023-01-05 23:33:49 +00:00
2024-05-28 05:20:05 +00:00
8) Run the app in the simulator:
2023-01-05 23:33:49 +00:00
2023-04-01 20:13:16 +00:00
```bash
npm run build
npx cap sync
2023-09-05 18:04:23 +00:00
npx cap run android
2023-04-01 20:13:16 +00:00
```
2023-01-05 23:33:49 +00:00
2024-05-28 05:20:05 +00:00
The app should look like the screenshot at the top of the page.
2023-01-05 23:33:49 +00:00
2024-05-28 05:20:05 +00:00
9) Test the export functionality.
2023-01-05 23:33:49 +00:00
2024-05-28 05:20:05 +00:00
Touch "Export XLSX" and the emulator will ask for permission. Tap "Allow" and a
popup will be displayed with a path.
2023-04-01 20:13:16 +00:00
2024-05-28 05:20:05 +00:00
Open the "Files" app in the simulator, tap the `≡` icon and tap "Documents". Tap
the "Documents" folder to find `SheetJSCap.xlsx` .
2023-04-01 20:13:16 +00:00
2024-05-28 05:20:05 +00:00
< details open >
< summary > < b > Downloading the generated file< / b > (click to hide)< / summary >
`adb` must be run from the root user:
```bash
adb root
```
The file location can be found by searching for `SheetJSCap.xlsx` :
```bash
adb exec-out find / -name SheetJSCap.xlsx
```
The first line of the output starting with `/` is the desired path:
```text
find: /proc/8533/task/8533/exe: No such file or directory
find: /proc/8533/exe: No such file or directory
// highlight-next-line
/data/media/0/Documents/SheetJSCap.xlsx
/storage/emulated/0/Documents/SheetJSCap.xlsx
```
`adb pull` can download the file:
```bash
adb pull "/data/media/0/Documents/SheetJSCap.xlsx" SheetJSCap.xlsx
```
`SheetJSCap.xlsx` can be opened with a spreadsheet editor such as Excel.
< / details >
2023-04-01 20:13:16 +00:00
2023-09-05 18:04:23 +00:00
### iOS
2023-04-01 20:13:16 +00:00
2023-09-05 18:04:23 +00:00
10) Create iOS app
2023-04-01 20:13:16 +00:00
```bash
2023-09-05 18:04:23 +00:00
npm i --save @capacitor/ios
npx cap add ios
2023-01-05 23:33:49 +00:00
```
2023-09-05 18:04:23 +00:00
11) 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` :
2023-04-01 20:13:16 +00:00
2023-09-05 18:04:23 +00:00
```xml title="ios/App/App/Info.plist (add to file)"
< plist version = "1.0" >
< dict >
2023-04-01 20:13:16 +00:00
<!-- highlight - start -->
2023-09-05 18:04:23 +00:00
< key > UIFileSharingEnabled< / key >
< true / >
< key > LSSupportsOpeningDocumentsInPlace< / key >
< true / >
2023-04-01 20:13:16 +00:00
<!-- highlight - end -->
2023-09-05 18:04:23 +00:00
< key > CFBundleDevelopmentRegion< / key >
2023-04-01 20:13:16 +00:00
```
2023-09-05 18:04:23 +00:00
(The root element of the document is `plist` and it contains one `dict` child)
12) Run the app in the simulator
2023-01-05 23:33:49 +00:00
```bash
2023-04-01 20:13:16 +00:00
npm run build
npx cap sync
2023-09-05 18:04:23 +00:00
npx cap run ios
2023-01-05 23:33:49 +00:00
```
2023-12-05 03:46:54 +00:00
If prompted to select a target device, select "iPhone 15 Pro Max (simulator)".
2023-09-05 18:04:23 +00:00
13) Test the app
2023-04-01 20:13:16 +00:00
Open the app and observe that presidents are listed in the table.
2023-09-05 18:04:23 +00:00
Touch "Export XLSX" and a popup will be displayed.
2023-04-01 20:13:16 +00:00
2023-09-05 18:04:23 +00:00
To see the generated file, switch to the "Files" app in the simulator and look
for `SheetJSCap.xlsx` in "On My iPhone" > "`sheetjs-cap`"
2023-01-05 23:33:49 +00:00
2023-12-05 03:46:54 +00:00
### Android Device
14) Connect an Android device using a USB cable.
If the device asks to allow USB debugging, tap "Allow".
15) Close any Android / iOS emulators.
16) Build APK and run on device:
```bash
npm run build
npx cap sync
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.
:::caution pass
For real devices running API level 29 or below, the following line must be added
to the `application` open tag in `android/app/src/main/AndroidManifest.xml` :
```xml title="android/app/src/main/AndroidManifest.xml (add highlighted attribute)"
< application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
// highlight-next-line
android:requestLegacyExternalStorage="true"
android:theme="@style/AppTheme">
```
:::
### iOS Device
17) Connect an iOS device using a USB cable
18) Close any Android / iOS emulators.
19) Enable developer code signing certificates[^2]
19) Run on device:
```bash
npm run build
npx cap sync
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`