docs.sheetjs.com/docz/docs/03-demos/02-mobile/05-capacitor.md
2023-01-09 19:57:01 -05:00

4.3 KiB
Raw Blame History

title pagination_prev pagination_next sidebar_position sidebar_custom_props
CapacitorJS demos/frontend/index demos/desktop/index 5
summary
JS + Web View

CapacitorJS

:::note

This demo was tested on an Intel Mac on 2022 August 26 with Svelte.

The iOS simulator runs iOS 15.5 on an iPhone 13 Pro Max.

:::

:::warning Telemetry

Before starting this demo, manually disable telemetry. On Linux and MacOS:

npx @capacitor/cli telemetry off

To verify telemetry was disabled:

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:

<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:

<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

Complete Example (click to show)
  1. Disable telemetry as noted in the warning.

Follow the React Native demo to ensure iOS and Android sims are ready.

  1. Create a new Svelte project:
npm create vite@latest sheetjs-cap -- --template svelte
cd sheetjs-cap
  1. Install dependencies:
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
npm i --save @capacitor/core @capacitor/cli @capacitor/ios @capacitor/filesystem
  1. Create CapacitorJS structure:
npx cap init sheetjs-cap com.sheetjs.cap --web-dir=dist
npx cap add ios
  1. Replace the contents of src/App.svelte with the following:
<script>
import { Filesystem, Directory, Encoding } from '@capacitor/filesystem';
import { onMount } from 'svelte';
import { read, utils, version, writeXLSX } from 'xlsx';

let html = "";
let tbl;

/* Fetch and update the state once */
onMount(async() => {
  const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
  const wb = read(f); // parse the array buffer
  const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
  html = utils.sheet_to_html(ws); // generate HTML and update state
});

/* 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 */
  const data = writeXLSX(wb, { type: "base64" });
  /* write */
  await Filesystem.writeFile({
    path: "SheetJSCap.xlsx",
    data,
    directory: Directory.Documents
  });
}

/* show file picker, read file, load table */
async function importFile(evt) {
  const f = evt.target.files[0];
  const wb = read(await f.arrayBuffer());
  const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
  html = utils.sheet_to_html(ws); // generate HTML and update state
}
</script>

<main>
  <h3>SheetJS × CapacitorJS { version }</h3>
  <input type="file" on:change={importFile}/>
  <button on:click={exportFile}>Export XLSX</button>
  <div bind:this={tbl}>{@html html}</div>
</main>
  1. Test the app:
npm run build; npx cap sync; npx cap run ios

There are 3 steps: build the Svelte app, sync with CapacitorJS, and run sim. This sequence must be run every time to ensure changes are propagated.