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) | ||||
| })); | ||||
| 
 | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| **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