standalone
This commit is contained in:
parent
4c191dcc59
commit
584af134db
@ -28,14 +28,13 @@ new versions are released!
|
||||
|
||||
:::
|
||||
|
||||
:::warning
|
||||
:::warning pass
|
||||
|
||||
A number of services host older versions of the SheetJS libraries. Due to
|
||||
syncing issues, they are generally out of date.
|
||||
|
||||
They are known CDN bugs.
|
||||
|
||||
<https://cdn.sheetjs.com/> is the authoritative source for SheetJS modules.
|
||||
**The SheetJS CDN** <https://cdn.sheetjs.com/> **is the authoritative source**
|
||||
**for SheetJS scripts**
|
||||
|
||||
:::
|
||||
|
||||
@ -67,6 +66,23 @@ scratch, a single script tag should be added at the top of the HTML page:
|
||||
|
||||
</details>
|
||||
|
||||
### Vendoring
|
||||
|
||||
For general stability, "vendoring" scripts is the recommended approach:
|
||||
|
||||
<p>1) Download the script (<code parentName="pre">xlsx.full.min.js</code>) for
|
||||
the desired version. The current version is available at <a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>https://cdn.sheetjs.com/xlsx-{current}/package/dist/xlsx.full.min.js</a></p>
|
||||
|
||||
2) Move the script to a `public` folder with other scripts.
|
||||
|
||||
3) Reference the local script from HTML pages:
|
||||
|
||||
```html
|
||||
<script src="/public/xlsx.full.min.js"></script>
|
||||
```
|
||||
|
||||
This script assigns to `window.XLSX`. The global can be used in other scripts.
|
||||
|
||||
### Internet Explorer and Older Browsers
|
||||
|
||||
For broad compatibility with JavaScript engines, the library is written using
|
||||
@ -104,11 +120,11 @@ importScripts("https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.mi
|
||||
|
||||
## ECMAScript Module Imports
|
||||
|
||||
:::caution
|
||||
:::caution pass
|
||||
|
||||
This section refers to imports using `script type="module"`. For imports in
|
||||
modern projects using Webpack or React or Angular or VueJS, the installation is
|
||||
described [in the next section](/docs/getting-started/installation/frameworks).
|
||||
described [in "Frameworks and Bundlers"](/docs/getting-started/installation/frameworks).
|
||||
|
||||
:::
|
||||
|
||||
@ -132,15 +148,19 @@ set_cptable(cptable);
|
||||
</script>`}
|
||||
</CodeBlock>
|
||||
|
||||
Dynamic imports with `import()` can be used in data export scenarios. This
|
||||
example will download the library only when the export button is pressed:
|
||||
Web Worker support is noted in [the "Web Workers" demo](/docs/demos/bigdata/worker#installation)
|
||||
|
||||
### Dynamic Imports
|
||||
|
||||
Dynamic imports with `import()` will only download the SheetJS scripts when they
|
||||
are used. This example will download the library when data is exported:
|
||||
|
||||
<CodeBlock language="html">{`\
|
||||
<button id="xport">Export</button>
|
||||
<script type="module">
|
||||
xport.addEventListener("click", async() => {
|
||||
\n\
|
||||
/* dynamically import the library in the event listener */
|
||||
/* dynamically import the script in the event listener */
|
||||
// highlight-next-line
|
||||
const XLSX = await import("https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs");
|
||||
\n\
|
||||
@ -152,11 +172,38 @@ xport.addEventListener("click", async() => {
|
||||
</script>`}
|
||||
</CodeBlock>
|
||||
|
||||
Web Worker support is noted in [the demo](/docs/demos/bigdata/worker#installation)
|
||||
:::caution pass
|
||||
|
||||
The callback functions must be marked as `async` and the script block must have
|
||||
the attribute `type="module"`
|
||||
|
||||
:::
|
||||
|
||||
If Encoding support is required, `cpexcel.full.mjs` must be manually imported:
|
||||
|
||||
<CodeBlock language="html">{`\
|
||||
<button id="xport">Export</button>
|
||||
<script type="module">
|
||||
xport.addEventListener("click", async() => {
|
||||
\n\
|
||||
/* dynamically import the scripts in the event listener */
|
||||
// highlight-start
|
||||
const XLSX = await import("https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs");
|
||||
const cptable = await import("https://cdn.sheetjs.com/xlsx-${current}/package/dist/cpexcel.full.mjs");
|
||||
XLSX.set_cptable(cptable);
|
||||
// highlight-end
|
||||
\n\
|
||||
const wb = XLSX.utils.book_new();
|
||||
const ws = XLSX.utils.aoa_to_sheet([["a","b","c"],[1,2,3]]);
|
||||
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
XLSX.writeFile(wb, "SheetJSESMTest.xlsx");
|
||||
});
|
||||
</script>`}
|
||||
</CodeBlock>
|
||||
|
||||
## Bower
|
||||
|
||||
:::caution
|
||||
:::warning pass
|
||||
|
||||
Bower is deprecated and the maintainers recommend using other tools.
|
||||
|
||||
|
@ -51,7 +51,7 @@ This demo was tested in the following environments:
|
||||
| Windows 10 | x64 | `v0.71.25` | 2023-07-24 |
|
||||
| Windows 11 | x64 | `v0.71.11` | 2023-05-11 |
|
||||
| MacOS 12.6 | x64 | `v0.71.26` | 2023-07-23 |
|
||||
| MacOS 13.4 | arm | `v0.71.18` | 2023-07-06 |
|
||||
| MacOS 13.4 | ARM | `v0.71.18` | 2023-07-06 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Redis
|
||||
title: Redis Databases Wrapped in Sheets
|
||||
sidebar_label: Redis
|
||||
description: Store complex datasets in Redis. Seamlessly save data to spreadsheets and read data from sheets using SheetJS. Enable Excel spreadsheet experts to update content.
|
||||
pagination_prev: demos/desktop/index
|
||||
pagination_next: demos/local/index
|
||||
sidebar_custom_props:
|
||||
@ -9,6 +11,18 @@ sidebar_custom_props:
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
[Redis](https://redis.io/) is a open source in-memory data store. It is capable
|
||||
of storing sets, lists and other simple data structures.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
This demo defines a schema for storing Redis databases in spreadsheets. We'll
|
||||
explore how to use SheetJS and Redis NodeJS connector modules to pull data
|
||||
from XLSX files to a Redis database and to serialize a database to a workbook.
|
||||
|
||||
#### Overview
|
||||
|
||||
Redis has 5 core data types: "String", List", "Set", "Sorted Set", and "Hash".
|
||||
Since the keys and values are limited to simple strings (and numbers), it is
|
||||
possible to store complete databases in a single worksheet.
|
||||
@ -17,7 +31,7 @@ possible to store complete databases in a single worksheet.
|
||||
|
||||
## Integration Details
|
||||
|
||||
:::note
|
||||
:::note pass
|
||||
|
||||
[`SheetJSRedis.mjs`](pathname:///nosql/SheetJSRedis.mjs) exports the methods:
|
||||
- `redis_to_ws` creates a SheetJS worksheet by querying a redis client
|
||||
@ -25,11 +39,32 @@ possible to store complete databases in a single worksheet.
|
||||
|
||||
:::
|
||||
|
||||
The first row holds the data type and the second row holds the property name.
|
||||
### Array of Arrays
|
||||
|
||||
The "Exporting Data" snippets generate arrays of arrays that can be added to a
|
||||
worksheet using `sheet_add_aoa`. Since the data is column-oriented, the goal is
|
||||
to add the data starting in the first row of the column after the data:
|
||||
The shared data representation is an "array of arrays"[^1]. Each array within
|
||||
the structure corresponds to one row.
|
||||
|
||||
The Redis to SheetJS converter generates an array of arrays of the data by
|
||||
running queries to fetch data from the database. The SheetJS `aoa_to_sheet` and
|
||||
`sheet_add_aoa`[^2] methods build up worksheets from arrays of arrays. Once the
|
||||
worksheet is created, it can be added to a SheetJS workbook object[^3] and
|
||||
exported using `writeFile`[^4].
|
||||
|
||||
The SheetJS to Redis converter works in reverse. Workbook files are parsed with
|
||||
the SheetJS `readFile` method[^5] and the desired worksheet is pulled from the
|
||||
workbook object. An array of arrays can be created with the `sheet_to_json`[^6]
|
||||
utility function. The data structure can be scanned to generate Redis queries.
|
||||
|
||||
### Appending Columns
|
||||
|
||||
Since the data is column-oriented, the goal is to add the data starting on the
|
||||
first row of the column after the data.
|
||||
|
||||
To calculate the starting point for writing data, SheetJS provides `encode_cell`
|
||||
and `decode_range` utility functions for working with addresses and ranges[^7].
|
||||
|
||||
The following snippet takes an array of arrays of values and writes the values
|
||||
to a worksheet starting from the column after the worksheet range:
|
||||
|
||||
```js
|
||||
function add_aoa_to_next_column(worksheet, aoa) {
|
||||
@ -45,14 +80,7 @@ function add_aoa_to_next_column(worksheet, aoa) {
|
||||
}
|
||||
```
|
||||
|
||||
The "Importing Data" snippets generate redis queries. The `ws_to_redis` function
|
||||
first generates an array of arrays with `sheet_to_json`:
|
||||
|
||||
```js
|
||||
const aoa = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
|
||||
```
|
||||
|
||||
#### Strings
|
||||
### Strings
|
||||
|
||||
Strings can be stored in a unified String table. The first column holds keys
|
||||
and the second column holds values:
|
||||
@ -67,7 +95,11 @@ XXX| A | B |
|
||||
```
|
||||
|
||||
The SheetJS array-of-arrays representation of the string table is an array of
|
||||
key/value pairs:
|
||||
key/value pairs.
|
||||
|
||||
The pairs can be generated from Redis by querying for all of the keys using the
|
||||
`KEYS`[^8] method, testing if the corresponding value is a string using the
|
||||
`TYPE`[^9] method, and fetching string values using the `GET`[^10] method:
|
||||
|
||||
```js
|
||||
const aoa = ["Strings"]; aoa.length = 2; // [ "Strings", empty ]
|
||||
@ -80,7 +112,7 @@ for(let key of keys) {
|
||||
}
|
||||
```
|
||||
|
||||
#### Lists
|
||||
### Lists
|
||||
|
||||
Lists are unidimensional and can be stored in their own columns.
|
||||
|
||||
@ -94,15 +126,18 @@ XXX| C |
|
||||
```
|
||||
|
||||
The SheetJS array-of-arrays representation of lists is a column of values.
|
||||
`LRANGE` returns a simple array of values. `sheet_add_aoa` interprets the result
|
||||
as one row. The code transposes the result with `values.map(v => [v])`.
|
||||
|
||||
Redis `LRANGE`[^11] returns a simple array of values. `sheet_add_aoa` interprets
|
||||
the result as one row, so the data should be transposed.
|
||||
|
||||
The code transposes the result with `values.map(v => [v])`.
|
||||
|
||||
```js
|
||||
const values = await client.LRANGE(key, 0, -1);
|
||||
const aoa = [ ["List"], [key] ].concat(values.map(v => [v]));
|
||||
```
|
||||
|
||||
#### Sets
|
||||
### Sets
|
||||
|
||||
Sets are unidimensional and can be stored in their own columns.
|
||||
|
||||
@ -116,15 +151,18 @@ XXX| D |
|
||||
```
|
||||
|
||||
The SheetJS array-of-arrays representation of sets is a column of values.
|
||||
`SMEMBERS` returns a simple array of values. `sheet_add_aoa` interprets result
|
||||
as one row. The code transposes the result with `values.map(v => [v])`.
|
||||
|
||||
Redis `SMEMBERS`[^12] returns an array of values. `sheet_add_aoa` interprets the
|
||||
result as one row, so the data should be transposed.
|
||||
|
||||
The code transposes the result with `values.map(v => [v])`.
|
||||
|
||||
```js
|
||||
const values = await client.SMEMBERS(key);
|
||||
const aoa = [ ["Set"], [key] ].concat(values.map(v => [v]));
|
||||
```
|
||||
|
||||
#### Sorted Sets
|
||||
### Sorted Sets
|
||||
|
||||
Sorted Sets have an associated score which can be stored in the second column.
|
||||
|
||||
@ -138,14 +176,15 @@ XXX| E | F |
|
||||
```
|
||||
|
||||
The SheetJS array-of-arrays representation is an array of key/score pairs.
|
||||
`ZRANGE_WITHSCORES` returns an array of objects which can be reshaped.
|
||||
|
||||
`ZRANGE_WITHSCORES`[^13] returns an array of objects which can be reshaped.
|
||||
|
||||
```js
|
||||
const values = await client.ZRANGE_WITHSCORES(key, 0, -1);
|
||||
const aoa = [ ["Sorted"], [key] ].concat(values.map(v => [v.value, v.score]));
|
||||
```
|
||||
|
||||
#### Hashes
|
||||
### Hashes
|
||||
|
||||
Hashes are stored like the string table, with key and value columns in order.
|
||||
|
||||
@ -159,7 +198,8 @@ XXX| G | H |
|
||||
```
|
||||
|
||||
The SheetJS array-of-arrays representation is an array of key/value pairs.
|
||||
`HGETALL` returns a plain object which can be converted using `Object.entries`:
|
||||
|
||||
`HGETALL`[^14] returns an object which can be converted using `Object.entries`:
|
||||
|
||||
```js
|
||||
const values = await client.HGETALL(key);
|
||||
@ -170,8 +210,8 @@ const aoa = [ ["Hash"], [key] ].concat(Object.entries(values));
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on 2023 May 11 with Redis 7.0.11, Redis connector
|
||||
module 4.6.6 and NodeJS 20.1.0.
|
||||
This demo was last tested on 2023 August 22 with Redis 7.2.0, Redis connector
|
||||
module 4.6.7 and NodeJS 20.5.1.
|
||||
|
||||
:::
|
||||
|
||||
@ -187,10 +227,10 @@ this demo also requires NodeJS version 18 or later.
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on Intel macOS. Redis was installed with:
|
||||
This demo was last tested on macOS. Redis was installed with:
|
||||
|
||||
```bash
|
||||
brew install redis@7.0.11
|
||||
brew install redis
|
||||
```
|
||||
|
||||
The following command started the server process:
|
||||
@ -214,7 +254,7 @@ curl -LO https://docs.sheetjs.com/nosql/SheetJSRedisTest.mjs
|
||||
2) Install dependencies:
|
||||
|
||||
<CodeBlock language="bash">{`\
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.6`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.7`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Run the test script:
|
||||
@ -226,3 +266,18 @@ node SheetJSRedisTest.mjs
|
||||
Inspect the output and compare with the data in `SheetJSRedisTest.mjs`.
|
||||
|
||||
Open `SheetJSRedis.xlsx` and verify the columns have the correct data
|
||||
|
||||
[^1]: See ["Array of Arrays" in "Utility Functions"](/docs/api/utilities/array#array-of-arrays)
|
||||
[^2]: See ["Array of Arrays Input" in "Utility Functions"](/docs/api/utilities/array#array-of-arrays-input).
|
||||
[^3]: See ["Workbook Helpers" in "Utility Functions"](/docs/api/utilities/wb)
|
||||
[^4]: See [`writeFile` in "Writing Files"](/docs/api/write-options)
|
||||
[^5]: See [`readFile` in "Reading Files"](/docs/api/parse-options)
|
||||
[^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
|
||||
[^7]: See ["Utilities" in "Addresses and Ranges"](/docs/csf/general#utilities)
|
||||
[^8]: See [`KEYS`](https://redis.io/commands/keys/) in the Redis documentation.
|
||||
[^9]: See [`TYPE`](https://redis.io/commands/type/) in the Redis documentation.
|
||||
[^10]: See [`GET`](https://redis.io/commands/get/) in the Redis documentation.
|
||||
[^11]: See [`LRANGE`](https://redis.io/commands/lrange/) in the Redis documentation.
|
||||
[^12]: See [`SMEMBERS`](https://redis.io/commands/smembers/) in the Redis documentation.
|
||||
[^13]: The official command is [`ZRANGE`](https://redis.io/commands/zrange/). `ZRANGE_WITHSCORES` is a special command supported by the NodeJS wrapper.
|
||||
[^14]: See [`HGETALL`](https://redis.io/commands/hgetall/) in the Redis documentation.
|
||||
|
@ -40,9 +40,9 @@ These instructions were tested on the following platforms:
|
||||
| Platform | Test Date |
|
||||
|:------------------------------|:-----------|
|
||||
| Linux (Steam Deck Holo 3.4.8) | 2023-07-12 |
|
||||
| Linux (Ubuntu 18.04 aarch64) | 2023-04-13 |
|
||||
| Linux (Ubuntu 18.04 AArch64) | 2023-04-13 |
|
||||
| MacOS 10.13 (x64) | 2023-04-04 |
|
||||
| MacOS 13.0 (arm64) | 2023-04-13 |
|
||||
| MacOS 13.0 (ARM64) | 2023-04-13 |
|
||||
| Windows 10 (x64) + WSL Ubuntu | 2023-07-23 |
|
||||
| Windows 11 (x64) + WSL Ubuntu | 2023-04-04 |
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user