forked from sheetjs/docs.sheetjs.com
visibility
This commit is contained in:
parent
f270ad6b3f
commit
481b147e97
@ -336,7 +336,7 @@ case it is easier to post-process the raw data:
|
||||
|
||||
```js
|
||||
let last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
@ -411,6 +411,32 @@ raw_data.forEach(r => {
|
||||
});
|
||||
```
|
||||
|
||||
Observing that `r[0]` must equal `last_value`, the inner statement can be
|
||||
rewritten to compute the final value and assign to both variables:
|
||||
|
||||
```js
|
||||
let last_value = null;
|
||||
raw_data.forEach(r => {
|
||||
last_value = r[0] = (r[0] != null ? r[0] : last_value);
|
||||
});
|
||||
```
|
||||
|
||||
:::caution pass
|
||||
|
||||
It is tempting to take advantage of implicit logical rules:
|
||||
|
||||
```js
|
||||
let last_value = null;
|
||||
raw_data.forEach(r => {
|
||||
last_value = r[0] = (r[0] || last_value);
|
||||
});
|
||||
```
|
||||
|
||||
This is strongly discouraged since the value `0` is false. The explicit `null`
|
||||
test distinguishes `null` and `undefined` from `0`
|
||||
|
||||
:::
|
||||
|
||||
</details>
|
||||
|
||||
After post-processing, the rows now have proper year fields:
|
||||
@ -443,7 +469,7 @@ function SheetJSAoAFilled() {
|
||||
const raw_data = XLSX.utils.sheet_to_json(worksheet, {header:1});
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
|
||||
/* pull Excel rows 13:16 (SheetJS 12:15) */
|
||||
const rows_13_16 = raw_data.slice(12,16);
|
||||
@ -479,7 +505,7 @@ function SheetJSAoAFiltered() {
|
||||
const raw_data = XLSX.utils.sheet_to_json(worksheet, {header:1});
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
/* select data rows */
|
||||
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2023);
|
||||
/* display data */
|
||||
@ -553,7 +579,7 @@ function SheetJSObjects() {
|
||||
const raw_data = XLSX.utils.sheet_to_json(worksheet, {header:1});
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
/* select data rows */
|
||||
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2023);
|
||||
/* generate row objects */
|
||||
@ -660,7 +686,7 @@ function StudentAidTotal() {
|
||||
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
|
||||
/* select data rows */
|
||||
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2023);
|
||||
@ -715,7 +741,7 @@ Save the following script to `SheetJSStandaloneDemo.html`:
|
||||
\n\
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
\n\
|
||||
/* select data rows */
|
||||
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2023);
|
||||
@ -768,7 +794,7 @@ const XLSX = require("xlsx");
|
||||
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
|
||||
/* select data rows */
|
||||
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2023);
|
||||
@ -783,7 +809,6 @@ const XLSX = require("xlsx");
|
||||
console.log(`${o.FY}\t${o.FQ||""}\t${o.total}`);
|
||||
});
|
||||
})();
|
||||
|
||||
```
|
||||
|
||||
After saving the script, run the script:
|
||||
@ -829,7 +854,7 @@ Save the following script to `SheetJSNW.html`:
|
||||
\n\
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
\n\
|
||||
/* select data rows */
|
||||
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2023);
|
||||
@ -923,7 +948,7 @@ const App = () => {
|
||||
|
||||
/* fill years */
|
||||
var last_year = 0;
|
||||
raw_data.forEach(r => (r[0] != null) ? (last_year = r[0]) : (r[0] = last_year));
|
||||
raw_data.forEach(r => last_year = r[0] = (r[0] != null ? r[0] : last_year));
|
||||
|
||||
/* select data rows */
|
||||
const rows = raw_data.filter(r => r[0] >= 2007 && r[0] <= 2023);
|
||||
|
@ -453,7 +453,6 @@ const columns = Array.from({ length: range.e.c + 1 }, (_, i) => ({
|
||||
/* column labels: encode_col translates 0 -> "A", 1 -> "B", 2 -> "C", ... */
|
||||
name: XLSX.utils.encode_col(i)
|
||||
}));
|
||||
|
||||
```
|
||||
|
||||
![Column labels for headers](pathname:///react/cols.png)
|
||||
|
@ -94,7 +94,7 @@ npx browserify xlsxworker.js > worker.js
|
||||
|
||||
4) Spin up a local web server:
|
||||
|
||||
```
|
||||
```bash
|
||||
npx http-server
|
||||
```
|
||||
|
||||
@ -1191,7 +1191,7 @@ This demo was last tested on 2023 May 07 against ViteJS `4.3.5`
|
||||
|
||||
1) Create a new ViteJS project:
|
||||
|
||||
```
|
||||
```bash
|
||||
npm create vite@latest sheetjs-vite -- --template vue-ts
|
||||
cd sheetjs-vite
|
||||
npm i
|
||||
@ -1258,7 +1258,7 @@ writeFileXLSX(workbook, "Presidents.xlsx");
|
||||
5) Run `npx vite build` and verify the generated pages work by running a local
|
||||
web server in the `dist` folder:
|
||||
|
||||
```
|
||||
```bash
|
||||
npx http-server dist/
|
||||
```
|
||||
|
||||
|
@ -265,7 +265,7 @@ Open that script.
|
||||
|
||||
Searching for `Bill Clinton` reveals the following:
|
||||
|
||||
```
|
||||
```js
|
||||
{"Name":"Bill Clinton","Index":42}
|
||||
```
|
||||
|
||||
|
@ -215,7 +215,7 @@ const wb = XLSX.read(ab);
|
||||
|
||||
:::note
|
||||
|
||||
This demo was tested on an Intel Mac on 2023 July 02 with RN `0.72.1`.
|
||||
This demo was tested on an Intel Mac on 2023 August 20 with RN `0.72.4`.
|
||||
|
||||
The iOS simulator runs iOS 16.2 on an iPhone SE (3rd generation).
|
||||
|
||||
@ -226,7 +226,7 @@ The Android simulator runs Android 12.0 (S) API 31 on a Pixel 3.
|
||||
1) Create project:
|
||||
|
||||
```bash
|
||||
npx -y react-native@0.72.1 init SheetJSRNFetch --version="0.72.1"
|
||||
npx -y react-native@0.72.4 init SheetJSRNFetch --version="0.72.4"
|
||||
```
|
||||
|
||||
2) Install shared dependencies:
|
||||
@ -253,9 +253,9 @@ curl -LO https://docs.sheetjs.com/reactnative/App.tsx
|
||||
When the demo was last tested on macOS, `java -version` displayed the following:
|
||||
|
||||
```
|
||||
openjdk version "11.0.19" 2023-04-18 LTS
|
||||
OpenJDK Runtime Environment Zulu11.64+19-CA (build 11.0.19+7-LTS)
|
||||
OpenJDK 64-Bit Server VM Zulu11.64+19-CA (build 11.0.19+7-LTS, mixed mode)
|
||||
openjdk version "11.0.20" 2023-07-18 LTS
|
||||
OpenJDK Runtime Environment Zulu11.66+15-CA (build 11.0.20+8-LTS)
|
||||
OpenJDK 64-Bit Server VM Zulu11.66+15-CA (build 11.0.20+8-LTS, mixed mode)
|
||||
```
|
||||
|
||||
:::
|
||||
@ -296,7 +296,7 @@ tapping "Import data from a spreadsheet", verify that the app shows new data:
|
||||
|
||||
:::warning pass
|
||||
|
||||
iOS testing requires macOS. It does not work on Windows.
|
||||
iOS testing requires macOS. It does not work on Windows or Linux.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -253,7 +253,6 @@ This uses two functions that should be added to the component script:
|
||||
// highlight-end
|
||||
}
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
The app should now show two buttons at the bottom:
|
||||
|
@ -13,8 +13,11 @@ sidebar_custom_props:
|
||||
import current from '/version.js';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
AlaSQL is a pure JavaScript in-memory SQL database. It has built-in support for
|
||||
SheetJS through the `XLSX` target operator.
|
||||
[AlaSQL](https://alasql.org/) is a pure JavaScript in-memory SQL database. It
|
||||
has built-in support for SheetJS through the `XLSX` target operator.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
This demo covers basic concepts pertaining to data import and export. The
|
||||
official documentation includes advanced examples and deployment tips as well as
|
||||
@ -27,7 +30,7 @@ This demo was tested in the following environments:
|
||||
| Environment | AlaSQL | Date |
|
||||
|:--------------------|:-------|:----------:|
|
||||
| NodeJS | 3.1.0 | 2023-07-24 |
|
||||
| Standalone (Chrome) | 3.0.0 | 2023-04-09 |
|
||||
| Standalone (Chrome) | 3.0.0 | 2023-08-20 |
|
||||
|
||||
:::
|
||||
|
||||
|
@ -47,8 +47,8 @@ const ws = utils.json_to_sheet(aoo);
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on 2023 February 23 with MongoDB CE 6.0.4, MongoDB
|
||||
connector module 5.1.0 and NodeJS 18.14.2.
|
||||
This demo was last tested on 2023 August 20 with MongoDB CE 7.0.0, MongoDB
|
||||
connector module 5.7.0 and NodeJS 20.5.1.
|
||||
|
||||
:::
|
||||
|
||||
@ -57,11 +57,11 @@ connector module 5.1.0 and NodeJS 18.14.2.
|
||||
```bash
|
||||
brew tap mongodb/brew
|
||||
brew update
|
||||
brew install mongodb-community@6.0
|
||||
brew install mongodb-community
|
||||
```
|
||||
|
||||
1) Start a MongoDB server on `localhost` (follow official instructions). To run
|
||||
in the foreground on Intel MacOS:
|
||||
1) Start a MongoDB server on `localhost` (follow official instructions).
|
||||
If `brew` was used to install MongoDB, the following command starts a server:
|
||||
|
||||
```bash
|
||||
/usr/local/opt/mongodb-community/bin/mongod --config /usr/local/etc/mongod.conf
|
||||
@ -73,7 +73,7 @@ in the foreground on Intel MacOS:
|
||||
mkdir sheetjs-mongo
|
||||
cd sheetjs-mongo
|
||||
npm init -y
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz mongodb@5.1.0`}
|
||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz mongodb@5.7.0`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Save the following to `SheetJSMongoCRUD.mjs` (the key step is highlighted):
|
||||
|
@ -24,7 +24,7 @@ This demo was verified by NetSuite consultants in the following deployments:
|
||||
|
||||
| `@NScriptType` | `@NApiVersion` | Date |
|
||||
|:----------------|:---------------|:-----------|
|
||||
| ScheduledScript | 2.1 | 2023-03-09 |
|
||||
| ScheduledScript | 2.1 | 2023-08-18 |
|
||||
| Restlet | 2.1 | 2023-04-20 |
|
||||
| Suitelet | 2.1 | 2023-07-21 |
|
||||
| MapReduceScript | 2.1 | 2023-07-31 |
|
||||
|
@ -350,7 +350,6 @@ fn eval_code_ab(scope: &mut v8::HandleScope, code: &str) -> Vec<u8> {
|
||||
result.byte_length()
|
||||
).to_vec(); }
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
:::note
|
||||
|
@ -299,7 +299,7 @@ curl -LO https://sheetjs.com/pres.numbers`}
|
||||
|
||||
6) Run the test program:
|
||||
|
||||
```
|
||||
```bash
|
||||
./sheetjs.ch pres.numbers
|
||||
```
|
||||
|
||||
@ -361,6 +361,6 @@ ready, it will read the bundled test data and print the contents as CSV.
|
||||
|
||||
5) Run the script using the ChakraCore standalone binary:
|
||||
|
||||
```
|
||||
```bash
|
||||
./ch xlsx.chakra.js
|
||||
```
|
||||
|
@ -4,11 +4,18 @@ pagination_next: solutions/input
|
||||
hide_table_of_contents: true
|
||||
---
|
||||
|
||||
# Demo Projects
|
||||
# Demos
|
||||
|
||||
Demos include complete examples and short discussions. For features that can
|
||||
run in the web browser, demos will include interactive examples.
|
||||
|
||||
:::tip pass
|
||||
|
||||
If a demo for a library or framework is not included here, please leave a note
|
||||
in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
|
||||
|
||||
:::
|
||||
|
||||
### JavaScript APIs
|
||||
|
||||
- [`XMLHttpRequest and fetch`](/docs/demos/net/network)
|
||||
@ -66,6 +73,7 @@ run in the web browser, demos will include interactive examples.
|
||||
- [`NextJS`](/docs/demos/static/nextjs)
|
||||
- [`NuxtJS`](/docs/demos/static/nuxtjs)
|
||||
- [`SvelteKit`](/docs/demos/static/svelte)
|
||||
- [`Webpack`](/docs/demos/static/webpack)
|
||||
|
||||
### App Extensions
|
||||
|
||||
@ -129,10 +137,3 @@ run in the web browser, demos will include interactive examples.
|
||||
- [`QuickJS (C)`](/docs/demos/engines/quickjs)
|
||||
- [`ExecJS (Ruby)`](/docs/demos/engines/rb)
|
||||
- [`JavaScript::Engine (Perl)`](/docs/demos/engines/perl)
|
||||
|
||||
|
||||
:::note
|
||||
|
||||
If a demo for a library or framework is not included here, please leave a note.
|
||||
|
||||
:::
|
||||
|
@ -522,7 +522,7 @@ const workbook = XLSX.read(data);`}</CodeBlock>
|
||||
|
||||
Deno must be run with the `--allow-net` flag to enable network requests:
|
||||
|
||||
```
|
||||
```bash
|
||||
deno run --allow-net test-fetch.ts
|
||||
```
|
||||
|
||||
|
@ -88,3 +88,12 @@ discussed in more detail in ["Defined Names"](/docs/csf/features/names)
|
||||
| `CodeName` | [VBA Workbook Name](/docs/csf/features/vba) |
|
||||
| `date1904` | epoch: 0/false for 1900 system, 1/true for 1904 |
|
||||
| `filterPrivacy` | Warn or strip personally identifying info on save |
|
||||
|
||||
### Sheet Metadata
|
||||
|
||||
`wb.Workbook.Sheets` is an array of sheet metadata objects which have the keys:
|
||||
|
||||
| Key | Description |
|
||||
|:----------------|:----------------------------------------------------|
|
||||
| `Hidden` | [Sheet Visibility](/docs/csf/features/visibility) |
|
||||
| `CodeName` | [VBA Sheet Code Name](/docs/csf/features/vba) |
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Dates and Times
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Formulae
|
||||
@ -16,17 +16,17 @@ while the writer will translate from A1-Style strings to the file format.
|
||||
|:------------------|:-----:|:-----:|:-----:|:-------:|:-----------------------|
|
||||
| XLSX / XLSM | ✔ | ✔ | ✔ | ✔ | A1-Style strings |
|
||||
| XLSB | ✔ | | ✔ | ✔ | BIFF parsed tokens |
|
||||
| XLS | ✔ | | ✔ | * | BIFF parsed tokens |
|
||||
| XLML | ✔ | ✔ | ✔ | * | RC-style strings |
|
||||
| SYLK | ✔ | ✔ | | * | A1/RC-style strings |
|
||||
| CSV / TXT | ✔ | ✔ | * | * | A1-Style strings |
|
||||
| ODS / FODS / UOS | ✔ | ✔ | | * | OpenFormula strings |
|
||||
| WK\* | ✔ | | | * | Lotus parsed tokens |
|
||||
| WQ\* / WB\* / QPW | | | | * | Quattro Pro tokens |
|
||||
| NUMBERS | | | | * | Numbers parsed tokens |
|
||||
| XLS | ✔ | | ✔ | ✕ | BIFF parsed tokens |
|
||||
| XLML | ✔ | ✔ | ✔ | ✕ | RC-style strings |
|
||||
| SYLK | ✔ | ✔ | | ✕ | A1/RC-style strings |
|
||||
| CSV / TXT | ✔ | ✔ | ✕ | ✕ | A1-Style strings |
|
||||
| ODS / FODS / UOS | ✔ | ✔ | | ✕ | OpenFormula strings |
|
||||
| WK\* | ✔ | | | ✕ | Lotus parsed tokens |
|
||||
| WQ\* / WB\* / QPW | | | | ✕ | Quattro Pro tokens |
|
||||
| NUMBERS | | | | ✕ | Numbers parsed tokens |
|
||||
|
||||
Asterisks (*) mark features that are not supported by the file formats. There is
|
||||
no way to mark a dynamic array formula in the XLS file format.
|
||||
X (✕) marks features that are not supported by the file formats. There is no way
|
||||
to mark a dynamic array formula in the XLS file format.
|
||||
|
||||
</details>
|
||||
|
||||
@ -163,7 +163,7 @@ function ConcatFormula(props) {
|
||||
};
|
||||
return ( <>
|
||||
<input type="file" onChange={process_file}/><br/>
|
||||
<b>addr: </b><input type="text" value={addr} onChange={setaddr} size="6"/>
|
||||
<b>Cell: </b><input type="text" value={addr} onChange={setaddr} size="6"/>
|
||||
{!ws[addr] ? ( <b>Cell {addr} not found</b> ) : ( <table>
|
||||
<tr><td>Formula</td><td><code>{ws[addr].f}</code></td></tr>
|
||||
<tr><td>Value</td><td><code>{ws[addr].v}</code></td></tr>
|
||||
@ -201,6 +201,8 @@ var worksheet = XLSX.utils.aoa_to_sheet([
|
||||
|
||||
<details open><summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
This demo creates a worksheet where `A1=1`, `A2=2`, and `A3=A1+A2`.
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportSimpleFormula(props) {
|
||||
@ -238,10 +240,13 @@ var worksheet = XLSX.utils.aoa_to_sheet([
|
||||
])
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
If the actual results are needed in JS, [SheetJS Pro](https://sheetjs.com/pro)
|
||||
offers a formula calculator component for evaluating expressions, updating
|
||||
values and dependent cells, and refreshing entire workbooks.
|
||||
|
||||
:::
|
||||
|
||||
## Array Formulae
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Hyperlinks
|
||||
@ -124,7 +124,7 @@ function SheetJSParseLinks(props) {
|
||||
|
||||
## Remote Links
|
||||
|
||||
HTTP / HTTPS links can be used directly:
|
||||
HTTP and HTTPS links can be used directly:
|
||||
|
||||
```js
|
||||
ws["A2"].l = { Target: "https://docs.sheetjs.com/docs/csf/features/hyperlinks" };
|
||||
@ -208,6 +208,14 @@ ws["C3"].l = { Target: "#SheetJSDName" }; /* Link to Defined Name */
|
||||
|
||||
<details><summary><b>Live Example</b> (click to show)</summary>
|
||||
|
||||
This demo creates a workbook with two worksheets. In the first worksheet:
|
||||
|
||||
- Cell `A1` ("Same") will link to the range `B2:D4` in the first sheet
|
||||
- Cell `B1` ("Cross") will link to the range `B2:D4` in the second sheet
|
||||
- Cell `C1` ("Name") will link to the range in the defined name `SheetJSDN`
|
||||
|
||||
The defined name `SheetJSDN` points to the range `A1:B2` in the second sheet.
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportInternalLink(props) { return ( <button onClick={() => {
|
||||
@ -248,10 +256,13 @@ XLSX documents. A workaround was added in library version 0.18.12.
|
||||
|
||||
## HTML
|
||||
|
||||
The HTML DOM parser will process `<a>` links in the table:
|
||||
The HTML DOM parser[^1] will process `<a>` links in the table.
|
||||
|
||||
<details open><summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
This example uses `table_to_book` to generate a SheetJS workbook object from a
|
||||
HTML table. The hyperlink in the second row will be parsed as a cell-level link.
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportHyperlink(props) {
|
||||
@ -278,3 +289,37 @@ function ExportHyperlink(props) {
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
The HTML writer[^2] will generate `<a>` links.
|
||||
|
||||
<details open><summary><b>Live Example</b> (click to hide)</summary>
|
||||
|
||||
This example creates a worksheet where `A1` has a link and `B1` does not. The
|
||||
`sheet_to_html` function generates an HTML table where the topleft table cell
|
||||
has a standard HTML link.
|
||||
|
||||
```jsx live
|
||||
/* The live editor requires this function wrapper */
|
||||
function ExportALinks(props) {
|
||||
const [ __html, setHTML ] = React.useState("");
|
||||
React.useEffect(() => {
|
||||
/* Create worksheet */
|
||||
var ws = XLSX.utils.aoa_to_sheet([ [ "Link", "No Link" ] ]);
|
||||
/* Add link */
|
||||
ws["A1"].l = {
|
||||
Target: "https://sheetjs.com",
|
||||
Tooltip: "Find us @ SheetJS.com!"
|
||||
};
|
||||
|
||||
/* Generate HTML */
|
||||
setHTML(XLSX.utils.sheet_to_html(ws));
|
||||
}, []);
|
||||
|
||||
return ( <div dangerouslySetInnerHTML={{__html}}/> );
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
[^1]: The primary SheetJS DOM parsing methods are [`table_to_book`, `table_to_sheet`, and `sheet_add_dom`](/docs/api/utilities/html#html-table-input)
|
||||
[^2]: HTML strings can be written using [`bookType: "html"` in the `write` or `writeFile` methods](/docs/api/write-options) or by using the [dedicated `sheet_to_html` utility function](/docs/api/utilities/html#html-table-output)
|
@ -167,7 +167,6 @@ function SheetJSComments2() {
|
||||
XLSX.writeFile(wb, "SheetJSComments2.xlsx");
|
||||
}}>Click me to generate a sample file</button>);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
150
docz/docs/07-csf/07-features/08-visibility.md
Normal file
150
docz/docs/07-csf/07-features/08-visibility.md
Normal file
@ -0,0 +1,150 @@
|
||||
---
|
||||
title: Sheet Visibility
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><b>File Format Support</b> (click to show)</summary>
|
||||
|
||||
By default, all sheets in a workbook are "Visible". The standard "Hidden" state
|
||||
is controlled through the context menu in the sheet tab bar. The "Very Hidden"
|
||||
state is controlled through the "Visibility" property in the VBA editor.
|
||||
|
||||
| Formats | Hidden | Very Hidden |
|
||||
|:----------|:------:|:-----------:|
|
||||
| XLSX/XLSM | ✔ | ✔ |
|
||||
| XLSB | ✔ | ✔ |
|
||||
| XLML | ✔ | ✔ |
|
||||
| BIFF8 XLS | ✔ | ✔ |
|
||||
| BIFF5 XLS | ✔ | ✔ |
|
||||
|
||||
</details>
|
||||
|
||||
Excel enables hiding sheets in the lower tab bar. The sheet data is stored in
|
||||
the file but the UI does not readily make it available.
|
||||
|
||||
Standard "hidden" sheets are revealed in the "Unhide" menu.
|
||||
|
||||
Excel also has "very hidden" sheets which cannot be revealed in the menu. They
|
||||
are only accessible in the VB Editor!
|
||||
|
||||
## Storage
|
||||
|
||||
The visibility setting is stored in the `Hidden` property of the corresponding
|
||||
[metadata in the `wb.Workbook.Sheets` array](/docs/csf/book#sheet-metadata)
|
||||
|
||||
The recognized values are listed below:
|
||||
|
||||
| Value | Definition | VB Editor "Visible" Property |
|
||||
|:-----:|:------------|:-----------------------------|
|
||||
| 0 | Visible | `-1 - xlSheetVisible` |
|
||||
| 1 | Hidden | ` 0 - xlSheetHidden` |
|
||||
| 2 | Very Hidden | ` 2 - xlSheetVeryHidden` |
|
||||
|
||||
If the respective Sheet entry does not exist or if the `Hidden` property is not
|
||||
set, the worksheet is visible.
|
||||
|
||||
### Parsing
|
||||
|
||||
Since worksheet visibility is stored in the workbook, both the workbook object
|
||||
and the sheet name must be known to determine visibility setting.
|
||||
|
||||
```js
|
||||
function get_sheet_visibility(workbook, sheet_name) {
|
||||
// if the metadata does not exist for the sheet, the sheet is visible
|
||||
if(!workbook.Workbook) return 0;
|
||||
if(!workbook.Workbook.Sheets) return 0;
|
||||
|
||||
var idx = workbook.SheetNames.indexOf(sheet_name);
|
||||
if(idx == -1) throw new Error(`Sheet ${sheet_name} missing from workbook`);
|
||||
|
||||
var meta = workbook.Workbook.Sheets[idx];
|
||||
return meta && meta.Hidden || 0;
|
||||
}
|
||||
```
|
||||
|
||||
Typically the distinction between "hidden" and "very hidden" is not relevant for
|
||||
applications. The values were chosen to make logical negation work as expected:
|
||||
|
||||
```js
|
||||
function is_sheet_visible(workbook, sheet_name) {
|
||||
return !get_sheet_visibility(workbook, sheet_name); // true if visible
|
||||
}
|
||||
```
|
||||
|
||||
### Writing
|
||||
|
||||
When assigning, the entire workbook metadata structure should be tested and
|
||||
constructed if necessary:
|
||||
|
||||
```js
|
||||
function set_sheet_visibility(workbook, sheet_name, Hidden) {
|
||||
var idx = workbook.SheetNames.indexOf(sheet_name);
|
||||
if(idx == -1) throw new Error(`Sheet ${sheet_name} missing from workbook`);
|
||||
|
||||
// if the metadata does not exist for the sheet, create it
|
||||
if(!workbook.Workbook) workbook.Workbook = {};
|
||||
if(!workbook.Workbook.Sheets) workbook.Workbook.Sheets = [];
|
||||
if(!workbook.Workbook.Sheets[idx]) workbook.Workbook.Sheets[idx] = {};
|
||||
|
||||
// set visibility
|
||||
workbook.Workbook.Sheets[idx].Hidden = Hidden;
|
||||
}
|
||||
```
|
||||
|
||||
## Demo
|
||||
|
||||
[This test file](pathname:///files/sheet_visibility.xlsx) has three sheets:
|
||||
|
||||
- "Visible" is visible
|
||||
- "Hidden" is hidden
|
||||
- "VeryHidden" is very hidden
|
||||
|
||||
![Screenshot](pathname:///files/sheet_visibility.png)
|
||||
|
||||
The live demo fetches the test file and displays visibility information.
|
||||
|
||||
```jsx live
|
||||
function Visibility(props) {
|
||||
const [wb, setWB] = React.useState({SheetNames:[]});
|
||||
const [sheets, setSheets] = React.useState([]);
|
||||
const vis = [ "Visible", "Hidden", "Very Hidden" ];
|
||||
|
||||
React.useEffect(async() => {
|
||||
const f = await fetch("/files/sheet_visibility.xlsx");
|
||||
const ab = await f.arrayBuffer();
|
||||
const wb = XLSX.read(ab);
|
||||
setWB(wb);
|
||||
/* State will be set to the `Sheets` property array */
|
||||
setSheets(wb.Workbook.Sheets);
|
||||
}, []);
|
||||
|
||||
return (<table>
|
||||
<thead><tr><th>Name</th><th>Value</th><th>Hidden</th></tr></thead>
|
||||
<tbody>{wb.SheetNames.map((n,i) => {
|
||||
const h = ((((wb||{}).Workbook||{}).Sheets||[])[i]||{}).Hidden||0;
|
||||
return ( <tr key={i}>
|
||||
<td>{n}</td>
|
||||
<td>{h} - {vis[h]}</td>
|
||||
<td>{!h ? "No" : "Yes"}</td>
|
||||
</tr> );
|
||||
})}</tbody></table>);
|
||||
}
|
||||
```
|
||||
|
||||
:::info pass
|
||||
|
||||
The live codeblock tests for visibility with:
|
||||
|
||||
```js
|
||||
const h = ((((wb||{}).Workbook||{}).Sheets||[])[i]||{}).Hidden||0;
|
||||
```
|
||||
|
||||
With modern JS, this can be written as
|
||||
|
||||
```js
|
||||
const h = wb?.Workbook?.Sheets?.[i]?.Hidden||0;
|
||||
```
|
||||
|
||||
:::
|
||||
|
@ -138,91 +138,3 @@ follow the priority order:
|
||||
3) use `wch` character count if available
|
||||
|
||||
</details>
|
||||
|
||||
## Sheet Visibility
|
||||
|
||||
<details>
|
||||
<summary><b>Format Support</b> (click to show)</summary>
|
||||
|
||||
**Hidden Sheets**: XLSX/M, XLSB, BIFF8/BIFF5 XLS, XLML
|
||||
|
||||
**Very Hidden Sheets**: XLSX/M, XLSB, BIFF8/BIFF5 XLS, XLML
|
||||
|
||||
</details>
|
||||
|
||||
Excel enables hiding sheets in the lower tab bar. The sheet data is stored in
|
||||
the file but the UI does not readily make it available. Standard hidden sheets
|
||||
are revealed in the "Unhide" menu. Excel also has "very hidden" sheets which
|
||||
cannot be revealed in the menu. It is only accessible in the VB Editor!
|
||||
|
||||
The visibility setting is stored in the `Hidden` property of sheet props array.
|
||||
|
||||
| Value | Definition | VB Editor "Visible" Property |
|
||||
|:-----:|:------------|:-----------------------------|
|
||||
| 0 | Visible | `-1 - xlSheetVisible` |
|
||||
| 1 | Hidden | ` 0 - xlSheetHidden` |
|
||||
| 2 | Very Hidden | ` 2 - xlSheetVeryHidden` |
|
||||
|
||||
If the respective Sheet entry does not exist or if the `Hidden` property is not
|
||||
set, the worksheet is visible.
|
||||
|
||||
**List all worksheets and their visibility settings**
|
||||
|
||||
```js
|
||||
wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] })
|
||||
// [ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ]
|
||||
```
|
||||
|
||||
**Check if worksheet is visible**
|
||||
|
||||
Non-Excel formats do not support the Very Hidden state. The best way to test
|
||||
if a sheet is visible is to check if the `Hidden` property is logical truth:
|
||||
|
||||
```js
|
||||
wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] })
|
||||
// [ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ]
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Live Example</b> (click to show)</summary>
|
||||
|
||||
|
||||
[This test file](pathname:///files/sheet_visibility.xlsx) has three sheets:
|
||||
|
||||
- "Visible" is visible
|
||||
- "Hidden" is hidden
|
||||
- "VeryHidden" is very hidden
|
||||
|
||||
![Screenshot](pathname:///files/sheet_visibility.png)
|
||||
|
||||
**Live demo**
|
||||
|
||||
```jsx live
|
||||
function Visibility(props) {
|
||||
const [sheets, setSheets] = React.useState([]);
|
||||
const names = [ "Visible", "Hidden", "Very Hidden" ];
|
||||
|
||||
React.useEffect(async() => {
|
||||
const f = await fetch("/files/sheet_visibility.xlsx");
|
||||
const ab = await f.arrayBuffer();
|
||||
const wb = XLSX.read(ab);
|
||||
|
||||
/* State will be set to the `Sheets` property array */
|
||||
setSheets(wb.Workbook.Sheets);
|
||||
}, []);
|
||||
|
||||
return (<table>
|
||||
<thead><tr><th>Name</th><th>Value</th><th>Hidden</th></tr></thead>
|
||||
<tbody>{sheets.map((x,i) => (<tr key={i}>
|
||||
|
||||
<td>{x.name}</td>
|
||||
|
||||
<td>{x.Hidden} - {names[x.Hidden]}</td>
|
||||
|
||||
<td>{!x.Hidden ? "No" : "Yes"}</td>
|
||||
|
||||
</tr>))}</tbody></table>);
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
31
docz/static/mongodb/SheetJSMongoCRUD.mjs
Normal file
31
docz/static/mongodb/SheetJSMongoCRUD.mjs
Normal file
@ -0,0 +1,31 @@
|
||||
import { writeFile, set_fs, utils } from 'xlsx';
|
||||
import * as fs from 'fs'; set_fs(fs);
|
||||
import { MongoClient } from 'mongodb';
|
||||
|
||||
const url = 'mongodb://localhost:27017/sheetjs';
|
||||
const db_name = 'sheetjs';
|
||||
|
||||
/* Connect to mongodb server */
|
||||
const client = await MongoClient.connect(url, { useUnifiedTopology: true });
|
||||
|
||||
/* Sample data table */
|
||||
const db = client.db(db_name);
|
||||
try { await db.collection('pres').drop(); } catch(e) {}
|
||||
const pres = db.collection('pres');
|
||||
await pres.insertMany([
|
||||
{ name: "Barack Obama", idx: 44 },
|
||||
{ name: "Donald Trump", idx: 45 },
|
||||
{ name: "Joseph Biden", idx: 46 }
|
||||
], {ordered: true});
|
||||
|
||||
/* Create worksheet from collection */
|
||||
const aoo = await pres.find({}, {projection:{_id:0}}).toArray();
|
||||
const ws = utils.json_to_sheet(aoo);
|
||||
|
||||
/* Export to XLSX */
|
||||
const wb = utils.book_new();
|
||||
utils.book_append_sheet(wb, ws, "Presidents");
|
||||
writeFile(wb, "SheetJSMongoCRUD.xlsx");
|
||||
|
||||
/* Close connection */
|
||||
client.close();
|
Loading…
Reference in New Issue
Block a user