quick
This commit is contained in:
parent
3e30d569c2
commit
01d7333f44
@ -55,19 +55,19 @@ For existing projects, the easiest approach is to uninstall and reinstall:
|
||||
<TabItem value="npm" label="npm">
|
||||
<pre><code parentName="pre" {...{"className": "language-bash"}}>{`\
|
||||
npm rm --save xlsx
|
||||
npm i --save file:vendor/xlsx-${current}.tgz`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</code></pre>
|
||||
</TabItem>
|
||||
<TabItem value="pnpm" label="pnpm">
|
||||
<pre><code parentName="pre" {...{"className": "language-bash"}}>{`\
|
||||
pnpm rm xlsx
|
||||
pnpm install file:vendor/xlsx-${current}.tgz`}
|
||||
pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</code></pre>
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn" default>
|
||||
<pre><code parentName="pre" {...{"className": "language-bash"}}>{`\
|
||||
yarn remove xlsx
|
||||
yarn add file:vendor/xlsx-${current}.tgz`}
|
||||
yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</code></pre>
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
@ -114,6 +114,39 @@ function exportFile() {
|
||||
</main>
|
||||
```
|
||||
|
||||
<details open><summary><b>How to run the example</b> (click to show)</summary>
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last run on 2023 March 08 using `svelte@3.55.1`. When running
|
||||
`npm create`, the package `create-vite@4.1.0` was installed.
|
||||
|
||||
:::
|
||||
|
||||
1) Run `npm create vite@latest sheetjs-svelte -- --template svelte-ts`.
|
||||
|
||||
2) Install the SheetJS dependency and start the dev server:
|
||||
|
||||
```bash
|
||||
cd sheetjs-svelte
|
||||
npm install
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
|
||||
npm run dev
|
||||
```
|
||||
|
||||
3) Open a web browser and access the displayed URL (`http://localhost:5173`)
|
||||
|
||||
4) Replace `src/App.svelte` with the `src/SheetJSSvelteAoO.svelte` example.
|
||||
|
||||
The page will refresh and show a table with an Export button. Click the button
|
||||
and the page will attempt to download `SheetJSSvelteAoA.xlsx`. There may be a
|
||||
delay since Vite will try to optimize the SheetJS library on the fly.
|
||||
|
||||
5) Build the site with `npm run build`, then test with `npx http-server dist`.
|
||||
Access `http://localhost:8080` with a web browser to test the bundled site.
|
||||
|
||||
</details>
|
||||
|
||||
### HTML
|
||||
|
||||
The main disadvantage of the Array of Objects approach is the specific nature
|
||||
@ -158,3 +191,36 @@ function exportFile() {
|
||||
<!-- highlight-end -->
|
||||
</main>
|
||||
```
|
||||
|
||||
<details open><summary><b>How to run the example</b> (click to show)</summary>
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last run on 2023 March 08 using `svelte@3.55.1`. When running
|
||||
`npm create`, the package `create-vite@4.1.0` was installed.
|
||||
|
||||
:::
|
||||
|
||||
1) Run `npm create vite@latest sheetjs-svelte -- --template svelte-ts`.
|
||||
|
||||
2) Install the SheetJS dependency and start the dev server:
|
||||
|
||||
```bash
|
||||
cd sheetjs-svelte
|
||||
npm install
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
|
||||
npm run dev
|
||||
```
|
||||
|
||||
3) Open a web browser and access the displayed URL (`http://localhost:5173`)
|
||||
|
||||
4) Replace `src/App.svelte` with the `src/SheetJSSvelteHTML.svelte` example.
|
||||
|
||||
The page will refresh and show a table with an Export button. Click the button
|
||||
and the page will attempt to download `SheetJSSvelteHTML.xlsx`. There may be a
|
||||
delay since Vite will try to optimize the SheetJS library on the fly.
|
||||
|
||||
5) Build the site with `npm run build`, then test with `npx http-server dist`.
|
||||
Access `http://localhost:8080` with a web browser to test the bundled site.
|
||||
|
||||
</details>
|
||||
|
@ -29,7 +29,7 @@ features like scrolling may not work as expected.
|
||||
function SheetJSXSpread() {
|
||||
const [url, setUrl] = React.useState("https://sheetjs.com/pres.numbers");
|
||||
const [done, setDone] = React.useState(false);
|
||||
const ref = React.useRef();
|
||||
const ref = React.useRef(); // ref to DIV container
|
||||
const set_url = React.useCallback((evt) => setUrl(evt.target.value));
|
||||
|
||||
return ( <>
|
||||
@ -43,7 +43,7 @@ function SheetJSXSpread() {
|
||||
x_spreadsheet(ref.current).loadData(stox(wb));
|
||||
setDone(true);
|
||||
}}><b>Fetch!</b></button>
|
||||
</>)}
|
||||
</> )}
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
137
docz/docs/03-demos/02-grid/02-cdg.md
Normal file
137
docz/docs/03-demos/02-grid/02-cdg.md
Normal file
@ -0,0 +1,137 @@
|
||||
---
|
||||
title: Canvas Datagrid
|
||||
pagination_prev: demos/frontend/index
|
||||
pagination_next: demos/net/index
|
||||
---
|
||||
|
||||
<head>
|
||||
<script src="https://unpkg.com/canvas-datagrid/dist/canvas-datagrid.js"></script>
|
||||
</head>
|
||||
|
||||
After extensive testing, `canvas-datagrid` stood out as a high-performance grid
|
||||
with a straightforward API.
|
||||
|
||||
[Click here for a live standalone integration demo.](pathname:///cdg/)
|
||||
|
||||
## Live Demo
|
||||
|
||||
:::note
|
||||
|
||||
Due to CSS conflicts between the data grid and the documentation generator,
|
||||
features like scrolling may not work as expected.
|
||||
|
||||
[The linked demo uses a simple HTML page.](pathname:///cdg/)
|
||||
|
||||
:::
|
||||
|
||||
```jsx live
|
||||
function SheetJSCDG() {
|
||||
const [url, setUrl] = React.useState("https://sheetjs.com/pres.numbers");
|
||||
const [done, setDone] = React.useState(false);
|
||||
const ref = React.useRef(); // ref to DIV container
|
||||
const set_url = React.useCallback((evt) => setUrl(evt.target.value));
|
||||
const [cdg, setCdg] = React.useState(null); // reference to grid object
|
||||
|
||||
return ( <>
|
||||
<div height={300} width={300} ref={ref}/>
|
||||
{!done && ( <>
|
||||
<b>URL: </b><input type="text" value={url} onChange={set_url} size="50"/>
|
||||
<br/><button onClick={async() => {
|
||||
/* fetch and parse workbook */
|
||||
const wb = XLSX.read(await (await fetch(url)).arrayBuffer());
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
const data = XLSX.utils.sheet_to_json(ws, { header:1 });
|
||||
|
||||
/* set up grid and load data */
|
||||
if(!cdg) setCdg(canvasDatagrid({ parentNode: ref.current, data }));
|
||||
else cdg.data = data;
|
||||
setDone(true);
|
||||
}}><b>Fetch!</b></button>
|
||||
</> )}
|
||||
</> );
|
||||
}
|
||||
```
|
||||
|
||||
## Integration Details
|
||||
|
||||
#### Obtaining the Library
|
||||
|
||||
The `canvas-datagrid` NodeJS packages include a minified script that can be
|
||||
directly inserted as a script tag. The unpkg CDN also serves this script:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/canvas-datagrid/dist/canvas-datagrid.js"></script>
|
||||
```
|
||||
|
||||
#### Previewing Data
|
||||
|
||||
The HTML document needs a container element:
|
||||
|
||||
```html
|
||||
<div id="gridctr"></div>
|
||||
```
|
||||
|
||||
Grid initialization is a one-liner:
|
||||
|
||||
```js
|
||||
var grid = canvasDatagrid({
|
||||
parentNode: document.getElementById('gridctr'),
|
||||
data: []
|
||||
});
|
||||
```
|
||||
|
||||
For large data sets, it's necessary to constrain the size of the grid.
|
||||
|
||||
```js
|
||||
grid.style.height = '100%';
|
||||
grid.style.width = '100%';
|
||||
```
|
||||
|
||||
Once the workbook is read and the worksheet is selected, assigning the data
|
||||
variable automatically updates the view:
|
||||
|
||||
```js
|
||||
grid.data = XLSX.utils.sheet_to_json(ws, {header:1});
|
||||
```
|
||||
|
||||
This demo previews the first worksheet.
|
||||
|
||||
#### Editing
|
||||
|
||||
`canvas-datagrid` handles the entire edit cycle. No intervention is necessary.
|
||||
|
||||
#### Saving Data
|
||||
|
||||
`grid.data` is immediately readable and can be converted back to a worksheet.
|
||||
Some versions return an array-like object without the length, so a little bit of
|
||||
preparation may be needed:
|
||||
|
||||
```js
|
||||
/* converts an array of array-like objects into an array of arrays */
|
||||
function prep(arr) {
|
||||
var out = [];
|
||||
for(var i = 0; i < arr.length; ++i) {
|
||||
if(!arr[i]) continue;
|
||||
if(Array.isArray(arr[i])) { out[i] = arr[i]; continue };
|
||||
var o = new Array();
|
||||
Object.keys(arr[i]).forEach(function(k) { o[+k] = arr[i][k] });
|
||||
out[i] = o;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* build worksheet from the grid data */
|
||||
var ws = XLSX.utils.aoa_to_sheet(prep(grid.data));
|
||||
|
||||
/* build up workbook */
|
||||
var wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
|
||||
|
||||
/* generate download */
|
||||
XLSX.writeFile(wb, "SheetJS.xlsx");
|
||||
```
|
||||
|
||||
#### Additional Features
|
||||
|
||||
This demo barely scratches the surface. The underlying grid component includes
|
||||
many additional features that work with [SheetJS Pro](https://sheetjs.com/pro).
|
@ -34,101 +34,16 @@ With a familiar UI, `x-spreadsheet` is an excellent choice for a modern editor.
|
||||
|
||||
[Click here for a live integration demo.](pathname:///xspreadsheet/)
|
||||
|
||||
[The exposition has been moved to a separate page.](/docs/demos/grid/xs)
|
||||
**[The exposition has been moved to a separate page.](/docs/demos/grid/xs)**
|
||||
|
||||
### Canvas DataGrid
|
||||
### Canvas Datagrid
|
||||
|
||||
After extensive testing, [`canvas-datagrid`](https://canvas-datagrid.js.org/demo.html)
|
||||
stood out as a very high-performance grid with an incredibly simple API.
|
||||
After extensive testing, `canvas-datagrid` stood out as a high-performance grid
|
||||
with a straightforward API.
|
||||
|
||||
[Click here for a live integration demo.](pathname:///cdg/index.html)
|
||||
|
||||
<details><summary><b>Full Exposition</b> (click to show)</summary>
|
||||
|
||||
**Obtaining the Library**
|
||||
|
||||
The `canvas-datagrid` NodeJS packages include a minified script that can be
|
||||
directly inserted as a script tag. The unpkg CDN also serves this script:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/canvas-datagrid/dist/canvas-datagrid.js"></script>
|
||||
```
|
||||
|
||||
**Previewing Data**
|
||||
|
||||
The HTML document needs a container element:
|
||||
|
||||
```html
|
||||
<div id="gridctr"></div>
|
||||
```
|
||||
|
||||
Grid initialization is a one-liner:
|
||||
|
||||
```js
|
||||
var grid = canvasDatagrid({
|
||||
parentNode: document.getElementById('gridctr'),
|
||||
data: []
|
||||
});
|
||||
```
|
||||
|
||||
For large data sets, it's necessary to constrain the size of the grid.
|
||||
|
||||
```js
|
||||
grid.style.height = '100%';
|
||||
grid.style.width = '100%';
|
||||
```
|
||||
|
||||
Once the workbook is read and the worksheet is selected, assigning the data
|
||||
variable automatically updates the view:
|
||||
|
||||
```js
|
||||
grid.data = XLSX.utils.sheet_to_json(ws, {header:1});
|
||||
```
|
||||
|
||||
This demo previews the first worksheet.
|
||||
|
||||
**Editing**
|
||||
|
||||
`canvas-datagrid` handles the entire edit cycle. No intervention is necessary.
|
||||
|
||||
**Saving Data**
|
||||
|
||||
`grid.data` is immediately readable and can be converted back to a worksheet.
|
||||
Some versions return an array-like object without the length, so a little bit of
|
||||
preparation may be needed:
|
||||
|
||||
```js
|
||||
/* converts an array of array-like objects into an array of arrays */
|
||||
function prep(arr) {
|
||||
var out = [];
|
||||
for(var i = 0; i < arr.length; ++i) {
|
||||
if(!arr[i]) continue;
|
||||
if(Array.isArray(arr[i])) { out[i] = arr[i]; continue };
|
||||
var o = new Array();
|
||||
Object.keys(arr[i]).forEach(function(k) { o[+k] = arr[i][k] });
|
||||
out[i] = o;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* build worksheet from the grid data */
|
||||
var ws = XLSX.utils.aoa_to_sheet(prep(grid.data));
|
||||
|
||||
/* build up workbook */
|
||||
var wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, 'SheetJS');
|
||||
|
||||
/* generate download */
|
||||
XLSX.writeFile(wb, "SheetJS.xlsx");
|
||||
```
|
||||
|
||||
**Additional Features**
|
||||
|
||||
This demo barely scratches the surface. The underlying grid component includes
|
||||
many additional features including massive data streaming, sorting and styling.
|
||||
|
||||
</details>
|
||||
|
||||
**[The exposition has been moved to a separate page.](/docs/demos/grid/cdg)**
|
||||
|
||||
### Tabulator
|
||||
|
||||
|
@ -13,6 +13,15 @@ work as-is in WebSQL.
|
||||
|
||||
The public demo <https://sheetjs.com/sql> generates a database from workbook.
|
||||
|
||||
:::caution
|
||||
|
||||
WebSQL is only supported in Chromium-based browsers including Chrome.
|
||||
|
||||
Safari historically supported WebSQL but Safari 13 dropped support. Legacy
|
||||
browsers including Internet Explorer and Firefox never added support.
|
||||
|
||||
:::
|
||||
|
||||
## WebSQL Details
|
||||
|
||||
Importing data from spreadsheets is straightforward using the `generate_sql`
|
||||
|
211
docz/docs/03-demos/12-engines/08_quickjs.md
Normal file
211
docz/docs/03-demos/12-engines/08_quickjs.md
Normal file
@ -0,0 +1,211 @@
|
||||
---
|
||||
title: C + QuickJS
|
||||
pagination_prev: demos/bigdata/index
|
||||
pagination_next: solutions/input
|
||||
---
|
||||
|
||||
QuickJS is an embeddable JS engine written in C. It provides a separate set of
|
||||
functions for interacting with the filesystem and the global object. It can run
|
||||
the standalone browser scripts.
|
||||
|
||||
## Integration Details
|
||||
|
||||
_Initialize QuickJS_
|
||||
|
||||
QuickJS provides a `global` object through `JS_GetGlobalObject`:
|
||||
|
||||
```c
|
||||
/* initialize */
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
|
||||
/* obtain reference to global object */
|
||||
JSValue global = JS_GetGlobalObject(ctx);
|
||||
|
||||
/* DO WORK HERE */
|
||||
|
||||
/* free after use */
|
||||
JS_FreeValue(ctx, global);
|
||||
|
||||
/* cleanup */
|
||||
JS_FreeContext(ctx);
|
||||
JS_FreeRuntime(rt);
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
All values must be freed with `JS_FreeValue` before calling `JS_FreeContext`!
|
||||
|
||||
`JS_IsException` should be used for validation.
|
||||
|
||||
Cleanup and validation code is omitted from the discussion. The integration
|
||||
example shows structured validation and controlled memory usage.
|
||||
|
||||
:::
|
||||
|
||||
_Load SheetJS Scripts_
|
||||
|
||||
The main library can be loaded by reading the script from the file system and
|
||||
evaluating in the QuickJS context:
|
||||
|
||||
```c
|
||||
static char *read_file(const char *filename, size_t *sz) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if(!f) return NULL;
|
||||
long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fsee (f, 0, SEEK_SET); }
|
||||
char *buf = (char *)malloc(fsize * sizeof(char));
|
||||
*sz = fread((void *) buf, 1, fsize, f);
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
// ...
|
||||
/* load library */
|
||||
{
|
||||
size_t len; char *buf = read_file("xlsx.full.min.js", &len);
|
||||
JS_Eval(ctx, buf, len, "<input>", 0);
|
||||
free(buf);
|
||||
}
|
||||
```
|
||||
|
||||
To confirm the library is loaded, `XLSX.version` can be inspected:
|
||||
|
||||
```c
|
||||
/* obtain reference to the XLSX object */
|
||||
JSValue XLSX = JS_GetPropertyStr(ctx, global, "XLSX");
|
||||
|
||||
/* print version */
|
||||
JSValue version = JS_GetPropertyStr(ctx, XLSX, "version");
|
||||
size_t vlen; const char *vers = JS_ToCStringLen(ctx, &vlen, version);
|
||||
printf("Version: %s\n", vers);
|
||||
```
|
||||
|
||||
### Reading Files
|
||||
|
||||
`JS_NewArrayBuffer` can generate an `ArrayBuffer` from a C byte array. The
|
||||
function signature expects `uint8_t *` instead of `char *`:
|
||||
|
||||
```c
|
||||
/* read file */
|
||||
size_t dlen; uint8_t * dbuf = (uint8_t *)read_file("pres.numbers", &dlen);
|
||||
|
||||
/* load data into array buffer */
|
||||
JSValue ab = JS_NewArrayBuffer(ctx, dbuf, dlen, NULL, NULL, 0);
|
||||
|
||||
/* obtain reference to the XLSX object */
|
||||
JSValue XLSX = JS_GetPropertyStr(ctx, global, "XLSX");
|
||||
|
||||
/* call XLSX.read(ab) */
|
||||
JSValue XLSX_read = JS_GetPropertyStr(ctx, XLSX, "read");
|
||||
JSValue args[] = { ab };
|
||||
JSValue wb = JS_Call(ctx, XLSX_read, XLSX, 1, args);
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
The "Integration Example" covers a traditional integration in a C application,
|
||||
while the "CLI Test" demonstrates other concepts using the `quickjs` CLI tool.
|
||||
|
||||
### Integration Example
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on 2023 March 11 against QuickJS commit `2788d71` on
|
||||
a Intel Mac. `gcc -v` printed:
|
||||
|
||||
```
|
||||
Apple clang version 14.0.0 (clang-1400.0.29.202)
|
||||
Target: x86_64-apple-darwin21.6.0
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
0) Build `libquickjs.a`:
|
||||
|
||||
```bash
|
||||
git clone --depth=1 https://github.com/bellard/quickjs
|
||||
cd quickjs
|
||||
git checkout 2788d71
|
||||
make
|
||||
cd ..
|
||||
```
|
||||
|
||||
1) Copy `libquickjs.a` and `quickjs.h` into the working directory:
|
||||
|
||||
```bash
|
||||
cp quickjs/libquickjs.a .
|
||||
cp quickjs/quickjs.h .
|
||||
```
|
||||
|
||||
2) Download [`sheetjs.quick.c`](pathname:///quickjs/sheetjs.quick.c):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/quickjs/sheetjs.quick.c
|
||||
```
|
||||
|
||||
3) Build the sample application:
|
||||
|
||||
```bash
|
||||
gcc -o sheetjs.quick -Wall -lm libquickjs.a sheetjs.quick.c
|
||||
```
|
||||
|
||||
This program tries to parse the file specified by the first argument
|
||||
|
||||
4) Download the standalone script and test file:
|
||||
|
||||
<ul>
|
||||
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
|
||||
<li><a href="https://sheetjs.com/pres.numbers">pres.numbers</a></li>
|
||||
</ul>
|
||||
|
||||
```bash
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
5) Run the test program:
|
||||
|
||||
```
|
||||
./sheetjs.quick pres.numbers
|
||||
```
|
||||
|
||||
If successful, the program will print the library version number, file size,
|
||||
first worksheet name, and the contents of the first sheet as CSV rows.
|
||||
|
||||
|
||||
### CLI Test
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on 2023 March 11 against QuickJS `2021-03-27`.
|
||||
|
||||
:::
|
||||
|
||||
0) Ensure `quickjs` command line utility is installed
|
||||
|
||||
1) Download the standalone script and the test file:
|
||||
|
||||
<ul>
|
||||
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
|
||||
<li><a href="https://sheetjs.com/pres.numbers">pres.numbers</a></li>
|
||||
</ul>
|
||||
|
||||
```bash
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
```
|
||||
|
||||
2) Download [`SheetJSQuick.js`](pathname:///quickjs/SheetJSQuick.js)
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/quickjs/SheetJSQuick.js
|
||||
```
|
||||
|
||||
3) Test the program:
|
||||
|
||||
```bash
|
||||
quickjs SheetJSQuick.js
|
||||
```
|
||||
|
||||
If successful, the script will generate `SheetJSQuick.xlsx`.
|
||||
|
@ -246,57 +246,7 @@ QuickJS is an embeddable JS engine written in C. It provides a separate set of
|
||||
functions for interacting with the filesystem and the global object. It can run
|
||||
the standalone browser scripts.
|
||||
|
||||
<details><summary><b>Complete Example</b> (click to show)</summary>
|
||||
|
||||
0) Ensure `quickjs` command line utility is installed
|
||||
|
||||
1) Download the standalone script, the shim and the test file:
|
||||
|
||||
<ul>
|
||||
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
|
||||
<li><a href={`https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js`}>shim.min.js</a></li>
|
||||
<li><a href="https://sheetjs.com/pres.numbers">pres.numbers</a></li>
|
||||
</ul>
|
||||
|
||||
2) Save the following script to `SheetJSQuick.js`:
|
||||
|
||||
```js title="SheetJSQuick.js"
|
||||
/* sheetjs (C) 2013-present SheetJS -- https://sheetjs.com */
|
||||
/* load XLSX */
|
||||
import * as std from "std";
|
||||
globalThis.global = globalThis;
|
||||
std.loadScript("xlsx.full.min.js");
|
||||
|
||||
/* read contents of file */
|
||||
var rh = std.open("pres.numbers", "rb");
|
||||
rh.seek(0, std.SEEK_END);
|
||||
var sz = rh.tell();
|
||||
var ab = new ArrayBuffer(sz);
|
||||
rh.seek();
|
||||
rh.read(ab, 0, sz);
|
||||
rh.close();
|
||||
|
||||
/* parse file */
|
||||
var wb = XLSX.read(ab);
|
||||
|
||||
/* write XLSX */
|
||||
var out = XLSX.write(wb, {bookType: "xlsx", type: "array"});
|
||||
|
||||
/* write contents to file */
|
||||
var wh = std.open("SheetJSQuick.xlsx", "wb");
|
||||
wh.write(out, 0, out.byteLength);
|
||||
wh.close();
|
||||
```
|
||||
|
||||
3) Test the program:
|
||||
|
||||
```bash
|
||||
quickjs SheetJSQuick.js
|
||||
```
|
||||
|
||||
If successful, the script will generate `SheetJSQuick.xlsx`.
|
||||
|
||||
</details>
|
||||
This demo has been moved [to a dedicated page](/docs/demos/engines/quickjs).
|
||||
|
||||
|
||||
### Rhino
|
||||
|
@ -32,7 +32,7 @@ run in the web browser, demos will include interactive examples.
|
||||
|
||||
### Front-End UI Components
|
||||
|
||||
- [`canvas-datagrid`](/docs/demos/grid#canvas-datagrid)
|
||||
- [`canvas-datagrid`](/docs/demos/grid/cdg)
|
||||
- [`x-spreadsheet`](/docs/demos/grid/xs)
|
||||
- [`react-data-grid`](/docs/demos/grid#react-data-grid)
|
||||
- [`glide-data-grid`](/docs/demos/grid#glide-data-grid)
|
||||
|
@ -737,9 +737,8 @@ function Tabeller(props) {
|
||||
/* fetch and update the workbook with an effect */
|
||||
React.useEffect(() => { (async() => {
|
||||
/* fetch and parse workbook -- see the fetch example for details */
|
||||
const wb = XLSX.read(await (await fetch("sheetjs.xlsx")).arrayBuffer());
|
||||
setWorkbook(wb);
|
||||
})(); });
|
||||
setWorkbook(XLSX.read(await (await fetch("sheetjs.xlsx")).arrayBuffer()));
|
||||
})(); }, []);
|
||||
|
||||
return workbook.SheetNames.map(name => ( <>
|
||||
<h3>name</h3>
|
||||
|
25
docz/static/quickjs/SheetJSQuick.js
Normal file
25
docz/static/quickjs/SheetJSQuick.js
Normal file
@ -0,0 +1,25 @@
|
||||
/* sheetjs (C) 2013-present SheetJS -- https://sheetjs.com */
|
||||
/* load XLSX */
|
||||
import * as std from "std";
|
||||
globalThis.global = globalThis;
|
||||
std.loadScript("xlsx.full.min.js");
|
||||
|
||||
/* read contents of file */
|
||||
var rh = std.open("pres.numbers", "rb");
|
||||
rh.seek(0, std.SEEK_END);
|
||||
var sz = rh.tell();
|
||||
var ab = new ArrayBuffer(sz);
|
||||
rh.seek();
|
||||
rh.read(ab, 0, sz);
|
||||
rh.close();
|
||||
|
||||
/* parse file */
|
||||
var wb = XLSX.read(ab);
|
||||
|
||||
/* write XLSX */
|
||||
var out = XLSX.write(wb, {bookType: "xlsx", type: "array"});
|
||||
|
||||
/* write contents to file */
|
||||
var wh = std.open("SheetJSQuick.xlsx", "wb");
|
||||
wh.write(out, 0, out.byteLength);
|
||||
wh.close();
|
120
docz/static/quickjs/sheetjs.quick.c
Normal file
120
docz/static/quickjs/sheetjs.quick.c
Normal file
@ -0,0 +1,120 @@
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "quickjs.h"
|
||||
|
||||
static char *read_file(const char *filename, size_t *sz) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if(!f) return NULL;
|
||||
long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); }
|
||||
char *buf = (char *)malloc(fsize * sizeof(char));
|
||||
*sz = fread((void *) buf, 1, fsize, f);
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
#define CLEANUP(v) { JS_FreeContext(ctx); JS_FreeRuntime(rt); return v; }
|
||||
#define FREE(v) JS_FreeValue(ctx, v);
|
||||
#define VALIDATE(v) { if(JS_IsException(v)) CLEANUP(1) }
|
||||
#define VALINIT(xx,vv) \
|
||||
JSValue xx = vv;\
|
||||
VALIDATE(xx)
|
||||
#define VALPROP(xx,vv,pp) VALINIT(xx, JS_GetPropertyStr(ctx, vv, pp))
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
JSRuntime *rt = JS_NewRuntime();
|
||||
JSContext *ctx = JS_NewContext(rt);
|
||||
|
||||
/* load library */
|
||||
{
|
||||
size_t len; char * buf = read_file("xlsx.full.min.js", &len);
|
||||
VALIDATE(JS_Eval(ctx, buf, len, "<input>", 0))
|
||||
free(buf);
|
||||
}
|
||||
|
||||
VALINIT(global, JS_GetGlobalObject(ctx))
|
||||
VALPROP(XLSX, global, "XLSX");
|
||||
FREE(global)
|
||||
|
||||
/* print version */
|
||||
{
|
||||
VALPROP(version, XLSX, "version")
|
||||
size_t vlen; const char *vers = JS_ToCStringLen(ctx, &vlen, version);
|
||||
printf("Version: %s\n", vers);
|
||||
FREE(version)
|
||||
}
|
||||
|
||||
/* parse workbook */
|
||||
JSValue wb;
|
||||
{
|
||||
/* read file */
|
||||
size_t dlen; uint8_t * dbuf = (uint8_t *)read_file(argv[1], &dlen);
|
||||
|
||||
/* load data into array buffer */
|
||||
JSValue ab = JS_NewArrayBuffer(ctx, dbuf, dlen, NULL, NULL, 0);
|
||||
{
|
||||
VALPROP(byteLen, ab, "byteLength")
|
||||
uint32_t byteLength; JS_ToUint32(ctx, &byteLength, byteLen);
|
||||
FREE(byteLen)
|
||||
printf("Size: %d\n", byteLength);
|
||||
}
|
||||
|
||||
/* call XLSX.read(ab) */
|
||||
{
|
||||
VALPROP(XLSX_read, XLSX, "read");
|
||||
JSValue args[] = { ab };
|
||||
wb = JS_Call(ctx, XLSX_read, XLSX, 1, args);
|
||||
FREE(XLSX_read)
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
FREE(ab)
|
||||
free(dbuf);
|
||||
}
|
||||
|
||||
/* print CSV of first worksheet */
|
||||
{
|
||||
/* get first worksheet */
|
||||
JSValue ws;
|
||||
{
|
||||
/* get name of first sheet */
|
||||
const char *wsname;
|
||||
{
|
||||
JSValue SheetNames = JS_GetPropertyStr(ctx, wb, "SheetNames");
|
||||
JSValue Sheet1 = JS_GetPropertyStr(ctx, SheetNames, "0");
|
||||
size_t wslen; wsname = JS_ToCStringLen(ctx, &wslen, Sheet1);
|
||||
FREE(Sheet1)
|
||||
FREE(SheetNames)
|
||||
}
|
||||
printf("Worksheet Name: %s\n", wsname);
|
||||
|
||||
/* get worksheet object */
|
||||
{
|
||||
VALPROP(Sheets, wb, "Sheets");
|
||||
ws = JS_GetPropertyStr(ctx, Sheets, wsname);
|
||||
FREE(Sheets)
|
||||
}
|
||||
}
|
||||
|
||||
/* print CSV */
|
||||
{
|
||||
VALPROP(utils, XLSX, "utils")
|
||||
VALPROP(sheet_to_csv, utils, "sheet_to_csv")
|
||||
JSValue args[] = { ws };
|
||||
JSValue csv = JS_Call(ctx, sheet_to_csv, utils, 1, args);
|
||||
FREE(sheet_to_csv)
|
||||
FREE(utils)
|
||||
size_t csvlen; const char *csvstr = JS_ToCStringLen(ctx, &csvlen, csv);
|
||||
printf("%s\n", csvstr);
|
||||
FREE(csv)
|
||||
}
|
||||
|
||||
FREE(ws)
|
||||
}
|
||||
|
||||
FREE(wb)
|
||||
FREE(XLSX)
|
||||
CLEANUP(0)
|
||||
}
|
Loading…
Reference in New Issue
Block a user