forked from sheetjs/docs.sheetjs.com
		
	neu
This commit is contained in:
		
							parent
							
								
									aa7cc47197
								
							
						
					
					
						commit
						5f52a9f6b6
					
				@ -78,7 +78,7 @@ The React `useState` hook can configure the state:
 | 
			
		||||
```ts
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
 | 
			
		||||
/* the component state is an array of presidents */
 | 
			
		||||
/* the component state is an array of objects */
 | 
			
		||||
const [pres, setPres] = useState([]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -88,6 +88,15 @@ const [pres, setPres] = useState([]);
 | 
			
		||||
```ts
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
 | 
			
		||||
/* the component state is an array of objects */
 | 
			
		||||
const [pres, setPres] = useState<any[]>([]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
When the spreadsheet header row is known ahead of time, row typing is possible:
 | 
			
		||||
 | 
			
		||||
```ts
 | 
			
		||||
import { useState } from 'react';
 | 
			
		||||
 | 
			
		||||
interface President {
 | 
			
		||||
  Name: string;
 | 
			
		||||
  Index: number;
 | 
			
		||||
@ -97,11 +106,13 @@ interface President {
 | 
			
		||||
const [pres, setPres] = useState<President[]>([]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
The types are informative. They do not enforce that worksheets include the named
 | 
			
		||||
columns. A runtime data validation library should be used to verify the dataset.
 | 
			
		||||
 | 
			
		||||
When the file header is not known in advance, `any` should be used.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
 | 
			
		||||
@ -212,7 +212,7 @@ require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
The ["Dojo" section in "Bundlers"](/docs/demos/bundler#dojo) includes a complete example
 | 
			
		||||
mirroring the [official example](/docs/getting-started/example)
 | 
			
		||||
mirroring the [official export example](/docs/getting-started/example)
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Details</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -257,9 +257,10 @@ This demo was tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| OS and Version | Arch | Tauri    | Date       |
 | 
			
		||||
|:---------------|:-----|:---------|:-----------|
 | 
			
		||||
| macOS 13.4.1   | ARM  | `v1.4.0` | 2023-06-29 |
 | 
			
		||||
| macOS 13.4.0   | x64  | `v1.4.0` | 2023-06-25 |
 | 
			
		||||
| Windows 10     | x64  | `v1.2.3` | 2023-03-18 |
 | 
			
		||||
| Linux (HoloOS) | x64  | `v1.2.3` | 2023-03-18 |
 | 
			
		||||
| Linux (HoloOS) | x64  | `v1.2.3` |            |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -294,6 +295,13 @@ If required dependencies are installed, the output will show a checkmark next to
 | 
			
		||||
    - npm: 9.5.1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
When the demo was last tested on ARM64 macOS, the output mentioned `X64`. The
 | 
			
		||||
build step will correctly detect the platform architecture.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
1) Create a new Tauri app:
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
---
 | 
			
		||||
title: NeutralinoJS
 | 
			
		||||
sidebar_label: NeutralinoJS
 | 
			
		||||
description: Build data-intensive desktop apps using NeutralinoJS. Seamlessly integrate spreadsheets into your app using SheetJS. Quickly modernize Excel-powered business processes.
 | 
			
		||||
pagination_prev: demos/mobile/index
 | 
			
		||||
pagination_next: demos/data/index
 | 
			
		||||
sidebar_position: 5
 | 
			
		||||
@ -7,15 +9,25 @@ sidebar_custom_props:
 | 
			
		||||
  summary: Webview + Lightweight Extensions
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# Data Munging in NeutralinoJS
 | 
			
		||||
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import Tabs from '@theme/Tabs';
 | 
			
		||||
import TabItem from '@theme/TabItem';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
The [Standalone build](/docs/getting-started/installation/standalone) can be added
 | 
			
		||||
to the entry `index.html`
 | 
			
		||||
[NeutralinoJS](https://neutralino.js.org/) is a modern desktop app framework.
 | 
			
		||||
NeutralinoJS apps pair platform-native browser tools with a static web server.
 | 
			
		||||
 | 
			
		||||
The "Complete Example" creates an app that looks like the screenshot:
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo uses NeutralinoJS and SheetJS to pull data from a spreadsheet and
 | 
			
		||||
display the data in the app. We'll explore how to load SheetJS in a NeutralinoJS
 | 
			
		||||
app and use native features to read and write files.
 | 
			
		||||
 | 
			
		||||
The ["Complete Example"](#complete-example) section covers a complete desktop
 | 
			
		||||
app to read and write workbooks. The app will look like the screenshots below:
 | 
			
		||||
 | 
			
		||||
<table><thead><tr>
 | 
			
		||||
  <th><a href="#complete-example">Win10</a></th>
 | 
			
		||||
@ -37,15 +49,16 @@ The "Complete Example" creates an app that looks like the screenshot:
 | 
			
		||||
 | 
			
		||||
## Integration Details
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
The [SheetJS Standalone build](/docs/getting-started/installation/standalone)
 | 
			
		||||
can be added to the entry `index.html`
 | 
			
		||||
 | 
			
		||||
NeutralinoJS currently does not provide the equivalent of NodeJS `fs` module.
 | 
			
		||||
The raw `Neutralino.filesystem` and `Neutralino.os` methods are used.
 | 
			
		||||
For code running in the window, native methods must be explicitly enabled in the
 | 
			
		||||
NeutralinoJS `neutralino.conf.json` settings file[^1].
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
- `os.*` enables the open and save dialog methods.
 | 
			
		||||
- `filesystem.*` enables reading and writing file data.
 | 
			
		||||
 | 
			
		||||
The `os` and `filesystem` modules must be enabled in `neutralino.conf.json`.
 | 
			
		||||
The starter already enables `os` so typically one line must be added:
 | 
			
		||||
The starter app enables `os.*` so typically one line must be added:
 | 
			
		||||
 | 
			
		||||
```json title="neutralino.config.json"
 | 
			
		||||
  "nativeAllowList": [
 | 
			
		||||
@ -57,28 +70,33 @@ The starter already enables `os` so typically one line must be added:
 | 
			
		||||
  ],
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::caution
 | 
			
		||||
 | 
			
		||||
At the time of writing, `filters` did not work as expected on MacOS.  They have
 | 
			
		||||
been omitted in the example and commented in the code snippets
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### Reading Files
 | 
			
		||||
 | 
			
		||||
There are two steps to reading files: obtaining a path and reading binary data:
 | 
			
		||||
There are three steps to reading files:
 | 
			
		||||
 | 
			
		||||
1) Show an open file dialog with `Neutralino.os.showOpenDialog`[^2]. This method
 | 
			
		||||
   resolves to the selected path.
 | 
			
		||||
 | 
			
		||||
