win10-x64 refresh
576
docz/docs/03-demos/02-frontend/01-kaioken.md
Normal file
@ -0,0 +1,576 @@
|
||||
---
|
||||
title: Super Saiyan Sheets with Kaioken
|
||||
sidebar_label: Kaioken
|
||||
description: Build interactive websites with Kaioken. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
|
||||
pagination_prev: demos/index
|
||||
pagination_next: demos/grid/index
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[Kaioken](https://kaioken.dev/) is a JavaScript library for building user
|
||||
interfaces.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
This demo uses Kaioken and SheetJS to process and generate spreadsheets. We'll
|
||||
explore how to load SheetJS in "Kaioponents" (Kaioken components) and compare
|
||||
common state models and data flow strategies.
|
||||
|
||||
:::note pass
|
||||
|
||||
This demo focuses on Kaioken concepts. Other demos cover general deployments:
|
||||
|
||||
- [Desktop application powered by Tauri](/docs/demos/desktop/tauri)
|
||||
|
||||
:::
|
||||
|
||||
## Installation
|
||||
|
||||
[The "Frameworks" section](/docs/getting-started/installation/frameworks) covers
|
||||
installation with Yarn and other package managers.
|
||||
|
||||
The library can be imported directly from JS or JSX code with:
|
||||
|
||||
```js
|
||||
import { read, utils, writeFile } from 'xlsx';
|
||||
```
|
||||
|
||||
|
||||
## Internal State
|
||||
|
||||
The various SheetJS APIs work with various data shapes. The preferred state
|
||||
depends on the application.
|
||||
|
||||
### Array of Objects
|
||||
|
||||
Typically, some users will create a spreadsheet with source data that should be
|
||||
loaded into the site. This sheet will have known columns.
|
||||
|
||||
#### State
|
||||
|
||||
The example [presidents sheet](https://sheetjs.com/pres.xlsx) has one header row
|
||||
with "Name" and "Index" columns. The natural JS representation is an object for
|
||||
each row, using the values in the first rows as keys:
|
||||
|
||||
<table><thead><tr><th>Spreadsheet</th><th>State</th></tr></thead><tbody><tr><td>
|
||||
|
||||
![`pres.xlsx` data](pathname:///pres.png)
|
||||
|
||||
</td><td>
|
||||
|
||||
```js
|
||||
[
|
||||
{ Name: "Bill Clinton", Index: 42 },
|
||||
{ Name: "GeorgeW Bush", Index: 43 },
|
||||
{ Name: "Barack Obama", Index: 44 },
|
||||
{ Name: "Donald Trump", Index: 45 },
|
||||
{ Name: "Joseph Biden", Index: 46 }
|
||||
]
|
||||
```
|
||||
|
||||
</td></tr></tbody></table>
|
||||
|
||||
The Kaioken `useState`[^1] hook can configure the state:
|
||||
|
||||
<Tabs groupId="lang">
|
||||
<TabItem name="JS" value="JavaScript">
|
||||
|
||||
```ts
|
||||
import { useState } from 'kaioken';
|
||||
|
||||
/* the kaioponent state is an array of objects */
|
||||
const [pres, setPres] = useState([]);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem name="TS" value="TypeScript" default>
|
||||
|
||||
```ts
|
||||
import { useState } from 'kaioken';
|
||||
|
||||
/* the kaioponent state is an array of objects */
|
||||
const [pres, setPres] = useState<any[]>([]);
|
||||
```
|
||||
|
||||
When the spreadsheet header row is known ahead of time, row typing is possible:
|
||||
|
||||
```ts
|
||||
import { useState } from 'kaioken';
|
||||
|
||||
interface President {
|
||||
Name: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
/* the kaioponent state is an array of presidents */
|
||||
const [pres, setPres] = useState<President[]>([]);
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
The types are informative. They do not enforce that worksheets include the named
|
||||
columns. A runtime data validation library should be used to verify the dataset.
|
||||
|
||||
When the file header is not known in advance, `any` should be used.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Updating State
|
||||
|
||||
The SheetJS [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/utilities/array#array-output)
|
||||
functions simplify state updates. They are best used in the function bodies of
|
||||
`useEffect`[^2] and `useCallback`[^3] hooks.
|
||||
|
||||
A `useEffect` hook can download and update state when a person loads the site:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
url[(Remote\nFile)]
|
||||
ab[(Data\nArrayBuffer)]
|
||||
wb(SheetJS\nWorkbook)
|
||||
ws(SheetJS\nWorksheet)
|
||||
aoo(array of\nobjects)
|
||||
state((Kaioponent\nstate))
|
||||
url --> |fetch\n\n| ab
|
||||
ab --> |read\n\n| wb
|
||||
wb --> |wb.Sheets\nselect sheet| ws
|
||||
ws --> |sheet_to_json\n\n| aoo
|
||||
aoo --> |setPres\nfrom `setState`| state
|
||||
```
|
||||
|
||||
<Tabs groupId="lang">
|
||||
<TabItem name="JS" value="JavaScript">
|
||||
|
||||
```js
|
||||
import { useEffect } from 'kaioken';
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
/* Fetch and update the state once */
|
||||
useEffect(() => { (async() => {
|
||||
/* Download from https://sheetjs.com/pres.numbers */
|
||||
const f = await fetch("https://sheetjs.com/pres.numbers");
|
||||
const ab = await f.arrayBuffer();
|
||||
|
||||
// highlight-start
|
||||
/* parse */
|
||||
const wb = read(ab);
|
||||
|
||||
/* generate array of objects from first worksheet */
|
||||
const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
|
||||
const data = utils.sheet_to_json(ws); // generate objects
|
||||
|
||||
/* update state */
|
||||
setPres(data); // update state
|
||||
// highlight-end
|
||||
})(); }, []);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem name="TS" value="TypeScript" default>
|
||||
|
||||
```ts
|
||||
import { useEffect } from 'kaioken';
|
||||
import { read, utils } from 'xlsx';
|
||||
|
||||
/* Fetch and update the state once */
|
||||
useEffect(() => { (async() => {
|
||||
/* Download from https://sheetjs.com/pres.numbers */
|
||||
const f = await fetch("https://sheetjs.com/pres.numbers");
|
||||
const ab = await f.arrayBuffer();
|
||||
|
||||
// highlight-start
|
||||
/* parse */
|
||||
const wb = read(ab);
|
||||
|
||||
/* generate array of presidents from the first worksheet */
|
||||
const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
|
||||
const data: President[] = utils.sheet_to_json<President>(ws); // generate objects
|
||||
|
||||
/* update state */
|
||||
setPres(data); // update state
|
||||
// highlight-end
|
||||
})(); }, []);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Rendering Data
|
||||
|
||||
Kaioponents typically render HTML tables from arrays of objects. The `TR` table
|
||||
row elements are typically generated by mapping over the state array, as shown
|
||||
in the example JSX code:
|
||||
|
||||
```jsx title="Example JSX for displaying arrays of objects"
|
||||
<table>
|
||||
{/* The `thead` section includes the table header row */}
|
||||
<thead><tr><th>Name</th><th>Index</th></tr></thead>
|
||||
{/* The `tbody` section includes the data rows */}
|
||||
<tbody>
|
||||
{/* generate row (TR) for each president */}
|
||||
// highlight-start
|
||||
{pres.map(row => (
|
||||
<tr>
|
||||
{/* Generate cell (TD) for name / index */}
|
||||
<td>{row.Name}</td>
|
||||
<td>{row.Index}</td>
|
||||
</tr>
|
||||
))}
|
||||
// highlight-end
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
|
||||
#### Exporting Data
|
||||
|
||||
The [`writeFile`](/docs/api/write-options) and [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
|
||||
functions simplify exporting data. They are best used in the function bodies of
|
||||
`useCallback`[^4] hooks attached to button or other elements.
|
||||
|
||||
A callback can generate a local file when a user clicks a button:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
state((Kaioponent\nstate))
|
||||
ws(SheetJS\nWorksheet)
|
||||
wb(SheetJS\nWorkbook)
|
||||
file[(XLSX\nexport)]
|
||||
state --> |json_to_sheet\n\n| ws
|
||||
ws --> |book_new\nbook_append_sheet| wb
|
||||
wb --> |writeFile\n\n| file
|
||||
```
|
||||
|
||||
```ts
|
||||
import { useCallback } from 'kaioken';
|
||||
import { utils, writeFile } from 'xlsx';
|
||||
|
||||
/* get state data and export to XLSX */
|
||||
const exportFile = useCallback(() => {
|
||||
/* generate worksheet from state */
|
||||
// highlight-next-line
|
||||
const ws = utils.json_to_sheet(pres);
|
||||
/* create workbook and append worksheet */
|
||||
const wb = utils.book_new();
|
||||
utils.book_append_sheet(wb, ws, "Data");
|
||||
/* export to XLSX */
|
||||
writeFile(wb, "SheetJSKaiokenAoO.xlsx");
|
||||
}, [pres]);
|
||||
```
|
||||
|
||||
#### Complete Kaioponent
|
||||
|
||||
This complete Kaioponent example fetches a test file and displays the data in a
|
||||
HTML table. When the export button is clicked, a callback will export a file:
|
||||
|
||||
```tsx title="src/SheetJSKaiokenAoO.tsx"
|
||||
import { useCallback, useEffect, useState } from "kaioken";
|
||||
import { read, utils, writeFileXLSX } from 'xlsx';
|
||||
|
||||
interface President {
|
||||
Name: string;
|
||||
Index: number;
|
||||
}
|
||||
|
||||
export default function SheetJSKaiokenAoO() {
|
||||
/* the kaioponent state is an array of presidents */
|
||||
const [pres, setPres] = useState<President[]>([]);
|
||||
|
||||
/* Fetch and update the state once */
|
||||
useEffect(() => { (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
|
||||
const data = utils.sheet_to_json<President>(ws); // generate objects
|
||||
setPres(data); // update state
|
||||
})(); }, []);
|
||||
|
||||
/* get state data and export to XLSX */
|
||||
const exportFile = useCallback(() => {
|
||||
const ws = utils.json_to_sheet(pres);
|
||||
const wb = utils.book_new();
|
||||
utils.book_append_sheet(wb, ws, "Data");
|
||||
writeFileXLSX(wb, "SheetJSKaiokenAoO.xlsx");
|
||||
}, [pres]);
|
||||
|
||||
return (<table><thead><tr><th>Name</th><th>Index</th></tr></thead><tbody>
|
||||
{ /* generate row for each president */
|
||||
pres.map(pres => (<tr>
|
||||
<td>{pres.Name}</td>
|
||||
<td>{pres.Index}</td>
|
||||
</tr>))
|
||||
}
|
||||
</tbody><tfoot><td colSpan={2}>
|
||||
<button onclick={exportFile}>Export XLSX</button>
|
||||
</td></tfoot></table>);
|
||||
}
|
||||
```
|
||||
|
||||
<details open><summary><b>How to run the example</b> (click to hide)</summary>
|
||||
|
||||
<Tabs groupId="starter">
|
||||
<TabItem name="vite" value="ViteJS">
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| Kaioken | ViteJS | Date |
|
||||
|:---------|:--------|:-----------|
|
||||
| `0.11.2` | `5.2.6` | 2024-03-24 |
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new site.
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-kaioken -- --template vanilla-ts
|
||||
cd sheetjs-kaioken
|
||||
pnpm add --save kaioken
|
||||
pnpm add --save vite-plugin-kaioken -D
|
||||
```
|
||||
|
||||
2) Create a new file `vite.config.ts` with the following content:
|
||||
|
||||
```ts title="vite.config.ts (create new file)"
|
||||
import { defineConfig } from "vite"
|
||||
import kaioken from "vite-plugin-kaioken"
|
||||
|
||||
export default defineConfig({
|
||||
esbuild: {
|
||||
jsxInject: `import * as kaioken from "kaioken"`,
|
||||
jsx: "transform",
|
||||
jsxFactory: "kaioken.createElement",
|
||||
jsxFragment: "kaioken.fragment",
|
||||
loader: "tsx",
|
||||
include: ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
|
||||
},
|
||||
plugins: [kaioken()],
|
||||
})
|
||||
```
|
||||
|
||||
3) Edit `tsconfig.json` and add `"jsx": "preserve"` within `compilerOptions`:
|
||||
|
||||
```js title="tsconfig.json (add highlighted line)"
|
||||
{
|
||||
"compilerOptions": {
|
||||
// highlight-next-line
|
||||
"jsx": "preserve",
|
||||
```
|
||||
|
||||
4) Replace `src/main.ts` with the following codeblock:
|
||||
|
||||
```ts title="src/main.ts (replace contents)"
|
||||
import { mount } from "kaioken";
|
||||
import App from "./SheetJSKaiokenAoO";
|
||||
|
||||
const root = document.getElementById("app");
|
||||
mount(App, root!);
|
||||
```
|
||||
|
||||
5) Create a new file `src/SheetJSKaiokenAoO.tsx` using the original code example.
|
||||
|
||||
6) Install the SheetJS dependency and start the dev server:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
pnpm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
|
||||
pnpm run dev`}
|
||||
</CodeBlock>
|
||||
|
||||
7) Open a web browser and access the displayed URL (`http://localhost:5173`)
|
||||
|
||||
The page will refresh and show a table with an Export button. Click the button
|
||||
and the page will attempt to download `SheetJSKaiokenAoO.xlsx`.
|
||||
|
||||
8) Build the site:
|
||||
|
||||
```bash
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
The generated site will be placed in the `dist` folder.
|
||||
|
||||
9) Start a local web server:
|
||||
|
||||
```bash
|
||||
npx http-server dist
|
||||
```
|
||||
|
||||
Access the displayed URL (typically `http://localhost:8080`) with a web browser
|
||||
and test the page.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
When the page loads, the app will fetch <https://sheetjs.com/pres.xlsx> and
|
||||
display the data from the first worksheet in a TABLE. The "Export XLSX" button
|
||||
will generate a workbook that can be opened in a spreadsheet editor.
|
||||
|
||||
</details>
|
||||
|
||||
### HTML
|
||||
|
||||
The main disadvantage of the Array of Objects approach is the specific nature
|
||||
of the columns. For more general use, passing around an Array of Arrays works.
|
||||
However, this does not handle merge cells well!
|
||||
|
||||
The [`sheet_to_html`](/docs/api/utilities/html#html-table-output) function
|
||||
generates HTML that is aware of merges and other worksheet features. To add the
|
||||
table to the page, the current recommendation involves setting the `innerHTML`
|
||||
attribute of a `ref`.
|
||||
|
||||
In this example, the kaioponent attaches a `ref` to the `DIV` container. During
|
||||
export, the first `TABLE` child element can be parsed with [`table_to_book`](/docs/api/utilities/html#html-table-input) to
|
||||
generate a workbook object.
|
||||
|
||||
```tsx title="src/SheetJSKaiokenHTML.tsx"
|
||||
import { useCallback, useEffect, useRef } from "kaioken";
|
||||
import { read, utils, writeFileXLSX } from 'xlsx';
|
||||
|
||||
export default function SheetJSKaiokenHTML() {
|
||||
/* the ref is used in export */
|
||||
const tbl = useRef<Element>(null);
|
||||
|
||||
/* Fetch and update the state once */
|
||||
useEffect(() => { (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
|
||||
// highlight-start
|
||||
const data = utils.sheet_to_html(ws); // generate HTML
|
||||
if(tbl.current == null) return;
|
||||
tbl.current.innerHTML = data;
|
||||
// highlight-end
|
||||
})(); }, []);
|
||||
|
||||
/* get live table and export to XLSX */
|
||||
const exportFile = useCallback(() => {
|
||||
// highlight-start
|
||||
const elt = tbl.current!.getElementsByTagName("TABLE")[0];
|
||||
const wb = utils.table_to_book(elt);
|
||||
// highlight-end
|
||||
writeFileXLSX(wb, "SheetJSKaiokenHTML.xlsx");
|
||||
}, [tbl]);
|
||||
|
||||
return ( <>
|
||||
<button onclick={exportFile}>Export XLSX</button>
|
||||
// highlight-next-line
|
||||
<div ref={tbl}/>
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
||||
<details open><summary><b>How to run the example</b> (click to hide)</summary>
|
||||
|
||||
<Tabs groupId="starter">
|
||||
<TabItem name="vite" value="ViteJS">
|
||||
|
||||
:::note Tested Deployments
|
||||
|
||||
This demo was tested in the following environments:
|
||||
|
||||
| Kaioken | ViteJS | Date |
|
||||
|:---------|:--------|:-----------|
|
||||
| `0.11.2` | `5.2.6` | 2024-03-24 |
|
||||
|
||||
:::
|
||||
|
||||
1) Create a new site.
|
||||
|
||||
```bash
|
||||
npm create vite@latest sheetjs-kaioken -- --template vanilla-ts
|
||||
cd sheetjs-kaioken
|
||||
pnpm add --save kaioken
|
||||
pnpm add --save vite-plugin-kaioken -D
|
||||
```
|
||||
|
||||
2) Create a new file `vite.config.ts` with the following content:
|
||||
|
||||
```ts title="vite.config.ts (create new file)"
|
||||
import { defineConfig } from "vite"
|
||||
import kaioken from "vite-plugin-kaioken"
|
||||
|
||||
export default defineConfig({
|
||||
esbuild: {
|
||||
jsxInject: `import * as kaioken from "kaioken"`,
|
||||
jsx: "transform",
|
||||
jsxFactory: "kaioken.createElement",
|
||||
jsxFragment: "kaioken.fragment",
|
||||
loader: "tsx",
|
||||
include: ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
|
||||
},
|
||||
plugins: [kaioken()],
|
||||
})
|
||||
```
|
||||
|
||||
3) Edit `tsconfig.json` and add `"jsx": "preserve"` within `compilerOptions`:
|
||||
|
||||
```js title="tsconfig.json (add highlighted line)"
|
||||
{
|
||||
"compilerOptions": {
|
||||
// highlight-next-line
|
||||
"jsx": "preserve",
|
||||
```
|
||||
|
||||
4) Replace `src/main.ts` with the following codeblock:
|
||||
|
||||
```ts title="src/main.ts (replace contents)"
|
||||
import { mount } from "kaioken";
|
||||
import App from "./SheetJSKaiokenHTML";
|
||||
|
||||
const root = document.getElementById("app");
|
||||
mount(App, root!);
|
||||
```
|
||||
|
||||
5) Create a new file `src/SheetJSKaiokenHTML.tsx` using the original code example.
|
||||
|
||||
6) Install the SheetJS dependency and start the dev server:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
pnpm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
|
||||
pnpm run dev`}
|
||||
</CodeBlock>
|
||||
|
||||
7) Open a web browser and access the displayed URL (`http://localhost:5173`)
|
||||
|
||||
The page will refresh and show a table with an Export button. Click the button
|
||||
and the page will attempt to download `SheetJSKaiokenHTML.xlsx`.
|
||||
|
||||
8) Build the site:
|
||||
|
||||
```bash
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
The generated site will be placed in the `dist` folder.
|
||||
|
||||
9) Start a local web server:
|
||||
|
||||
```bash
|
||||
npx http-server dist
|
||||
```
|
||||
|
||||
Access the displayed URL (typically `http://localhost:8080`) with a web browser
|
||||
and test the page.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
When the page loads, the app will fetch <https://sheetjs.com/pres.xlsx> and
|
||||
display the data from the first worksheet in a TABLE. The "Export XLSX" button
|
||||
will generate a workbook that can be opened in a spreadsheet editor.
|
||||
|
||||
</details>
|
||||
|
||||
[^1]: See [`useState`](https://kaioken.dev/docs/hooks/usestate) in the Kaioken documentation.
|
||||
[^2]: See [`useEffect`](https://kaioken.dev/docs/hooks/useeffect) in the Kaioken documentation.
|
||||
[^3]: See [`useCallback`](https://kaioken.dev/docs/hooks/usecallback) in the Kaioken documentation.
|
||||
[^4]: See [`useCallback`](https://kaioken.dev/docs/hooks/usecallback) in the Kaioken documentation.
|
@ -4,7 +4,7 @@ sidebar_label: ReactJS
|
||||
description: Build interactive websites with ReactJS. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
|
||||
pagination_prev: demos/index
|
||||
pagination_next: demos/grid/index
|
||||
sidebar_position: 1
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
@ -4,7 +4,7 @@ sidebar_label: VueJS
|
||||
description: Build interactive websites with VueJS. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
|
||||
pagination_prev: demos/index
|
||||
pagination_next: demos/grid/index
|
||||
sidebar_position: 2
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
@ -4,7 +4,7 @@ sidebar_label: Svelte
|
||||
description: Build interactive websites with Svelte. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
|
||||
pagination_prev: demos/index
|
||||
pagination_next: demos/grid/index
|
||||
sidebar_position: 4
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
@ -405,7 +405,7 @@ This demo was tested in the following environments:
|
||||
| Architecture | PhantomJS | Date |
|
||||
|:-------------|:----------|:-----------|
|
||||
| `darwin-x64` | `2.1.1` | 2024-03-15 |
|
||||
| `win10-x64` | `2.1.1` | 2024-02-23 |
|
||||
| `win10-x64` | `2.1.1` | 2024-03-24 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -299,7 +299,7 @@ This demo was tested in the following environments:
|
||||
|:---------------|:-------------|:---------|:-----------|
|
||||
| macOS 14.4 | `darwin-x64` | `v2.8.0` | 2024-03-15 |
|
||||
| macOS 14.1.2 | `darwin-arm` | `v2.6.0` | 2023-12-01 |
|
||||
| Windows 10 | `win10-x64` | `v2.8.0` | 2024-03-10 |
|
||||
| Windows 10 | `win10-x64` | `v2.8.0` | 2024-03-24 |
|
||||
| Windows 11 | `win11-arm` | `v2.6.0` | 2023-12-01 |
|
||||
| Linux (HoloOS) | `linux-x64` | `v2.8.0` | 2024-03-21 |
|
||||
| Linux (Debian) | `linux-arm` | `v2.6.0` | 2023-12-01 |
|
||||
|
@ -150,10 +150,14 @@ async function openFile() {
|
||||
|
||||
At this point, standard SheetJS utility functions[^8] can extract data from the
|
||||
workbook object. The demo includes a button that calls `sheet_to_json`[^9] to
|
||||
generate an array of arrays of data. The following snippet uses VueJS framework
|
||||
but the same logic works with ReactJS and other front-end frameworks:
|
||||
generate an array of arrays of data.
|
||||
|
||||
```js
|
||||
<Tabs groupId="framework">
|
||||
<TabItem value="vuejs" label="VueJS">
|
||||
|
||||
The following snippet uses the VueJS framework:
|
||||
|
||||
```js title="VueJS sample"
|
||||
import { utils } from 'xlsx';
|
||||
import { shallowRef } from 'vue';
|
||||
const data = shallowRef([[]]); // update data by setting `data.value`
|
||||
@ -174,6 +178,45 @@ const open_button_callback = async() => {
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="kaioken" label="Kaioken" default>
|
||||
|
||||
The following snippet shows a simple Kaioponent:
|
||||
|
||||
```tsx title="Kaioponent for importing data"
|
||||
import { utils } from 'xlsx';
|
||||
import { useState } from 'kaioken';
|
||||
|
||||
function SheetJSImportKaioponent() {
|
||||
const [data, setData] = useState<any[][]>([]);
|
||||
|
||||
const open_callback = async() => {
|
||||
const wb = await openFile();
|
||||
|
||||
/* get the first worksheet */
|
||||
// highlight-start
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
// highlight-end
|
||||
|
||||
/* get data from the first worksheet */
|
||||
// highlight-start
|
||||
const array = utils.sheet_to_json(ws, { header: 1 });
|
||||
// highlight-end
|
||||
setData(array);
|
||||
};
|
||||
|
||||
return ( <>
|
||||
<button type="button" onclick={open_callback}>Load Data</button>
|
||||
<table><tbody>{data.map((row) =>
|
||||
<tr>{row.map((cell) => <td>{cell}</td>)}</tr>
|
||||
)}</tbody></table>
|
||||
</>);
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Writing Files
|
||||
|
||||
There are three steps to writing files:
|
||||
@ -221,10 +264,14 @@ async function saveFile(wb) {
|
||||
|
||||
The demo includes a button that calls `aoa_to_sheet`[^14] to generate a sheet
|
||||
from array of arrays of data. A workbook is constructed using `book_new` and
|
||||
`book_append_sheet`[^15]. The following snippet uses VueJS framework but the
|
||||
same logic works with ReactJS and other front-end frameworks:
|
||||
`book_append_sheet`[^15].
|
||||
|
||||
```js
|
||||
<Tabs groupId="framework">
|
||||
<TabItem value="vuejs" label="VueJS">
|
||||
|
||||
The following snippet uses the VueJS framework:
|
||||
|
||||
```js title="VueJS sample"
|
||||
import { utils } from 'xlsx';
|
||||
import { shallowRef } from 'vue';
|
||||
const data = shallowRef([[]]); // `data.value` is an array of arrays
|
||||
@ -249,6 +296,45 @@ const save_button_callback = async() => {
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="kaioken" label="Kaioken" default>
|
||||
|
||||
The following snippet shows a simple Kaioponent:
|
||||
|
||||
```js title="Kaioponent for exporting data"
|
||||
import { utils } from 'xlsx';
|
||||
import { useState } from 'kaioken';
|
||||
|
||||
function SheetJSExportKaioponent() {
|
||||
const [data, setData] = useState<any[][]>(["SheetJS".split(""), "Kaioken".split("")]);
|
||||
|
||||
const save_callback = async() => {
|
||||
/* generate worksheet from the data */
|
||||
// highlight-start
|
||||
const ws = utils.aoa_to_sheet(data);
|
||||
// highlight-end
|
||||
|
||||
/* create a new workbook object */
|
||||
// highlight-start
|
||||
const wb = utils.book_new();
|
||||
// highlight-end
|
||||
|
||||
/* append the worksheet to the workbook using the sheet name "SheetJSTauri" */
|
||||
// highlight-start
|
||||
utils.book_append_sheet(wb, ws, "SheetJSTauri");
|
||||
// highlight-end
|
||||
|
||||
await saveFile(wb);
|
||||
}
|
||||
|
||||
return ( <button type="button" onclick={save_callback}>Save Data</button> );
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Complete Example
|
||||
|
||||
:::note Tested Deployments
|
||||
@ -259,7 +345,7 @@ This demo was tested in the following environments:
|
||||
|:---------------|:-------------|:----------|:-----------|
|
||||
| macOS 14.4 | `darwin-x64` | `v1.5.11` | 2024-03-15 |
|
||||
| macOS 14.0 | `darwin-arm` | `v1.5.2` | 2023-10-18 |
|
||||
| Windows 10 | `win10-x64` | `v1.5.0` | 2023-10-01 |
|
||||
| Windows 10 | `win10-x64` | `v1.5.11` | 2024-03-24 |
|
||||
| Windows 11 | `win11-arm` | `v1.5.7` | 2023-12-01 |
|
||||
| Linux (HoloOS) | `linux-x64` | `v1.5.11` | 2024-03-21 |
|
||||
| Linux (Debian) | `linux-arm` | `v1.5.7` | 2023-12-01 |
|
||||
@ -309,10 +395,30 @@ build step will correctly detect the platform architecture.
|
||||
|
||||
1) Create a new Tauri app:
|
||||
|
||||
<Tabs groupId="framework">
|
||||
<TabItem value="vuejs" label="VueJS">
|
||||
|
||||
```bash
|
||||
npm create tauri-app@latest -- -m npm -t vue-ts SheetJSTauri -y
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="kaioken" label="Kaioken" default>
|
||||
|
||||
:::note pass
|
||||
|
||||
There is no official Tauri Kaioken template. This demo starts from the vanilla
|
||||
TypeScript template and manually wires Kaioken
|
||||
|
||||
:::
|
||||
|
||||
```bash
|
||||
npm create tauri-app@latest -- -m npm -t vanilla-ts SheetJSTauri -y
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
2) Enter the directory and install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
@ -322,6 +428,20 @@ npm i --save @tauri-apps/api
|
||||
npm i --save-dev @tauri-apps/cli`}
|
||||
</CodeBlock>
|
||||
|
||||
<Tabs groupId="framework">
|
||||
<TabItem value="vuejs" label="VueJS">
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="kaioken" label="Kaioken" default>
|
||||
|
||||
```bash
|
||||
npm add kaioken --save
|
||||
npm add vite-plugin-kaioken -D --save
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
3) Add the highlighted lines to `src-tauri/tauri.conf.json` in the
|
||||
`tauri.allowlist` section:
|
||||
|
||||
@ -353,6 +473,8 @@ In the same file, look for the `"identifier"` key and replace the value with `co
|
||||
"longDescription": "",
|
||||
```
|
||||
|
||||
<Tabs groupId="framework">
|
||||
<TabItem value="vuejs" label="VueJS">
|
||||
|
||||
4) Download [`App.vue`](pathname:///tauri/App.vue) and replace `src/App.vue`
|
||||
with the downloaded script.
|
||||
@ -361,6 +483,99 @@ In the same file, look for the `"identifier"` key and replace the value with `co
|
||||
curl -o src/App.vue https://docs.sheetjs.com/tauri/App.vue
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="kaioken" label="Kaioken" default>
|
||||
|
||||
4) Wire up Kaioken to the Tauri app:
|
||||
|
||||
- Add the highlighted lines to `vite.config.ts`:
|
||||
|
||||
```ts title="vite.config.ts (add highlighted lines)"
|
||||
import { defineConfig } from "vite";
|
||||
// highlight-next-line
|
||||
import kaioken from "vite-plugin-kaioken"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(async () => ({
|
||||
// highlight-start
|
||||
esbuild: {
|
||||
jsxInject: `import * as kaioken from "kaioken"`,
|
||||
jsx: "transform",
|
||||
jsxFactory: "kaioken.createElement",
|
||||
jsxFragment: "kaioken.fragment",
|
||||
loader: "tsx",
|
||||
include: ["**/*.tsx", "**/*.ts", "**/*.jsx", "**/*.js"],
|
||||
},
|
||||
plugins: [kaioken()],
|
||||
// highlight-end
|
||||
```
|
||||
|
||||
- Add the highlighted line to `tsconfig.json`:
|
||||
|
||||
```js title="tsconfig.json (add highlighted line)"
|
||||
{
|
||||
"compilerOptions": {
|
||||
// highlight-next-line
|
||||
"jsx": "preserve",
|
||||
"target": "ES2020",
|
||||
```
|
||||
|
||||
- Replace `index.html` with the following codeblock:
|
||||
|
||||
```html title="index.html"
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="/src/styles.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>SheetJS x Tauri</title>
|
||||
<script type="module" src="/src/main.ts" defer></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container" class="container"></div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
- Add the following lines to `src/styles.css`:
|
||||
|
||||
```css title="src/styles.css (add to end)"
|
||||
.logo {
|
||||
padding: 0px;
|
||||
height: 64px; width: 64px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.centre { text-align: center; }
|
||||
table.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
```
|
||||
|
||||
- Replace `src/main.ts` with the following codeblock:
|
||||
|
||||
```ts title="src/main.ts"
|
||||
import { mount } from "kaioken";
|
||||
import App from "./App";
|
||||
|
||||
const root = document.getElementById("container");
|
||||
mount(App, root!);
|
||||
```
|
||||
|
||||
- Download [`App.tsx`](pathname:///tauri/App.tsx) and save to `src/App.tsx`:
|
||||
|
||||
```bash
|
||||
curl -o src/App.tsx https://docs.sheetjs.com/tauri/App.tsx
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
5) Build the app with
|
||||
|
||||
```bash
|
||||
|
@ -194,7 +194,7 @@ This demo was tested in the following environments:
|
||||
|:---------------|:-------------|:---------|:---------|:-----------|
|
||||
| macOS 14.4 | `darwin-x64` | `5.0.0` | `5.0.1` | 2024-03-15 |
|
||||
| macOS 14.0 | `darwin-arm` | `4.14.1` | `3.12.0` | 2023-10-18 |
|
||||
| Windows 10 | `win10-x64` | `4.14.1` | `3.12.0` | 2023-12-09 |
|
||||
| Windows 10 | `win10-x64` | `5.1.0` | `5.1.0` | 2024-03-24 |
|
||||
| Windows 11 | `win11-arm` | `4.14.1` | `3.12.0` | 2023-12-01 |
|
||||
| Linux (HoloOS) | `linux-x64` | `5.0.0` | `5.0.1` | 2024-03-21 |
|
||||
| Linux (Debian) | `linux-arm` | `4.14.1` | `3.12.0` | 2023-12-01 |
|
||||
|
@ -46,10 +46,10 @@ This demo was tested in the following environments:
|
||||
|
||||
| OS and Version | Architecture | RN Platform | Date |
|
||||
|:---------------|:-------------|:------------|:-----------|
|
||||
| Windows 10 | `win10-x64` | `v0.72.16` | 2023-10-27 |
|
||||
| Windows 10 | `win10-x64` | `v0.73.11` | 2024-03-24 |
|
||||
| Windows 11 | `win11-x64` | `v0.72.12` | 2023-10-14 |
|
||||
| Windows 11 | `win11-arm` | `v0.72.20` | 2023-12-01 |
|
||||
| MacOS 14.4 | `darwin-x64` | `v0.73.21` | 2024-03-15 |
|
||||
| MacOS 14.4 | `darwin-x64` | `v0.73.22` | 2024-03-24 |
|
||||
| MacOS 14.1.2 | `darwin-arm` | `v0.72.11` | 2023-12-01 |
|
||||
|
||||
:::
|
||||
@ -420,10 +420,10 @@ setup instructions" to find instructions for manual installation.
|
||||
|
||||
### Project Setup
|
||||
|
||||
1) Create a new project using React Native `0.72.7`:
|
||||
1) Create a new project using React Native `0.73.6`:
|
||||
|
||||
```bash
|
||||
npx react-native init SheetJSWin --template react-native@0.72.7
|
||||
npx react-native init SheetJSWin --template react-native@0.73.6
|
||||
cd SheetJSWin
|
||||
```
|
||||
|
||||
@ -527,7 +527,7 @@ curl -Lo windows/SheetJSWin/DocumentPicker.cs https://docs.sheetjs.com/reactnati
|
||||
Search for `ReactPackageProvider.cs` in the file. There will be one instance.
|
||||
Add the highlighted line just before that instance:
|
||||
|
||||
```xml title="windows\SheetJSWin\SheetJSWin.csproj"
|
||||
```xml title="windows\SheetJSWin\SheetJSWin.csproj (add highlighted line)"
|
||||
<!-- highlight-next-line -->
|
||||
<Compile Include="DocumentPicker.cs" />
|
||||
<Compile Include="ReactPackageProvider.cs" />
|
||||
|
@ -101,7 +101,7 @@ This demo was last tested in the following deployments:
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `1.41.3` | 2024-03-15 |
|
||||
| `darwin-arm` | `1.37.2` | 2023-10-18 |
|
||||
| `win10-x64` | `1.37.1` | 2023-10-09 |
|
||||
| `win10-x64` | `1.41.3` | 2024-03-24 |
|
||||
| `win11-x64` | `1.37.2` | 2023-10-14 |
|
||||
| `win11-arm` | `1.38.4` | 2023-12-01 |
|
||||
| `linux-x64` | `1.41.3` | 2024-03-18 |
|
||||
@ -114,7 +114,7 @@ This demo was last tested in the following deployments:
|
||||
1) Download the test file <https://sheetjs.com/pres.numbers>:
|
||||
|
||||
```bash
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
curl -o pres.numbers https://sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
2) Test the script with `deno run`:
|
||||
|
@ -103,7 +103,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `5.8.1` | `18.5.0` | 2024-03-15 |
|
||||
| `darwin-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
| `win10-x64` | `5.8.1` | `18.5.0` | 2023-10-09 |
|
||||
| `win10-x64` | `5.8.1` | `18.5.0` | 2024-03-24 |
|
||||
| `win11-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
| `linux-x64` | `5.8.1` | `18.5.0` | 2024-03-21 |
|
||||
| `linux-arm` | `5.8.1` | `18.5.0` | 2023-12-01 |
|
||||
@ -115,7 +115,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:--------|:----------|:-----------|
|
||||
| `darwin-x64` | `2.4.0` | `21.7.1` | 2024-03-15 |
|
||||
| `darwin-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
|
||||
| `win10-x64` | `2.1.2` | `16.20.2` | 2023-10-09 |
|
||||
| `win10-x64` | `2.4.0` | `16.20.2` | 2024-03-24 |
|
||||
| `linux-x64` | `2.4.0` | `21.7.1` | 2024-03-21 |
|
||||
| `linux-arm` | `2.3.0` | `21.3.0` | 2023-12-01 |
|
||||
|
||||
@ -127,13 +127,13 @@ This demo was tested in the following deployments:
|
||||
0) Download the test file <https://sheetjs.com/pres.numbers>:
|
||||
|
||||
```bash
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
curl -o pres.numbers https://sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
1) Download [`xlsx-cli.js`](pathname:///cli/xlsx-cli.js)
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/cli/xlsx-cli.js
|
||||
curl -o xlsx-cli.js https://docs.sheetjs.com/cli/xlsx-cli.js
|
||||
```
|
||||
|
||||
2) Install the dependencies:
|
||||
@ -279,9 +279,35 @@ npx boxednode@2.4.0 -s xlsx-cli.js -t xlsx-cli.exe -n 16.20.2
|
||||
:::info pass
|
||||
|
||||
The Windows 10 build requires Visual Studio with "Desktop development with C++"
|
||||
workload, Python 3, and NASM[^1].
|
||||
workload, Python 3.11, and NASM[^1].
|
||||
|
||||
The build command should be run in "x64 Native Tools Command Prompt"
|
||||
**The build command must be run in "x64 Native Tools Command Prompt"**
|
||||
|
||||
:::
|
||||
|
||||
:::caution pass
|
||||
|
||||
When the demo was last tested, the build failed:
|
||||
|
||||
```
|
||||
Not an executable Python program
|
||||
Could not find Python.
|
||||
```
|
||||
|
||||
By default, Windows aliases `python` to a Microsoft Store installer. If the
|
||||
official installer was used, the alias should be disabled manually:
|
||||
|
||||
1) Open Start menu and type "app alias". Click "Manage app execution aliases".
|
||||
|
||||
2) Disable the App Installer for all items with `python` in the name.
|
||||
|
||||
Using Python 3.12, the build fails with an error:
|
||||
|
||||
```
|
||||
Please use python3.11 or python3.10 or python3.9 or python3.8 or python3.7 or python3.6.
|
||||
```
|
||||
|
||||
In the most recent test, Python 3.11.8 was installed from the official site.
|
||||
|
||||
:::
|
||||
|
||||
@ -345,7 +371,7 @@ This demo was last tested in the following deployments:
|
||||
|:-------------|:--------------|:---------|:-----------|
|
||||
| `darwin-x64` | `12.3.219.9` | `0.88.0` | 2024-03-15 |
|
||||
| `darwin-arm` | `11.8.172.13` | `0.79.2` | 2023-10-18 |
|
||||
| `win10-x64` | `11.8.172.13` | `0.79.2` | 2023-10-09 |
|
||||
| `win10-x64` | `12.3.219.9` | `0.88.0` | 2024-03-24 |
|
||||
| `win11-x64` | `11.8.172.13` | `0.79.2` | 2023-10-14 |
|
||||
| `linux-x64` | `12.3.219.9` | `0.88.0` | 2024-03-18 |
|
||||
| `linux-arm` | `12.0.267.8` | `0.82.0` | 2023-12-01 |
|
||||
@ -366,9 +392,9 @@ cd sheetjs2csv
|
||||
- [`sheet2csv.rs`](pathname:///cli/sheet2csv.rs)
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/cli/Cargo.toml
|
||||
curl -LO https://docs.sheetjs.com/cli/snapshot.rs
|
||||
curl -LO https://docs.sheetjs.com/cli/sheet2csv.rs
|
||||
curl -o Cargo.toml https://docs.sheetjs.com/cli/Cargo.toml
|
||||
curl -o snapshot.rs https://docs.sheetjs.com/cli/snapshot.rs
|
||||
curl -o sheet2csv.rs https://docs.sheetjs.com/cli/sheet2csv.rs
|
||||
```
|
||||
|
||||
2) Download the SheetJS Standalone script and move to the project directory:
|
||||
@ -378,7 +404,7 @@ curl -LO https://docs.sheetjs.com/cli/sheet2csv.rs
|
||||
</ul>
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
|
||||
curl -o xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Build the V8 snapshot:
|
||||
@ -414,7 +440,7 @@ cargo build --release --bin sheet2csv
|
||||
5) Download the test file <https://sheetjs.com/pres.numbers>:
|
||||
|
||||
```bash
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
curl -o pres.numbers https://sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
6) Test the application:
|
||||
|
@ -132,7 +132,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:--------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | 2024-03-15 |
|
||||
| `darwin-arm` | `2.7.0` | 2023-10-18 |
|
||||
| `win10-x64` | `2.7.0` | 2023-10-27 |
|
||||
| `win10-x64` | `2.7.0` | 2024-03-27 |
|
||||
| `win11-arm` | `2.7.0` | 2023-12-01 |
|
||||
| `linux-x64` | `2.7.0` | 2024-03-21 |
|
||||
| `linux-arm` | `2.7.0` | 2023-12-01 |
|
||||
|
@ -126,7 +126,7 @@ This demo was tested in the following deployments:
|
||||
|:--------------|:-------------|:--------------|:-----------------|:-----------|
|
||||
| `12.4.253` | `darwin-x64` | macOS 14.4 | `clang 15.0.0` | 2024-03-15 |
|
||||
| `12.1.283` | `darwin-arm` | macOS 14.1.2 | `clang 15.0.0` | 2023-12-01 |
|
||||
| `12.0.265` | `win10-x64` | Windows 10 | `CL 19.37.32822` | 2023-10-28 |
|
||||
| `12.5.48` | `win10-x64` | Windows 10 | `CL 19.39.33523` | 2024-03-24 |
|
||||
| `12.5.48` | `linux-x64` | HoloOS 3.5.17 | `gcc 13.1.1` | 2024-03-21 |
|
||||
| `11.8.82` | `linux-arm` | Debian 12 | `gcc 12.2.0` | 2023-12-01 |
|
||||
|
||||
@ -865,7 +865,7 @@ This demo was last tested in the following deployments:
|
||||
|:-------------|:---------|:-----------|
|
||||
| `darwin-x64` | `0.88.0` | 2024-03-15 |
|
||||
| `darwin-arm` | `0.82.0` | 2023-12-01 |
|
||||
| `win10-x64` | `0.81.0` | 2023-11-14 |
|
||||
| `win10-x64` | `0.89.0` | 2024-03-24 |
|
||||
| `linux-x64` | `0.89.0` | 2024-03-21 |
|
||||
| `linux-arm` | `0.82.0` | 2023-12-01 |
|
||||
|
||||
|
@ -96,7 +96,7 @@ This demo was tested in the following deployments:
|
||||
|:-------------|:-----------|:-----------|:-----------|
|
||||
| `darwin-x64` | `e401ed4` | `1.22.1` | 2024-03-15 |
|
||||
| `darwin-arm` | `873a149` | `1.21.3` | 2023-10-18 |
|
||||
| `win10-x64` | `b396bb4` | `1.21.3` | 2023-10-28 |
|
||||
| `win10-x64` | `e401ed4` | `1.22.1` | 2024-03-24 |
|
||||
| `win11-arm` | `b396bb4` | `1.21.1` | 2023-12-01 |
|
||||
| `linux-x64` | `e401ed4` | `1.22.1` | 2024-03-21 |
|
||||
| `linux-arm` | `b396bb4` | `1.21.4` | 2023-12-01 |
|
||||
|
@ -374,7 +374,7 @@ fork, which powers React Native for Windows, does have built-in support[^5]
|
||||
|
||||
| Architecture | Git Commit | Date |
|
||||
|:-------------|:-----------|:-----------|
|
||||
| `win10-x64` | `930456b` | 2023-10-28 |
|
||||
| `win10-x64` | `240573e` | 2024-03-24 |
|
||||
|
||||
The ["Windows Example"](#windows-example) covers `hermes-windows`.
|
||||
|
||||
@ -544,12 +544,15 @@ contents of the first sheet as CSV rows.
|
||||
|
||||
<details><summary><b>Installation Notes</b> (click to show)</summary>
|
||||
|
||||
CMake and Visual Studio with "Desktop development with C++" workload must be
|
||||
installed. In addition, the following Spectre-mitigated libs must be added:
|
||||
The build sequence requires Python, which can be installed from the official
|
||||
Windows installer[^7].
|
||||
|
||||
- MSVC C++ Spectre-mitigated libs (Latest)
|
||||
- C++ ATL for latest build tools with Spectre Mitigations
|
||||
- C++ MFC for latest build tools with Spectre Mitigations
|
||||
Visual Studio with "Desktop development with C++" workload and Cmake must be
|
||||
installed[^8]. In addition, the following Spectre-mitigated libs must be added:
|
||||
|
||||
- MSVC C++ x64/x86 Spectre-mitigated libs (Latest)
|
||||
- C++ ATL for latest build tools with Spectre Mitigations (x86 & x64)
|
||||
- C++ MFC for latest build tools with Spectre Mitigations (x86 & x64)
|
||||
|
||||
The easiest way to install is to select "Individual components" and search for
|
||||
"spectre latest" (no quotation marks). Pick each option for the relevant CPU.
|
||||
@ -604,7 +607,7 @@ cd sheetjs-hermes
|
||||
```bash
|
||||
git clone https://github.com/microsoft/hermes-windows
|
||||
cd hermes-windows
|
||||
git checkout 930456b
|
||||
git checkout 240573e
|
||||
cd ..
|
||||
```
|
||||
|
||||
@ -645,7 +648,7 @@ Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
|
||||
|
||||
:::info pass
|
||||
|
||||
In the most recent test, the command failed when trying to copy `hermes.exe`:
|
||||
In some test runs, the command failed when trying to copy `hermes.exe`:
|
||||
|
||||
```
|
||||
Copy-Item: C:\Users\Me\Documents\hermes-windows\.ado\scripts\cibuild.ps1:331
|
||||
@ -671,7 +674,7 @@ dir -r -Path .\hermes-windows\workspace\build\win32-x64-debug\ -Filter "*.lib" |
|
||||
7) Download [`sheetjs-hermes.cpp`](pathname:///hermes/sheetjs-hermesw.cpp):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/hermes/sheetjs-hermesw.cpp
|
||||
curl -o sheetjs-hermesw.cpp https://docs.sheetjs.com/hermes/sheetjs-hermesw.cpp
|
||||
```
|
||||
|
||||
8) Build the application:
|
||||
@ -695,8 +698,8 @@ the project directory:
|
||||
</ul>
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -LO https://sheetjs.com/pres.numbers`}
|
||||
curl -o xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
|
||||
curl -o pres.numbers https://sheetjs.com/pres.numbers`}
|
||||
</CodeBlock>
|
||||
|
||||
10) Run the application:
|
||||
@ -822,4 +825,6 @@ If successful, the script will print CSV data from the test file.
|
||||
[^3]: See ["Workbook Object"](/docs/csf/book)
|
||||
[^4]: See [`sheet_to_csv` in "Utilities"](/docs/api/utilities/csv#csv-output)
|
||||
[^5]: See [`microsoft/hermes-windows`](https://github.com/microsoft/hermes-windows) on GitHub
|
||||
[^6]: See ["Dependencies" in "Building and Running"](https://hermesengine.dev/docs/building-and-running/#dependencies) in the Hermes Documentation
|
||||
[^6]: See ["Dependencies" in "Building and Running"](https://hermesengine.dev/docs/building-and-running/#dependencies) in the Hermes Documentation
|
||||
[^7]: See ["Download Python"](https://www.python.org/downloads/) in the Python website.
|
||||
[^8]: See [the Visual Studio website](https://visualstudio.microsoft.com/#vs-section) for download links.
|
||||
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
86
docz/static/tauri/App.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import { useEffect, useState } from 'kaioken'
|
||||
import { read, write, utils, version, WorkBook } from 'xlsx';
|
||||
import { DialogFilter, message, open, save } from '@tauri-apps/api/dialog';
|
||||
import { fetch, ResponseType } from '@tauri-apps/api/http';
|
||||
import { readBinaryFile, writeBinaryFile } from '@tauri-apps/api/fs';
|
||||
|
||||
const filters: DialogFilter[] = [
|
||||
{name: "Excel Binary Workbook", extensions: ["xlsb"]},
|
||||
{name: "Excel Workbook", extensions: ["xlsx"]},
|
||||
{name: "Excel 97-2004 Workbook", extensions: ["xls"]},
|
||||
{name: "Excel 2003 XML Spreadsheet", extensions: ["xml"]},
|
||||
{name: "Symbolic Link", extensions: ["slk"]},
|
||||
{name: "Flat OpenDocument Spreadsheet", extensions: ["fods"]},
|
||||
{name: "OpenDocument Spreadsheet", extensions: ["fods"]},
|
||||
// ...
|
||||
];
|
||||
|
||||
export default function SheetJSTauriKaioken() {
|
||||
const [data, setData] = useState<any[][]>([[]])
|
||||
const [origin, setOrigin] = useState("");
|
||||
|
||||
const update = (wb: WorkBook) => {
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
const d = utils.sheet_to_json<any[]>(ws, { header: 1})
|
||||
setData(d);
|
||||
};
|
||||
|
||||
/* Load from File */
|
||||
const openFile = async() => {
|
||||
try {
|
||||
const selected = await open({
|
||||
title: "Open Spreadsheet",
|
||||
multiple: false,
|
||||
directory: false,
|
||||
filters
|
||||
}) as string;
|
||||
const d = await readBinaryFile(selected);
|
||||
const wb = read(d);
|
||||
update(wb);
|
||||
setOrigin(selected);
|
||||
} catch(e) { await message((e as Error).message || (e as string), { title: "Load Error", type: "error"}); }
|
||||
};
|
||||
|
||||
/* Save to File */
|
||||
const saveFile = async() => {
|
||||
try {
|
||||
const selected = await save({
|
||||
title: "Save to Spreadsheet",
|
||||
filters
|
||||
});
|
||||
if(!selected) throw new Error("No file selected");
|
||||
const ws = utils.aoa_to_sheet(data);
|
||||
const wb = utils.book_new();
|
||||
utils.book_append_sheet(wb, ws, "SheetJSTauri");
|
||||
const d = write(wb, {type: "buffer", bookType: selected.slice(selected.lastIndexOf(".") + 1) as any}) as Uint8Array;
|
||||
await writeBinaryFile(selected, d);
|
||||
await message(`File saved to ${selected}`);
|
||||
} catch(e) { await message((e as Error).message || (e as string), { title: "Save Error", type: "error"}); }
|
||||
};
|
||||
|
||||
/* Download from https://sheetjs.com/pres.numbers */
|
||||
useEffect(() => {(async() => {
|
||||
try {
|
||||
setOrigin("https://sheetjs.com/pres.numbers");
|
||||
const response = await fetch<Uint8Array>("https://sheetjs.com/pres.numbers", { method: "GET", responseType: ResponseType.Binary });
|
||||
const wb = read(new Uint8Array(response.data));
|
||||
update(wb);
|
||||
} catch(e) { await message((e as Error).message || (e as string), { title: "Fetch Error", type: "error"}); }
|
||||
})(); }, []);
|
||||
|
||||
return ( <div>
|
||||
<h1><a href="https://sheetjs.com" target="_blank">
|
||||
<img src="https://sheetjs.com/sketch128.png" className="logo" alt="SheetJS" />
|
||||
SheetJS × Tauri {version}</a></h1>
|
||||
|
||||
<div className="centre"><button type="button" onclick={openFile}>Load Data</button> or
|
||||
<button type="button" onclick={saveFile}>Save Data</button></div>
|
||||
<p className="centre"><b className="centre">Data from { origin }</b></p>
|
||||
<table className="center"><tbody>
|
||||
{data.map((row) => <tr>
|
||||
{row.map((cell) => <td>{cell}</td>)}
|
||||
</tr>)}
|
||||
</tbody></table>
|
||||
</div>
|
||||
);
|
||||
}
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 22 KiB |