--- title: CapacitorJS pagination_prev: demos/static/index pagination_next: demos/desktop/index sidebar_position: 5 sidebar_custom_props: summary: JS + Web View --- import current from '/version.js'; import CodeBlock from '@theme/CodeBlock'; The [NodeJS Module](/docs/getting-started/installation/nodejs) can be imported from the main entrypoint or any script in the project. The "Complete Example" creates an app that looks like the screenshots below: <table><thead><tr> <th><a href="#demo">iOS</a></th> <th><a href="#demo">Android</a></th> </tr></thead><tbody><tr><td>  </td><td>  </td></tr></tbody></table> :::warning Telemetry 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 ``` ::: ## Integration Details 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> ``` ## Demo :::note This demo was tested on an Intel Mac on 2023 April 01 with Capacitor 4.7.3 and `@capacitor/filesystem` 4.1.4 The iOS simulator runs iOS 16.2 on an iPhone 14 Pro Max. The Android simulator runs Android 12.0 (S) API 31 on a Pixel 3. ::: ### Base Project 1) Disable telemetry. ```bash npx @capacitor/cli telemetry off ``` Verify that telemetry is disabled by running ```bash npx @capacitor/cli telemetry ``` (it should print `Telemetry is off`) 2) Create a new Svelte project: ```bash npm create vite@latest sheetjs-cap -- --template svelte cd sheetjs-cap ``` 3) Install dependencies: <CodeBlock language="bash">{`\ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz npm i --save @capacitor/core @capacitor/cli @capacitor/filesystem`} </CodeBlock> 4) Create CapacitorJS structure: ```bash npx cap init sheetjs-cap com.sheetjs.cap --web-dir=dist npm run build ``` 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 ``` ### iOS 6) Follow the [React Native demo](/docs/demos/mobile/reactnative#demo) to ensure the iOS simulator is ready. 7) Create iOS app ```bash npm i --save @capacitor/ios npx cap add ios ``` 8) 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" <plist version="1.0"> <dict> <!-- highlight-start --> <key>UIFileSharingEnabled</key> <true/> <key>LSSupportsOpeningDocumentsInPlace</key> <true/> <!-- highlight-end --> <key>CFBundleDevelopmentRegion</key> ``` (The root element of the document is `plist` and it contains one `dict` child) 9) Run the app in the simulator ```bash npm run build npx cap sync npx cap run ios ``` 10) Test the app Open the app and observe that presidents are listed in the table. 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`" ### Android 11) Follow the [React Native demo](/docs/demos/mobile/reactnative#demo) to ensure the Android simulator is ready. 12) Create Android app ```bash npm i --save @capacitor/android npx cap add android ``` 13) Enable file reading and writing in the Android app. The following lines must be added to `android/app/src/main/AndroidManifest.xml` after the `Permissions` comment: ```xml title="android/app/src/main/AndroidManifest.xml" <!-- Permissions --> <!-- highlight-start --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- highlight-end --> <uses-permission android:name="android.permission.INTERNET" /> ``` 14) Run the app in the simulator ```bash npm run build npx cap sync npx cap run android ``` 15) Test the app Open the app and observe that presidents are listed in the table. Touch "Export XLSX" and the emulator will ask for permission: Tap "Allow" and a popup will be displayed with a path. To see the generated file, switch to the "Files" app in the simulator, tap the `≡` icon and tap "Documents". Tap "Documents" folder to find `SheetJSCap.xlsx`.