2) Read raw data from the file with `Neutralino.filesystem.readBinaryFile`[^3].
 | 
			
		||||
   This method resolves to a standard `ArrayBuffer`.
 | 
			
		||||
 | 
			
		||||
3) Parse the data with the SheetJS `read` method[^4]. This method returns a
 | 
			
		||||
   SheetJS workbook object.
 | 
			
		||||
 | 
			
		||||
The following code example defines a single function `openFile` that performs
 | 
			
		||||
all three steps and returns a SheetJS workbook object:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const filters = [
 | 
			
		||||
  {name: "Excel Binary Workbook", extensions: ["xlsb"]},
 | 
			
		||||
  {name: "Excel Workbook", extensions: ["xlsx"]},
 | 
			
		||||
  {name: "Excel Binary Workbook", extensions: ["xls", "xlsb"]},
 | 
			
		||||
  {name: "Excel Workbook", extensions: ["xls", "xlsx"]},
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
async function openFile() {
 | 
			
		||||
  /* show open file dialog */
 | 
			
		||||
  const [filename] = await Neutralino.os.showOpenDialog(
 | 
			
		||||
    'Open a spreadsheet',
 | 
			
		||||
    { /* filters, */ multiSelections: false }
 | 
			
		||||
    { filters, multiSelections: false }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /* read data into an ArrayBuffer */
 | 
			
		||||
@ -90,23 +108,56 @@ async function openFile() {
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This method can be called from a button click or other event.
 | 
			
		||||
At this point, standard SheetJS utility functions[^5] can extract data from the
 | 
			
		||||
workbook object. The demo includes a button that calls `sheet_to_html`[^6] to
 | 
			
		||||
generate an HTML TABLE and add to the DOM:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const open_button_callback = async() => {
 | 
			
		||||
  const wb = await openFile();
 | 
			
		||||
 | 
			
		||||
  /* get the first worksheet */
 | 
			
		||||
  // highlight-start
 | 
			
		||||
  const ws = wb.Sheets[wb.SheetNames[0]];
 | 
			
		||||
  // highlight-end
 | 
			
		||||
 | 
			
		||||
  /* get data from the first worksheet */
 | 
			
		||||
  // highlight-start
 | 
			
		||||
  const html = XLSX.utils.sheet_to_html(ws);
 | 
			
		||||
  // highlight-end
 | 
			
		||||
 | 
			
		||||
  /* display table */
 | 
			
		||||
  document.getElementById('info').innerHTML = html;
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Writing Files
 | 
			
		||||
 | 
			
		||||
There are two steps to writing files: obtaining a path and writing binary data:
 | 
			
		||||
There are three steps to reading files:
 | 
			
		||||
 | 
			
		||||
1) Show a file dialog with `Neutralino.os.showSaveDialog`[^7]. This method
 | 
			
		||||
   resolves to the selected path.
 | 
			
		||||
 | 
			
		||||
2) Write the data with the SheetJS `write` method[^8]. The output book type can
 | 
			
		||||
   be inferred from the selected file path. Using the `buffer` output type[^9],
 | 
			
		||||
   the method returns a `Uint8Array` object that plays nice with NeutralinoJS.
 | 
			
		||||
 | 
			
		||||
2) Write to file with `Neutralino.filesystem.writeBinaryFile`[^10].
 | 
			
		||||
 | 
			
		||||
The following code example defines a single function `saveFile` that performs
 | 
			
		||||
all three steps starting from a SheetJS workbook object:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const filters = [
 | 
			
		||||
  {name: "Excel Binary Workbook", extensions: ["xlsb"]},
 | 
			
		||||
  {name: "Excel Workbook", extensions: ["xlsx"]},
 | 
			
		||||
  {name: "Excel Binary Workbook", extensions: ["xls", "xlsb"]},
 | 
			
		||||
  {name: "Excel Workbook", extensions: ["xls", "xlsx"]},
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
async function saveFile(wb) {
 | 
			
		||||
  /* show save file dialog */
 | 
			
		||||
  const filename = await Neutralino.os.showSaveDialog(
 | 
			
		||||
    'Save to file',
 | 
			
		||||
    { /* filters */ }
 | 
			
		||||
    { filters }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /* Generate workbook */
 | 
			
		||||
@ -118,11 +169,35 @@ async function saveFile(wb) {
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The demo includes a button that calls `table_to_book`[^11] to generate a
 | 
			
		||||
workbook object from the HTML table:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const save_button_callback = async() => {
 | 
			
		||||
  /* get the table */
 | 
			
		||||
  const tbl = document.getElementById('info').querySelector('table');
 | 
			
		||||
 | 
			
		||||
  /* generate workbook from the table */
 | 
			
		||||
  // highlight-start
 | 
			
		||||
  const wb = XLSX.utils.table_to_book(tbl);
 | 
			
		||||
  // highlight-end
 | 
			
		||||
 | 
			
		||||
  await saveFile(wb);
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Complete Example
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
This demo was tested on 2023 March 19 with "binaries" `4.7.0` and "client" `3.6.0`
 | 
			
		||||
This demo was tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| OS and Version | Arch | Server    | Client   | Date       |
 | 
			
		||||
|:---------------|:-----|:----------|:---------|:-----------|
 | 
			
		||||
| macOS 13.4.1   | x64  | `v4.10.0` | `v3.8.2` | 2023-06-28 |
 | 
			
		||||
| macOS 13.4.1   | ARM  | `v4.10.0` | `v3.8.2` | 2023-06-28 |
 | 
			
		||||
| Windows 10     | x64  | `v4.7.0`  | `v3.6.0` | 2023-03-19 |
 | 
			
		||||
| Linux (HoloOS) | x64  | `v4.7.0`  | `v3.6.0` |            |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -137,13 +212,13 @@ cd sheetjs-neu
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Download [Standalone build](/docs/getting-started/installation/standalone)
 | 
			
		||||
and place in `resources/js/main.js`:
 | 
			
		||||
and place in the `resources/js/` folder:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
curl -L -o resources/js/xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
3) Add the highlighted line to `neutralino.conf.json` in `nativeAllowList`:
 | 
			
		||||
3) Add the highlighted line to `neutralino.config.json` in `nativeAllowList`:
 | 
			
		||||
 | 
			
		||||
```json title="neutralino.config.json"
 | 
			
		||||
  "nativeAllowList": [
 | 
			
		||||
@ -158,9 +233,16 @@ curl -L -o resources/js/xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}
 | 
			
		||||
 | 
			
		||||
4) Set up skeleton app and print version info:
 | 
			
		||||
 | 
			
		||||
- Edit `resources/index.html` and replace the `<body>` with the code below:
 | 
			
		||||
- Replace the contents of `resources/index.html` with the following code:
 | 
			
		||||
 | 
			
		||||
```html title="resources/index.html"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
  <head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <title>SheetJS + NeutralinoJS</title>
 | 
			
		||||
    <link rel="stylesheet" href="styles.css">
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="neutralinoapp">
 | 
			
		||||
      <h1>SheetJS × NeutralinoJS</h1>
 | 
			
		||||
@ -173,6 +255,7 @@ curl -L -o resources/js/xlsx.full.min.js https://cdn.sheetjs.com/xlsx-${current}
 | 
			
		||||
    <script src="js/xlsx.full.min.js"></script>
 | 
			
		||||
    <script src="js/main.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- Append the following code to `resources/styles.css` to center the table:
 | 
			
		||||
@ -190,6 +273,8 @@ table {
 | 
			
		||||
- Print the version number in the `showInfo` method of `resources/js/main.js`:
 | 
			
		||||
 | 
			
		||||
```js title="resources/js/main.js"
 | 
			
		||||
function showInfo() {
 | 
			
		||||
    document.getElementById('info').innerHTML = `
 | 
			
		||||
        ${NL_APPID} is running on port ${NL_PORT}  inside ${NL_OS}
 | 
			
		||||
        <br/><br/>
 | 
			
		||||
        <span>server: v${NL_VERSION} . client: v${NL_CVERSION}</span>
 | 
			
		||||
@ -198,6 +283,7 @@ table {
 | 
			
		||||
        <span>SheetJS version ${XLSX.version}</span>
 | 
			
		||||
// highlight-end
 | 
			
		||||
        `;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
5) Run the app:
 | 
			
		||||
@ -206,11 +292,11 @@ table {
 | 
			
		||||
npx @neutralinojs/neu run
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You should see `SheetJS Version ` followed by the library version number.
 | 
			
		||||
<p>The app should print <code>SheetJS Version {current}</code></p>
 | 
			
		||||
 | 
			
		||||
6) Add the following code to the bottom of `resources/js/main.js`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
```js title="resources/js/main.js"
 | 
			
		||||
(async() => {
 | 
			
		||||
  const ab = await (await fetch("https://sheetjs.com/pres.numbers")).arrayBuffer();
 | 
			
		||||
  const wb = XLSX.read(ab);
 | 
			
		||||
@ -219,13 +305,13 @@ You should see `SheetJS Version ` followed by the library version number.
 | 
			
		||||
})();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Save the source file, close the app and re-run the command from step 5.
 | 
			
		||||
Save the source file, close the app and re-run with `npx @neutralinojs/neu run`
 | 
			
		||||
 | 
			
		||||
When the app loads, a table should show in the main screen.
 | 
			
		||||
 | 
			
		||||
7) Add `importFile` and `exportFile` to the bottom of `resources/js/main.js`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
```js title="resources/js/main.js"
 | 
			
		||||
async function importData() {
 | 
			
		||||
  /* show open dialog */
 | 
			
		||||
  const [filename] = await Neutralino.os.showOpenDialog('Open a spreadsheet');
 | 
			
		||||
@ -240,7 +326,7 @@ async function importData() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function exportData() {
 | 
			
		||||
    /* show save dialog */
 | 
			
		||||
  /* show save dialog */
 | 
			
		||||
  const filename = await Neutralino.os.showSaveDialog('Save to file');
 | 
			
		||||
 | 
			
		||||
  /* make workbook */
 | 
			
		||||
@ -254,15 +340,36 @@ async function exportData() {
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Save the source file, close the app and re-run the command from step 5.
 | 
			
		||||
Save the source file, close the app and re-run with `npx @neutralinojs/neu run`
 | 
			
		||||
 | 
			
		||||
When the app loads, click the "Import File" button and select a spreadsheet to
 | 
			
		||||
see the contents.  Click "Export File" and enter `SheetJSNeu.xlsx` to write.
 | 
			
		||||
see the contents.
 | 
			
		||||
 | 
			
		||||
Click "Export File" and enter `SheetJSNeu.xlsx` to write a new file.
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
When saving the file, the actual file extension must be included. Attempting to
 | 
			
		||||
save as `SheetJSNeu` will not automatically add the `.xlsx` extension!
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
8) Build production apps:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx @neutralinojs/neu run
 | 
			
		||||
npx @neutralinojs/neu build
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Platform-specific programs will be created in the `dist` folder.
 | 
			
		||||
 | 
			
		||||
[^1]: See [`nativeAllowList`](https://neutralino.js.org/docs/configuration/neutralino.config.json#nativeallowlist-string) in the NeutralinoJS documentation
 | 
			
		||||
[^2]: See [`os.showOpenDialog`](https://neutralino.js.org/docs/api/os#osshowopendialogtitle-options) in the NeutralinoJS documentation
 | 
			
		||||
[^3]: See [`filesystem.readBinaryFile`](https://neutralino.js.org/docs/api/filesystem/#filesystemreadbinaryfilefilename) in the NeutralinoJS documentation
 | 
			
		||||
[^4]: See [`read` in "Reading Files"](/docs/api/parse-options)
 | 
			
		||||
[^5]: See ["Utility Functions"](/docs/api/utilities/)
 | 
			
		||||
[^6]: See ["HTML Table Output" in "Utility Functions"](/docs/api/utilities/html#html-table-output)
 | 
			
		||||
[^7]: See [`os.showSaveDialog`](https://neutralino.js.org/docs/api/os#osshowsavedialogtitle-options) in the NeutralinoJS documentation
 | 
			
		||||
[^8]: See [`write` in "Writing Files"](/docs/api/write-options)
 | 
			
		||||
[^9]: See ["Supported Output Formats"](/docs/api/write-options#supported-output-formats)
 | 
			
		||||
[^10]: See [`filesystem.writeBinaryFile`](https://neutralino.js.org/docs/api/filesystem/#filesystemwritebinaryfilefilename-data) in the NeutralinoJS documentation
 | 
			
		||||
[^11]: See ["HTML Table Input" in "Utility Functions"](/docs/api/utilities/html#html-table-input)
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ PouchDB is a pure JS database with built-in synchronization features.
 | 
			
		||||
`Database#allDocs` is the standard approach for bulk data export. The generated
 | 
			
		||||
row objects have additional `_id` and `_rev` keys that should be removed.
 | 
			
		||||
 | 
			
		||||
Nested objects must be flattened. The ["Tutorial"](/docs/getting-started/example)
 | 
			
		||||
Nested objects must be flattened. The ["Export Tutorial"](/docs/getting-started/example)
 | 
			
		||||
includes an example of constructing a simple array.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
 | 
			
		||||
@ -735,8 +735,8 @@ the function and the optional `opts` argument in more detail.
 | 
			
		||||
 | 
			
		||||
#### Examples
 | 
			
		||||
 | 
			
		||||
["Complete Example"](/docs/getting-started/example) contains a detailed example
 | 
			
		||||
"Get Data from a JSON Endpoint and Generate a Workbook"
 | 
			
		||||
["Export Tutorial"](/docs/getting-started/example) contains a detailed
 | 
			
		||||
example of fetching data from a JSON Endpoint and generating a workbook.
 | 
			
		||||
 | 
			
		||||
[`x-spreadsheet`](/docs/demos/grid/xs) is an interactive data grid for
 | 
			
		||||
previewing and modifying structured data in the web browser.
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ of date or time.  Instead, dates and times are stored as offsets from an epoch.
 | 
			
		||||
The magic behind date interpretations is hidden in functions or number formats.
 | 
			
		||||
 | 
			
		||||
SheetJS attempts to create a friendly JS date experience while also exposing
 | 
			
		||||
options to use the traditional date codes
 | 
			
		||||
options to use the traditional date codes.
 | 
			
		||||
 | 
			
		||||
:::tip pass
 | 
			
		||||
 | 
			
		||||
@ -104,7 +104,7 @@ function SheetJSNow() {
 | 
			
		||||
## How Spreadsheets Understand Time
 | 
			
		||||
 | 
			
		||||
Excel stores dates as numbers.  When displaying dates, the format code should
 | 
			
		||||
include special date and time tokens like `yyyyy` for long year. `EDATE` and
 | 
			
		||||
include special date and time tokens like `yyyy` for long year. `EDATE` and
 | 
			
		||||
other date functions operate on and return date numbers.
 | 
			
		||||
 | 
			
		||||
For date formats like `yyyy-mm-dd`, the integer part represents the number of
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docz/static/data/mf221.xlw
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								docz/static/data/mf221.xlw
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 107 KiB  | 
		Loading…
	
		Reference in New Issue
	
	Block a user