forked from sheetjs/docs.sheetjs.com
		
	darwin-arm
This commit is contained in:
		
							parent
							
								
									b230d64dd6
								
							
						
					
					
						commit
						2505d3b639
					
				@ -97,6 +97,8 @@ require(['xlsx'], function(XLSX) {
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**See the [RequireJS demo](/docs/demos/frontend/bundler/requirejs) for details**
 | 
			
		||||
 | 
			
		||||
## Dojo Toolkit
 | 
			
		||||
 | 
			
		||||
Dojo has changed module loading strategies over the years.  These examples were
 | 
			
		||||
 | 
			
		||||
@ -448,7 +448,8 @@ In the component, `aoa_to_sheet` is used to generate the worksheet:
 | 
			
		||||
The default angular-cli configuration requires no additional configuration.
 | 
			
		||||
 | 
			
		||||
Some deployments use the SystemJS loader, which does require configuration.
 | 
			
		||||
[The SystemJS demo](/docs/demos/bundler#systemjs) describe the required settings.
 | 
			
		||||
[The SystemJS demo](/docs/demos/frontend/bundler/systemjs) includes the
 | 
			
		||||
required settings.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Legacy Demo
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										225
									
								
								docz/docs/03-demos/01-frontend/19-bundler/11-requirejs.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										225
									
								
								docz/docs/03-demos/01-frontend/19-bundler/11-requirejs.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,225 @@
 | 
			
		||||
---
 | 
			
		||||
title: Bundling Sheets with RequireJS
 | 
			
		||||
sidebar_label: RequireJS
 | 
			
		||||
pagination_prev: demos/index
 | 
			
		||||
pagination_next: demos/grid/index
 | 
			
		||||
sidebar_position: 11
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import Tabs from '@theme/Tabs';
 | 
			
		||||
import TabItem from '@theme/TabItem';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
[RequireJS](https://requirejs.org/) is a JavaScript file and module loader. It
 | 
			
		||||
includes an in-browser loader as well as a static optimizer.
 | 
			
		||||
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo uses RequireJS and SheetJS to export data. We'll explore how to load
 | 
			
		||||
SheetJS in a site using RequireJS and how to use the `r.js` optimizer to create
 | 
			
		||||
a bundled site.
 | 
			
		||||
 | 
			
		||||
The [Live demo](pathname:///requirejs/requirejs.html) loads RequireJS from the
 | 
			
		||||
CDN, uses it to load the standalone script from the SheetJS CDN, and uses the
 | 
			
		||||
`XLSX` variable to create a button click handler that creates a workbook.
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 October 18 against RequireJS `2.3.6`
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Integration Details
 | 
			
		||||
 | 
			
		||||
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
 | 
			
		||||
comply with AMD `define` semantics. They support RequireJS and the `r.js`
 | 
			
		||||
optimizer out of the box.
 | 
			
		||||
 | 
			
		||||
### Config
 | 
			
		||||
 | 
			
		||||
The RequireJS config should set the `xlsx` alias in the `paths` property.
 | 
			
		||||
 | 
			
		||||
#### SheetJS CDN
 | 
			
		||||
 | 
			
		||||
The SheetJS CDN URL can be directly referenced in a path alias:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="js">{`\
 | 
			
		||||
require.config({
 | 
			
		||||
  baseUrl: ".",
 | 
			
		||||
  name: "app",
 | 
			
		||||
  paths: {
 | 
			
		||||
    // highlight-next-line
 | 
			
		||||
    xlsx: "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min"
 | 
			
		||||
  }
 | 
			
		||||
});`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Vendoring
 | 
			
		||||
 | 
			
		||||
After downloading the SheetJS standalone script, a relative path can be used in
 | 
			
		||||
the path alias. For example, if the standalone script was downloaded in the same
 | 
			
		||||
directory as the HTML page, the path should be `./xlsx.full.min`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
require.config({
 | 
			
		||||
  baseUrl: ".",
 | 
			
		||||
  name: "app",
 | 
			
		||||
  paths: {
 | 
			
		||||
    // highlight-next-line
 | 
			
		||||
    xlsx: "./xlsx.full.min"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Usage
 | 
			
		||||
 | 
			
		||||
Once the alias is set, `"xlsx"` can be required from app scripts:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
// highlight-next-line
 | 
			
		||||
require(["xlsx"], function(XLSX) {
 | 
			
		||||
  /* use XLSX here */
 | 
			
		||||
  console.log(XLSX.version);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Within the callback, the `XLSX` variable exposes the functions listed in the
 | 
			
		||||
["API Reference"](/docs/api/) section of the documentation.
 | 
			
		||||
 | 
			
		||||
## Complete Example
 | 
			
		||||
 | 
			
		||||
This demo will explore the standalone RequireJS script and the `r.js` optimizer.
 | 
			
		||||
 | 
			
		||||
### Standalone RequireJS
 | 
			
		||||
 | 
			
		||||
0) Download the SheetJS Standalone script and move to the project directory:
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
1) Save the following to `index.html`:
 | 
			
		||||
 | 
			
		||||
```html title="index.html"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head></head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="http://requirejs.org/docs/release/2.3.6/comments/require.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
/* Wire up RequireJS */
 | 
			
		||||
require.config({
 | 
			
		||||
  baseUrl: ".",
 | 
			
		||||
  name: "SheetJSRequire",
 | 
			
		||||
  paths: {
 | 
			
		||||
    xlsx: "./xlsx.full.min"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
    <script src="SheetJSRequire.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Save the following to `SheetJSRequire.js`:
 | 
			
		||||
 | 
			
		||||
```js title="SheetJSRequire.js"
 | 
			
		||||
require(["xlsx"], function(XLSX) {
 | 
			
		||||
  document.getElementById("xport").addEventListener("click", function() {
 | 
			
		||||
    /* fetch JSON data and parse */
 | 
			
		||||
    var url = "https://sheetjs.com/data/executive.json";
 | 
			
		||||
    fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) {
 | 
			
		||||
 | 
			
		||||
    /* filter for the Presidents */
 | 
			
		||||
    var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); });
 | 
			
		||||
 | 
			
		||||
    /* flatten objects */
 | 
			
		||||
    var rows = prez.map(function(row) { return {
 | 
			
		||||
      name: row.name.first + " " + row.name.last,
 | 
			
		||||
      birthday: row.bio.birthday
 | 
			
		||||
    }; });
 | 
			
		||||
 | 
			
		||||
    /* generate worksheet and workbook */
 | 
			
		||||
    var worksheet = XLSX.utils.json_to_sheet(rows);
 | 
			
		||||
    var workbook = XLSX.utils.book_new();
 | 
			
		||||
    XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
 | 
			
		||||
 | 
			
		||||
    /* fix headers */
 | 
			
		||||
    XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
 | 
			
		||||
 | 
			
		||||
    /* calculate column width */
 | 
			
		||||
    var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10);
 | 
			
		||||
    worksheet["!cols"] = [ { wch: max_width } ];
 | 
			
		||||
 | 
			
		||||
    /* create an XLSX file and try to save to Presidents.xlsx */
 | 
			
		||||
    XLSX.writeFileXLSX(workbook, "Presidents.xlsx");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
The `r.js` optimizer does not handle `async` functions or ES6 arrow functions.
 | 
			
		||||
 | 
			
		||||
To demonstrate compatibility with older versions of Webpack, `SheetJSRequire.js`
 | 
			
		||||
uses normal functions and traditional Promise chains.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
3) Start a local HTTP server, then go to `http://localhost:8080/`
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx http-server .
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Click on "Click here to export" to generate a file.
 | 
			
		||||
 | 
			
		||||
### r.js Optimizer
 | 
			
		||||
 | 
			
		||||
4) Create `build.js` configuration for the optimizer:
 | 
			
		||||
 | 
			
		||||
```js title="build.js"
 | 
			
		||||
({
 | 
			
		||||
  baseUrl: ".",
 | 
			
		||||
  name: "SheetJSRequire",
 | 
			
		||||
  paths: {
 | 
			
		||||
    xlsx: "./xlsx.full.min"
 | 
			
		||||
  },
 | 
			
		||||
  out: "SheetJSRequire.min.js"
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
5) Run the `r.js` optimizer to create `SheetJSRequire.min.js`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx -p requirejs@2.3.6 r.js -o build.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
6) Save the following to `optimized.html`:
 | 
			
		||||
 | 
			
		||||
```html title="optimized.html"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head></head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
 | 
			
		||||
    <script src="SheetJSRequire.min.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
7) Open `http://localhost:8080/optimized.html`
 | 
			
		||||
 | 
			
		||||
Click on "Click here to export" to generate a file.
 | 
			
		||||
							
								
								
									
										225
									
								
								docz/docs/03-demos/01-frontend/19-bundler/12-systemjs.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										225
									
								
								docz/docs/03-demos/01-frontend/19-bundler/12-systemjs.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,225 @@
 | 
			
		||||
---
 | 
			
		||||
title: Bundling Sheets with SystemJS
 | 
			
		||||
sidebar_label: SystemJS
 | 
			
		||||
pagination_prev: demos/index
 | 
			
		||||
pagination_next: demos/grid/index
 | 
			
		||||
sidebar_position: 12
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import Tabs from '@theme/Tabs';
 | 
			
		||||
import TabItem from '@theme/TabItem';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
SystemJS[^1] is a module loader for NodeJS and browsers.
 | 
			
		||||
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo uses SystemJS and SheetJS to export data. We'll explore two workflows:
 | 
			
		||||
 | 
			
		||||
- ["Browser"](#browser) explores how to load SheetJS with SystemJS using the
 | 
			
		||||
in-browser dynamic loader
 | 
			
		||||
 | 
			
		||||
- ["NodeJS"](#nodejs) explores how to load SheetJS with SystemJS in NodeJS.
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
This demo was originally written for SystemJS 0.19, the most popular SystemJS
 | 
			
		||||
version used with Angular projects. In the years since the release, Angular and
 | 
			
		||||
other tools using SystemJS have switched to Webpack.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was tested against the following SystemJS versions:
 | 
			
		||||
 | 
			
		||||
| Version   | Date       |
 | 
			
		||||
|:----------|:-----------|
 | 
			
		||||
| `0.19.47` | 2023-10-18 |
 | 
			
		||||
| `0.20.19` | 2023-10-18 |
 | 
			
		||||
| `0.21.6`  | 2023-10-18 |
 | 
			
		||||
| `6.14.2`  | 2023-10-18 |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Browser
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
The [Live demo](pathname:///systemjs/systemjs.html) loads SystemJS from the
 | 
			
		||||
CDN, uses it to load the standalone script from the SheetJS CDN and emulate
 | 
			
		||||
a `require` implementation when loading [`main.js`](pathname:///systemjs/main.js)
 | 
			
		||||
 | 
			
		||||
"View Source" works on the main HTML page and the `main.js` script.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
SystemJS fails by default because the library does not export anything in the
 | 
			
		||||
web browser.  The `meta` configuration option can be used to expose `XLSX`:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="js">{`\
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
  meta: {
 | 
			
		||||
    'xlsx': {
 | 
			
		||||
      exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  map: {
 | 
			
		||||
    'xlsx': 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js',
 | 
			
		||||
    'fs': '',     // <--|
 | 
			
		||||
    'crypto': '', // <--| suppress native node modules
 | 
			
		||||
    'stream': ''  // <--|
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
SystemJS.import('main.js'); // load \`main.js\``}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
With this import, the `main.js` script can freely `require("xlsx")`.
 | 
			
		||||
 | 
			
		||||
:::caution Web Workers
 | 
			
		||||
 | 
			
		||||
Web Workers can load the SystemJS library with `importScripts`, but the imported
 | 
			
		||||
code cannot assign the original worker's `onmessage` callback.  The recommended
 | 
			
		||||
approach is to expose a global from the required script,  For example, supposing
 | 
			
		||||
the shared name is `_cb`, the primary worker script would call the callback:
 | 
			
		||||
 | 
			
		||||
```js title="worker.js"
 | 
			
		||||
/* main worker script */
 | 
			
		||||
importScripts('system.js');
 | 
			
		||||
 | 
			
		||||
SystemJS.config({ /* ... browser config ... */ });
 | 
			
		||||
 | 
			
		||||
onmessage = function(evt) {
 | 
			
		||||
  SystemJS.import('workermain.js').then(function() { _cb(evt); });
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The worker script would define and expose the function:
 | 
			
		||||
 | 
			
		||||
```js title="workermain.js"
 | 
			
		||||
/* Loaded with SystemJS import */
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
 | 
			
		||||
_cb = function(evt) { /* ... do work here ... */ };
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## NodeJS
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
While SystemJS works in NodeJS, the built-in `require` should be preferred.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### Old Style
 | 
			
		||||
 | 
			
		||||
The NodeJS module main script is `xlsx/xlsx.js` and should be mapped:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
  map: {
 | 
			
		||||
    "xlsx": "./node_modules/xlsx/xlsx.js"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The standalone scripts can be required, but SystemJS config must include a hint
 | 
			
		||||
that the script assigns a global:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
  meta: {
 | 
			
		||||
    "standalone": { format: "global" }
 | 
			
		||||
  },
 | 
			
		||||
  map: {
 | 
			
		||||
    "standalone": "xlsx.full.min.js"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### New Style
 | 
			
		||||
 | 
			
		||||
Newer versions of SystemJS supports "import maps" through `applyImportMap`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const SystemJS = require('systemjs');
 | 
			
		||||
const src = require("path").join(process.cwd(), 'node_modules/xlsx/xlsx.js');
 | 
			
		||||
SystemJS.applyImportMap(SystemJS.System, {
 | 
			
		||||
  imports: {
 | 
			
		||||
    'xlsx': "file://" + src,
 | 
			
		||||
    'fs': 'node:fs',
 | 
			
		||||
    'crypto': 'node:crypto',
 | 
			
		||||
    'stream': 'node:stream'
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
````
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
In the modern style, importing to the name `XLSX` will cause conflicts.
 | 
			
		||||
 | 
			
		||||
**It is strongly recommended to import to the name `_XLSX`!**
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
SystemJS.System.import("xlsx").then(function(
 | 
			
		||||
// highlight-next-line
 | 
			
		||||
  _XLSX // use _XLSX instead of XLSX
 | 
			
		||||
) {
 | 
			
		||||
  if(typeof XLSX == "undefined") throw "Import failed!";
 | 
			
		||||
 | 
			
		||||
  // XLSX is defined here
 | 
			
		||||
  console.log(XLSX.version);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### NodeJS Demo
 | 
			
		||||
 | 
			
		||||
0) Prepare a blank project:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
mkdir sheetjs-systemjs
 | 
			
		||||
cd sheetjs-systemjs
 | 
			
		||||
npm init -y
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Install the dependencies:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz systemjs@6.14.2`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Download [`SheetJSystem.js`](pathname:///systemjs/SheetJSystem.js) and move
 | 
			
		||||
to the project folder:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/systemjs/SheetJSystem.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
The script is handles both old-style and new-style SystemJS loaders.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
3) Run in NodeJS:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
node SheetJSystem.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If the demo worked, `Presidents.xlsx` will be created.
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
As it uses `fetch`, this demo requires Node 18.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[^1]: The project does not have a separate website. The source repository is hosted on [GitHub](https://github.com/systemjs/systemjs)
 | 
			
		||||
@ -11,6 +11,7 @@ import current from '/version.js';
 | 
			
		||||
import Tabs from '@theme/Tabs';
 | 
			
		||||
import TabItem from '@theme/TabItem';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
 | 
			
		||||
 | 
			
		||||
SheetJS predates ECMAScript modules and most bundler tools. As best practices
 | 
			
		||||
have evolved, stress testing SheetJS libraries have revealed bugs in bundlers
 | 
			
		||||
@ -23,6 +24,16 @@ considered a bundler bug if the tool cannot properly handle JS libraries.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
The following tools are covered in separate pages:
 | 
			
		||||
 | 
			
		||||
<ul>{useCurrentSidebarCategory().items.filter(item => !item?.customProps?.skip).map((item, index) => {
 | 
			
		||||
  const listyle = (item.customProps?.icon) ? {
 | 
			
		||||
    listStyleImage: `url("${item.customProps.icon}")`
 | 
			
		||||
  } : {};
 | 
			
		||||
  return (<li style={listyle} {...(item.customProps?.class ? {className: item.customProps.class}: {})}>
 | 
			
		||||
    <a href={item.href}>{item.label}</a>{item.customProps?.summary && (" - " + item.customProps.summary)}
 | 
			
		||||
  </li>);
 | 
			
		||||
})}</ul>
 | 
			
		||||
 | 
			
		||||
## Browserify
 | 
			
		||||
 | 
			
		||||
@ -481,167 +492,7 @@ click the "Click to Export!" button to generate a file.
 | 
			
		||||
 | 
			
		||||
## RequireJS
 | 
			
		||||
 | 
			
		||||
The [SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
 | 
			
		||||
comply with AMD `define` semantics. They support RequireJS out of the box.
 | 
			
		||||
 | 
			
		||||
The RequireJS config should set the `xlsx` alias in the `paths` property:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
require.config({
 | 
			
		||||
  baseUrl: ".",
 | 
			
		||||
  name: "app",
 | 
			
		||||
  paths: {
 | 
			
		||||
    // highlight-next-line
 | 
			
		||||
    xlsx: "xlsx.full.min"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
// highlight-next-line
 | 
			
		||||
require(["xlsx"], function(XLSX) {
 | 
			
		||||
  /* use XLSX here */
 | 
			
		||||
  console.log(XLSX.version);
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The [Live demo](pathname:///requirejs/requirejs.html) loads RequireJS from the
 | 
			
		||||
CDN, uses it to load the standalone script from the SheetJS CDN, and uses the
 | 
			
		||||
`XLSX` variable to create a button click handler that creates a workbook.
 | 
			
		||||
 | 
			
		||||
The `r.js` optimizer also supports the standalone scripts.
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 May 07 against RequireJS `2.3.3`
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
The `r.js` optimizer does not support ES6 syntax including arrow functions and
 | 
			
		||||
the `async` keyword! The demo JS code uses traditional functions.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
0) Download the SheetJS Standalone script and move to the project directory:
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
1) Save the following to `index.html`:
 | 
			
		||||
 | 
			
		||||
```html title="index.html"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head></head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
/* Wire up RequireJS */
 | 
			
		||||
require.config({
 | 
			
		||||
  baseUrl: ".",
 | 
			
		||||
  name: "SheetJSRequire",
 | 
			
		||||
  paths: {
 | 
			
		||||
    xlsx: "./xlsx.full.min"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
    </script>
 | 
			
		||||
    <script src="SheetJSRequire.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Save the following to `SheetJSRequire.js`:
 | 
			
		||||
 | 
			
		||||
```js title="SheetJSRequire.js"
 | 
			
		||||
require(["xlsx"], function(XLSX) {
 | 
			
		||||
  document.getElementById("xport").addEventListener("click", function() {
 | 
			
		||||
    /* fetch JSON data and parse */
 | 
			
		||||
    var url = "https://sheetjs.com/data/executive.json";
 | 
			
		||||
    fetch(url).then(function(res) { return res.json(); }).then(function(raw_data) {
 | 
			
		||||
 | 
			
		||||
    /* filter for the Presidents */
 | 
			
		||||
    var prez = raw_data.filter(function(row) { return row.terms.some(function(term) { return term.type === "prez"; }); });
 | 
			
		||||
 | 
			
		||||
    /* flatten objects */
 | 
			
		||||
    var rows = prez.map(function(row) { return {
 | 
			
		||||
      name: row.name.first + " " + row.name.last,
 | 
			
		||||
      birthday: row.bio.birthday
 | 
			
		||||
    }; });
 | 
			
		||||
 | 
			
		||||
    /* generate worksheet and workbook */
 | 
			
		||||
    var worksheet = XLSX.utils.json_to_sheet(rows);
 | 
			
		||||
    var workbook = XLSX.utils.book_new();
 | 
			
		||||
    XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
 | 
			
		||||
 | 
			
		||||
    /* fix headers */
 | 
			
		||||
    XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
 | 
			
		||||
 | 
			
		||||
    /* calculate column width */
 | 
			
		||||
    var max_width = rows.reduce(function(w, r) { return Math.max(w, r.name.length); }, 10);
 | 
			
		||||
    worksheet["!cols"] = [ { wch: max_width } ];
 | 
			
		||||
 | 
			
		||||
    /* create an XLSX file and try to save to Presidents.xlsx */
 | 
			
		||||
    XLSX.writeFileXLSX(workbook, "Presidents.xlsx");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Start a local HTTP server, then go to `http://localhost:8080/`
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx http-server .
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Click on "Click here to export" to generate a file.
 | 
			
		||||
 | 
			
		||||
4) Create `build.js` configuration for the optimizer:
 | 
			
		||||
 | 
			
		||||
```js title="build.js"
 | 
			
		||||
({
 | 
			
		||||
  baseUrl: ".",
 | 
			
		||||
  name: "SheetJSRequire",
 | 
			
		||||
  paths: {
 | 
			
		||||
    xlsx: "./xlsx.full.min"
 | 
			
		||||
  },
 | 
			
		||||
  out: "SheetJSRequire.min.js"
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
5) Run the `r.js` optimizer to create `SheetJSRequire.min.js`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
npx -p requirejs@2.3.3 r.js -o build.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
6) Save the following to `optimized.html`:
 | 
			
		||||
 | 
			
		||||
```html title="optimized.html"
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
  <head></head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
 | 
			
		||||
    <script src="SheetJSRequire.min.js"></script>
 | 
			
		||||
  </body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
7) Open `http://localhost:8080/optimized.html`
 | 
			
		||||
 | 
			
		||||
Click on "Click here to export" to generate a file.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/requirejs)**
 | 
			
		||||
 | 
			
		||||
## Rollup
 | 
			
		||||
 | 
			
		||||
@ -978,206 +829,9 @@ Click on "Click here to export" to generate a file.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
 | 
			
		||||
## SystemJS
 | 
			
		||||
#### SystemJS
 | 
			
		||||
 | 
			
		||||
With configuration, SystemJS supports both browser and NodeJS deployments.
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
This demo was written against SystemJS 0.19, the most popular SystemJS version
 | 
			
		||||
used with Angular applications.  In the years since the release, Angular and
 | 
			
		||||
other tools using SystemJS have switched to Webpack.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
<Tabs>
 | 
			
		||||
  <TabItem value="browser" label="Browser">
 | 
			
		||||
 | 
			
		||||
SystemJS fails by default because the library does not export anything in the
 | 
			
		||||
web browser.  The `meta` configuration option can be used to expose `XLSX`:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="js">{`\
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
  meta: {
 | 
			
		||||
    'xlsx': {
 | 
			
		||||
      exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  map: {
 | 
			
		||||
    'xlsx': 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js',
 | 
			
		||||
    'fs': '',     // <--|
 | 
			
		||||
    'crypto': '', // <--| suppress native node modules
 | 
			
		||||
    'stream': ''  // <--|
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
SystemJS.import('main.js'); // load \`main.js\``}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
The `main.js` script can freely `require("xlsx")`.
 | 
			
		||||
 | 
			
		||||
:::caution Web Workers
 | 
			
		||||
 | 
			
		||||
Web Workers can load the SystemJS library with `importScripts`, but the imported
 | 
			
		||||
code cannot assign the original worker's `onmessage` callback.  The recommended
 | 
			
		||||
approach is to expose a global from the required script,  For example, supposing
 | 
			
		||||
the shared name is `_cb`, the primary worker script would call the callback:
 | 
			
		||||
 | 
			
		||||
```js title="worker.js"
 | 
			
		||||
/* main worker script */
 | 
			
		||||
importScripts('system.js');
 | 
			
		||||
 | 
			
		||||
SystemJS.config({ /* ... browser config ... */ });
 | 
			
		||||
 | 
			
		||||
onmessage = function(evt) {
 | 
			
		||||
  SystemJS.import('workermain.js').then(function() { _cb(evt); });
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The worker script would define and expose the function:
 | 
			
		||||
 | 
			
		||||
```js title="workermain.js"
 | 
			
		||||
/* Loaded with SystemJS import */
 | 
			
		||||
var XLSX = require('xlsx');
 | 
			
		||||
 | 
			
		||||
_cb = function(evt) { /* ... do work here ... */ };
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="nodejs" label="NodeJS">
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
While SystemJS works in NodeJS, the built-in `require` should be preferred.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
The NodeJS module main script is `xlsx/xlsx.js` and should be mapped:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
  map: {
 | 
			
		||||
    "xlsx": "./node_modules/xlsx/xlsx.js"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The standalone scripts require a hint that the script assigns a global:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
  meta: {
 | 
			
		||||
    "standalone": { format: "global" }
 | 
			
		||||
  },
 | 
			
		||||
  map: {
 | 
			
		||||
    "standalone": "xlsx.full.min.js"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
<Tabs>
 | 
			
		||||
  <TabItem value="browser" label="Browser">
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 May 07 against SystemJS 0.20.16
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
The [Live demo](pathname:///systemjs/systemjs.html) loads SystemJS from the
 | 
			
		||||
CDN, uses it to load the standalone script from the SheetJS CDN and emulate
 | 
			
		||||
a `require` implementation when loading [`main.js`](pathname:///systemjs/main.js)
 | 
			
		||||
 | 
			
		||||
"View Source" works on the main HTML page and the `main.js` script.
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="nodejs" label="NodeJS">
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 May 07 against SystemJS 0.19.47
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
1) Install the dependencies:
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
npm init -y
 | 
			
		||||
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz systemjs@0.19.47`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Save the following script to `SheetJSystem.js`:
 | 
			
		||||
 | 
			
		||||
```js title="SheetJSystem.js"
 | 
			
		||||
const SystemJS = require('systemjs');
 | 
			
		||||
 | 
			
		||||
// highlight-start
 | 
			
		||||
SystemJS.config({
 | 
			
		||||
  map: {
 | 
			
		||||
    'xlsx': 'node_modules/xlsx/xlsx.js',
 | 
			
		||||
    'fs': '@node/fs',
 | 
			
		||||
    'crypto': '@node/crypto',
 | 
			
		||||
    'stream': '@node/stream'
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
// highlight-end
 | 
			
		||||
 | 
			
		||||
SystemJS.import('xlsx').then(async function(XLSX) {
 | 
			
		||||
 | 
			
		||||
  /* fetch JSON data and parse */
 | 
			
		||||
  const url = "https://sheetjs.com/data/executive.json";
 | 
			
		||||
  const raw_data = await (await fetch(url)).json();
 | 
			
		||||
 | 
			
		||||
  /* filter for the Presidents */
 | 
			
		||||
  const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
 | 
			
		||||
 | 
			
		||||
  /* flatten objects */
 | 
			
		||||
  const rows = prez.map(row => ({
 | 
			
		||||
    name: row.name.first + " " + row.name.last,
 | 
			
		||||
    birthday: row.bio.birthday
 | 
			
		||||
  }));
 | 
			
		||||
 | 
			
		||||
  /* generate worksheet and workbook */
 | 
			
		||||
  const worksheet = XLSX.utils.json_to_sheet(rows);
 | 
			
		||||
  const workbook = XLSX.utils.book_new();
 | 
			
		||||
  XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
 | 
			
		||||
 | 
			
		||||
  /* fix headers */
 | 
			
		||||
  XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
 | 
			
		||||
 | 
			
		||||
  /* calculate column width */
 | 
			
		||||
  const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
 | 
			
		||||
  worksheet["!cols"] = [ { wch: max_width } ];
 | 
			
		||||
 | 
			
		||||
  /* create an XLSX file and try to save to Presidents.xlsx */
 | 
			
		||||
  XLSX.writeFile(workbook, "Presidents.xlsx");
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Run in NodeJS:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
node SheetJSystem.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If the demo worked, `Presidents.xlsx` will be created.
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
As it uses `fetch`, this demo requires Node 18.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
</Tabs>
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
**[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/systemjs)**
 | 
			
		||||
 | 
			
		||||
## Vite
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -258,7 +258,7 @@ This demo was tested in the following environments:
 | 
			
		||||
| OS and Version | Arch | Tauri    | Date       |
 | 
			
		||||
|:---------------|:-----|:---------|:-----------|
 | 
			
		||||
| macOS 13.5.1   | x64  | `v1.5.0` | 2023-09-30 |
 | 
			
		||||
| macOS 13.4.1   | ARM  | `v1.4.0` | 2023-06-29 |
 | 
			
		||||
| macOS 14.0     | ARM  | `v1.5.2` | 2023-10-18 |
 | 
			
		||||
| Windows 10     | x64  | `v1.5.0` | 2023-10-01 |
 | 
			
		||||
| Windows 11     | ARM  | `v1.4.1` | 2023-09-26 |
 | 
			
		||||
| Linux (HoloOS) | x64  | `v1.5.2` | 2023-10-11 |
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
---
 | 
			
		||||
title: NeutralinoJS
 | 
			
		||||
title: Data Munging in 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
 | 
			
		||||
@ -9,8 +9,6 @@ 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';
 | 
			
		||||
@ -195,7 +193,7 @@ This demo was tested in the following environments:
 | 
			
		||||
| OS and Version | Arch | Server    | Client    | Date       |
 | 
			
		||||
|:---------------|:-----|:----------|:----------|:-----------|
 | 
			
		||||
| macOS 13.5.1   | x64  | `v4.13.0` | `v3.11.0` | 2023-08-26 |
 | 
			
		||||
| macOS 13.4.1   | ARM  | `v4.10.0` | `v3.8.2`  | 2023-06-28 |
 | 
			
		||||
| macOS 14.0     | ARM  | `v4.14.1` | `v3.12.0` | 2023-10-18 |
 | 
			
		||||
| Windows 10     | x64  | `v4.13.0` | `v3.11.0` | 2023-08-26 |
 | 
			
		||||
| Windows 11     | ARM  | `v4.13.0` | `v3.11.0` | 2023-09-21 |
 | 
			
		||||
| Linux (HoloOS) | x64  | `v4.14.1` | `v3.12.0` | 2023-10-11 |
 | 
			
		||||
@ -385,7 +383,8 @@ save as `SheetJSNeu` will not automatically add the `.xlsx` extension!
 | 
			
		||||
npx @neutralinojs/neu build
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Platform-specific programs will be created in the `dist` folder.
 | 
			
		||||
Platform-specific programs will be created in the `dist` folder. For example,
 | 
			
		||||
the `darwin-arm` program will be `./dist/sheetjs-neu/sheetjs-neu-mac_arm64`
 | 
			
		||||
 | 
			
		||||
[^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
 | 
			
		||||
 | 
			
		||||
@ -240,7 +240,7 @@ This demo was last tested in the following deployments:
 | 
			
		||||
| Architecture | V8 Version    | Crate    | Date       |
 | 
			
		||||
|:-------------|:--------------|:---------|:-----------|
 | 
			
		||||
| `darwin-x64` | `11.8.172.13` | `0.79.2` | 2023-10-12 |
 | 
			
		||||
| `darwin-arm` | `11.4.183.2`  | `0.71.2` | 2023-05-22 |
 | 
			
		||||
| `darwin-arm` | `11.8.172.13` | `0.79.2` | 2023-10-18 |
 | 
			
		||||
| `win10-x64`  | `11.8.172.13` | `0.79.2` | 2023-10-09 |
 | 
			
		||||
| `win11-x64`  | `11.8.172.13` | `0.79.2` | 2023-10-14 |
 | 
			
		||||
| `linux-x64`  | `11.8.172.13` | `0.79.2` | 2023-10-11 |
 | 
			
		||||
@ -351,7 +351,7 @@ This demo was last tested in the following deployments:
 | 
			
		||||
| Architecture | Version  | Date       |
 | 
			
		||||
|:-------------|:---------|:-----------|
 | 
			
		||||
| `darwin-x64` | `1.37.1` | 2023-10-12 |
 | 
			
		||||
| `darwin-arm` | `1.34.1` | 2023-06-05 |
 | 
			
		||||
| `darwin-arm` | `1.37.2` | 2023-10-18 |
 | 
			
		||||
| `win10-x64`  | `1.37.1` | 2023-10-09 |
 | 
			
		||||
| `win11-x64`  | `1.37.2` | 2023-10-14 |
 | 
			
		||||
| `win11-arm`  | `1.37.0` | 2023-09-26 |
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,11 @@ production sites.
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 June 1 with `localForage` 1.10.0
 | 
			
		||||
This demo was last tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| Browser     | Date       | `localForage` |
 | 
			
		||||
|:------------|:-----------|:--------------|
 | 
			
		||||
| Chrome 117  | 2023-10-18 | 1.10.0        |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -106,7 +110,11 @@ function SheetJSLocalForage() {
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 June 1 with DexieJS 3.2.4
 | 
			
		||||
This demo was last tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| Browser     | Date       | DexieJS |
 | 
			
		||||
|:------------|:-----------|:--------|
 | 
			
		||||
| Chrome 117  | 2023-10-18 | 3.2.4   |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,10 +7,36 @@ pagination_next: demos/extensions/index
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
Deno Deploy offers "Serverless Functions" powered by Deno.
 | 
			
		||||
[Deno Deploy](https://dash.deno.com/) offers distributed "Serverless Functions"
 | 
			
		||||
powered by Deno.
 | 
			
		||||
 | 
			
		||||
The [Deno installation](/docs/getting-started/installation/deno) instructions
 | 
			
		||||
apply to Deno Deploy scripts.
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo covers integration details. We'll explore how to load and use SheetJS
 | 
			
		||||
scripts in Deno Deploy functions.
 | 
			
		||||
 | 
			
		||||
The ["Demo"](#demo) section includes build a sample service that converts XLSX
 | 
			
		||||
and other types of spreadsheets to HTML tables and CSV rows.
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
When the demo was last tested, Deno Deploy required a GitHub account.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
This demo was last tested by SheetJS users on 2023 October 18.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Integration Details
 | 
			
		||||
 | 
			
		||||
The [SheetJS Deno module](/docs/getting-started/installation/nodejs) can be
 | 
			
		||||
imported from Deno Deploy server scripts.
 | 
			
		||||
 | 
			
		||||
### Supported Frameworks
 | 
			
		||||
 | 
			
		||||
:::warning pass
 | 
			
		||||
 | 
			
		||||
@ -20,17 +46,11 @@ This breaks web frameworks that use the filesystem in body parsing.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
When the demo was last tested, Deno Deploy required a GitHub account.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Supported Frameworks
 | 
			
		||||
 | 
			
		||||
When the demo was last tested, the `drash` server framework used an in-memory
 | 
			
		||||
approach for parsing POST request bodies.
 | 
			
		||||
 | 
			
		||||
The [Drash demo](/docs/demos/net/server/drash) covers the framework in detail.
 | 
			
		||||
 | 
			
		||||
### Parsing Data
 | 
			
		||||
 | 
			
		||||
When files are submitted via HTTP POST, the `bodyParam` method can fetch data.
 | 
			
		||||
@ -41,7 +61,7 @@ The following example assumes the file is submitted at field name `file`:
 | 
			
		||||
<CodeBlock language="ts">{`\
 | 
			
		||||
// @deno-types="https://cdn.sheetjs.com/xlsx-${current}/package/types/index.d.ts"
 | 
			
		||||
import { read, utils } from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs';
 | 
			
		||||
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.0/mod.ts";
 | 
			
		||||
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.1/mod.ts";
 | 
			
		||||
\n\
 | 
			
		||||
class SheetJSResource extends Drash.Resource {
 | 
			
		||||
  public paths = ["/"];
 | 
			
		||||
@ -61,39 +81,43 @@ class SheetJSResource extends Drash.Resource {
 | 
			
		||||
 | 
			
		||||
## Demo
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
0) Create a new GitHub account or sign into an existing account.
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2023 June 05. The service <https://s2c.sheetjs.com>
 | 
			
		||||
was implemented using this exact sequence.
 | 
			
		||||
1) Open the [main Deno Deploy portal](https://dash.deno.com/) in a browser.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
2) If the account never signed into Deno Deploy, click "Continue with Github".
 | 
			
		||||
 | 
			
		||||
1) Register and Sign in.
 | 
			
		||||
In the next screen, review the prompt and click "Authorize Deno Deploy"
 | 
			
		||||
 | 
			
		||||
2) Click "New Project" to create a new Project. In the next screen, look for the
 | 
			
		||||
"Hello World" sample and click the corresponding "Fork" button.
 | 
			
		||||
3) Click "New Playground" to create a new Playground.
 | 
			
		||||
 | 
			
		||||
3) Download [`s2c.ts`](pathname:///deno/s2c.ts).  Open with a text editor and
 | 
			
		||||
copy the contents into the playground editor (left pane).
 | 
			
		||||
4) Download [`s2c.ts`](pathname:///deno/s2c.ts).
 | 
			
		||||
 | 
			
		||||
4) Click "Save and Deploy".
 | 
			
		||||
5) Open `s2c.ts` with a text editor and copy the contents of the source file
 | 
			
		||||
into the playground editor (left pane in the browser).
 | 
			
		||||
 | 
			
		||||
6) Click "Save and Deploy". When the demo was last tested, it was a blue button.
 | 
			
		||||
 | 
			
		||||
### Testing
 | 
			
		||||
 | 
			
		||||
5) Download the test file <https://sheetjs.com/pres.xlsx>
 | 
			
		||||
7) Wait until the server is deployed. When it is deployed, the right panel will
 | 
			
		||||
show "SheetJS Spreadsheet Conversion Service":
 | 
			
		||||
 | 
			
		||||
6) In the browser window, click "Choose File" and select the downloaded file.
 | 
			
		||||
Click "Submit" and the page will show the contents in a HTML TABLE.
 | 
			
		||||
> 
 | 
			
		||||
 | 
			
		||||
7) Click the "Fullscreen" icon in the top-right corner of the page window.
 | 
			
		||||
8) Download the test file <https://sheetjs.com/pres.xlsx>
 | 
			
		||||
 | 
			
		||||
8) Open a terminal window and download <https://sheetjs.com/pres.numbers>:
 | 
			
		||||
9) In the browser window, click "Choose File" and select the downloaded file.
 | 
			
		||||
 | 
			
		||||
10) Click "Submit". The right panel will show the contents in a HTML TABLE.
 | 
			
		||||
 | 
			
		||||
11) Open a terminal window and download <https://sheetjs.com/pres.numbers>:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://sheetjs.com/pres.numbers
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
9) Copy the first `curl` line from the page and run in the terminal. For
 | 
			
		||||
12) Copy the first `curl` line from the page and run in the terminal. For
 | 
			
		||||
example, if the deployment is `clean-badger-69`, the command would be
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
@ -102,7 +126,7 @@ curl -X POST -F"file=@pres.numbers" https://clean-badger-69.deno.dev/
 | 
			
		||||
 | 
			
		||||
The output will be an HTML table
 | 
			
		||||
 | 
			
		||||
10) Copy the second `curl` line from the page and run in the terminal. For
 | 
			
		||||
13) Copy the second `curl` line from the page and run in the terminal. For
 | 
			
		||||
example, if the deployment is `clean-badger-69`, the command would be
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
 | 
			
		||||
@ -120,7 +120,7 @@ This demo was tested in the following deployments:
 | 
			
		||||
| Architecture | Version | Date       |
 | 
			
		||||
|:-------------|:--------|:-----------|
 | 
			
		||||
| `darwin-x64` | `2.7.0` | 2023-07-24 |
 | 
			
		||||
| `darwin-arm` | `2.7.0` | 2023-06-05 |
 | 
			
		||||
| `darwin-arm` | `2.7.0` | 2023-10-18 |
 | 
			
		||||
| `win10-x64`  | `2.7.0` | 2023-07-24 |
 | 
			
		||||
| `win11-arm`  | `2.7.0` | 2023-09-26 |
 | 
			
		||||
| `linux-x64`  | `2.7.0` | 2023-10-11 |
 | 
			
		||||
@ -173,6 +173,20 @@ curl -LO https://docs.sheetjs.com/duk/sheetjs.duk.c
 | 
			
		||||
gcc -std=c99 -Wall -osheetjs.duk sheetjs.duk.c duktape.c -lm
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
 | 
			
		||||
GCC may generate a warning:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
duk_js_compiler.c:5628:13: warning: variable 'num_stmts' set but not used [-Wunused-but-set-variable]
 | 
			
		||||
                duk_int_t num_stmts;
 | 
			
		||||
                          ^
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This warning can be ignored.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
  </TabItem>
 | 
			
		||||
  <TabItem value="win" label="Windows">
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -808,7 +808,7 @@ This demo was last tested in the following deployments:
 | 
			
		||||
| Architecture | V8 Crate | Date       |
 | 
			
		||||
|:-------------|:---------|:-----------|
 | 
			
		||||
| `darwin-x64` | `0.75.1` | 2023-08-26 |
 | 
			
		||||
| `darwin-arm` | `0.73.0` | 2023-06-05 |
 | 
			
		||||
| `darwin-arm` | `0.79.2` | 2023-10-18 |
 | 
			
		||||
| `win10-x64`  | `0.79.2` | 2023-10-09 |
 | 
			
		||||
| `linux-x64`  | `0.79.2` | 2023-10-11 |
 | 
			
		||||
| `linux-arm`  | `0.75.1` | 2023-08-30 |
 | 
			
		||||
 | 
			
		||||
@ -134,7 +134,7 @@ This demo was tested in the following environments:
 | 
			
		||||
| Architecture | Swift   | Date       |
 | 
			
		||||
|:-------------|:--------|:-----------|
 | 
			
		||||
| `darwin-x64` | `5.8.1` | 2023-07-24 |
 | 
			
		||||
| `darwin-arm` | `5.8.1` | 2023-06-05 |
 | 
			
		||||
| `darwin-arm` | `5.9.0` | 2023-10-18 |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -95,7 +95,7 @@ This demo was tested in the following deployments:
 | 
			
		||||
| Architecture | Git Commit | Go version | Date       |
 | 
			
		||||
|:-------------|:-----------|:-----------|:-----------|
 | 
			
		||||
| `darwin-x64` | `873a149`  | `1.21.3`   | 2023-10-14 |
 | 
			
		||||
| `darwin-arm` | `28ee0ee`  | `1.20.4`   | 2023-06-05 |
 | 
			
		||||
| `darwin-arm` | `873a149`  | `1.21.3`   | 2023-10-18 |
 | 
			
		||||
| `win10-x64`  | `81d7606`  | `1.20.2`   | 2023-08-27 |
 | 
			
		||||
| `win11-arm`  | `fc55792`  | `1.21.1`   | 2023-09-25 |
 | 
			
		||||
| `linux-x64`  | `fc55792`  | `1.21.3`   | 2023-10-11 |
 | 
			
		||||
 | 
			
		||||
@ -263,7 +263,7 @@ This demo was tested in the following deployments:
 | 
			
		||||
| Architecture | Git Commit | Date       |
 | 
			
		||||
|:-------------|:-----------|:-----------|
 | 
			
		||||
| `darwin-x64` | `2788d71`  | 2023-07-24 |
 | 
			
		||||
| `darwin-arm` | `2788d71`  | 2023-06-05 |
 | 
			
		||||
| `darwin-arm` | `2788d71`  | 2023-10-18 |
 | 
			
		||||
| `win10-x64`  | `2788d71`  | 2023-10-09 |
 | 
			
		||||
| `win11-arm`  | `2788d71`  | 2023-09-25 |
 | 
			
		||||
| `linux-x64`  | `2788d71`  | 2023-10-11 |
 | 
			
		||||
 | 
			
		||||
@ -363,7 +363,7 @@ This demo was tested in the following deployments:
 | 
			
		||||
| Architecture | Git Commit | Date       |
 | 
			
		||||
|:-------------|:-----------|:-----------|
 | 
			
		||||
| `darwin-x64` | `70af78b`  | 2023-08-27 |
 | 
			
		||||
| `darwin-arm` | `869312f`  | 2023-06-05 |
 | 
			
		||||
| `darwin-arm` | `2b4f949`  | 2023-10-18 |
 | 
			
		||||
| `linux-x64`  | `2b4f949`  | 2023-10-11 |
 | 
			
		||||
| `linux-arm`  | `70af78b`  | 2023-08-27 |
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -120,11 +120,11 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
 | 
			
		||||
- [`bun`](/docs/demos/frontend/bundler#bun)
 | 
			
		||||
- [`esbuild`](/docs/demos/frontend/bundler#esbuild)
 | 
			
		||||
- [`parcel`](/docs/demos/frontend/bundler#parcel)
 | 
			
		||||
- [`requirejs`](/docs/demos/frontend/bundler#requirejs)
 | 
			
		||||
- [`requirejs`](/docs/demos/frontend/bundler/requirejs)
 | 
			
		||||
- [`rollup`](/docs/demos/frontend/bundler#rollup)
 | 
			
		||||
- [`snowpack`](/docs/demos/frontend/bundler#snowpack)
 | 
			
		||||
- [`swc`](/docs/demos/frontend/bundler#swc)
 | 
			
		||||
- [`systemjs`](/docs/demos/frontend/bundler#systemjs)
 | 
			
		||||
- [`systemjs`](/docs/demos/frontend/bundler/systemjs)
 | 
			
		||||
- [`vite`](/docs/demos/frontend/bundler#vite)
 | 
			
		||||
- [`webpack`](/docs/demos/frontend/bundler/webpack)
 | 
			
		||||
- [`wmr`](/docs/demos/frontend/bundler#wmr)
 | 
			
		||||
@ -132,6 +132,7 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
 | 
			
		||||
### Other Programming Languages
 | 
			
		||||
 | 
			
		||||
- [`JavaScript Engines`](/docs/demos/engines)
 | 
			
		||||
- [`V8 (C++ / Rust)`](/docs/demos/engines/v8)
 | 
			
		||||
- [`Duktape (C / Perl)`](/docs/demos/engines/duktape)
 | 
			
		||||
- [`JavaScriptCore (Swift)`](/docs/demos/engines/jsc)
 | 
			
		||||
- [`Rhino (Java)`](/docs/demos/engines/rhino)
 | 
			
		||||
 | 
			
		||||
@ -344,7 +344,7 @@ import * as XLSX from 'https://cdn.sheetjs.com/xlsx-${current}/package/xlsx.mjs'
 | 
			
		||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-${current}/package/dist/cpexcel.full.mjs';
 | 
			
		||||
XLSX.set_cptable(cptable);
 | 
			
		||||
\n\
 | 
			
		||||
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.0/mod.ts";
 | 
			
		||||
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.1/mod.ts";
 | 
			
		||||
\n\
 | 
			
		||||
class SheetResource extends Drash.Resource {
 | 
			
		||||
  public paths = ["/"];
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@ import { read, utils, set_cptable, version } from 'https://cdn.sheetjs.com/xlsx-
 | 
			
		||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.20.0/package/dist/cpexcel.full.mjs';
 | 
			
		||||
set_cptable(cptable);
 | 
			
		||||
 | 
			
		||||
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.0/mod.ts";
 | 
			
		||||
import * as Drash from "https://cdn.jsdelivr.net/gh/drashland/drash@v2.8.1/mod.ts";
 | 
			
		||||
 | 
			
		||||
class SheetJSResource extends Drash.Resource {
 | 
			
		||||
  public paths = ["/"];
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docz/static/deno/sshot.png
									
									
									
									
									
										Normal file
									
								
							
							
								
									
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								docz/static/deno/sshot.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 170 KiB  | 
@ -4,7 +4,7 @@
 | 
			
		||||
  <body>
 | 
			
		||||
    <h1>SheetJS Presidents Demo</h1>
 | 
			
		||||
    <button id="xport">Click here to export</button>
 | 
			
		||||
    <script src="http://requirejs.org/docs/release/2.3.3/comments/require.js"></script>
 | 
			
		||||
    <script src="http://requirejs.org/docs/release/2.3.6/comments/require.js"></script>
 | 
			
		||||
    <script>
 | 
			
		||||
/* Wire up RequireJS */
 | 
			
		||||
require.config({
 | 
			
		||||
@ -14,7 +14,7 @@ require.config({
 | 
			
		||||
    xlsx: "https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min"
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
require(["xlsx"], function(XLSX) {
 | 
			
		||||
require(["xlsx"], function(_XLSX) {
 | 
			
		||||
  document.getElementById("xport").addEventListener("click", async() => {
 | 
			
		||||
    /* fetch JSON data and parse */
 | 
			
		||||
    const url = "https://sheetjs.com/data/executive.json";
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								docz/static/systemjs/SheetJSystem.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										55
									
								
								docz/static/systemjs/SheetJSystem.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,55 @@
 | 
			
		||||
const SystemJS = require('systemjs');
 | 
			
		||||
 | 
			
		||||
/* old SystemJS behavior */
 | 
			
		||||
if(typeof SystemJS.config != "undefined") SystemJS.config({ map: {
 | 
			
		||||
  'xlsx': 'node_modules/xlsx/xlsx.js',
 | 
			
		||||
  'fs': '@node/fs',
 | 
			
		||||
  'crypto': '@node/crypto',
 | 
			
		||||
  'stream': '@empty'
 | 
			
		||||
} });
 | 
			
		||||
/* new SystemJS behavior */
 | 
			
		||||
else SystemJS.applyImportMap(SystemJS.System, {
 | 
			
		||||
  imports: {
 | 
			
		||||
    'xlsx': "file://" + require("path").join(process.cwd(), 'node_modules/xlsx/xlsx.js'),
 | 
			
		||||
    'fs': 'node:fs',
 | 
			
		||||
    'crypto': 'node:crypto',
 | 
			
		||||
    'stream': 'node:stream'
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
(typeof SystemJS.System != "undefined" ? SystemJS.System : SystemJS).import('xlsx').then(async function(_XLSX) {
 | 
			
		||||
  if(typeof XLSX == "undefined") XLSX = _XLSX;
 | 
			
		||||
  /* fetch JSON data and parse */
 | 
			
		||||
  const url = "https://sheetjs.com/data/executive.json";
 | 
			
		||||
  const raw_data = await (await fetch(url)).json();
 | 
			
		||||
 | 
			
		||||
  /* filter for the Presidents */
 | 
			
		||||
  const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
 | 
			
		||||
 | 
			
		||||
  /* sort by first presidential term */
 | 
			
		||||
  prez.forEach(row => row.start = row.terms.find(term => term.type === "prez").start);
 | 
			
		||||
  prez.sort((l,r) => l.start.localeCompare(r.start));
 | 
			
		||||
 | 
			
		||||
  /* flatten objects */
 | 
			
		||||
  const rows = prez.map(row => ({
 | 
			
		||||
    name: row.name.first + " " + row.name.last,
 | 
			
		||||
    birthday: row.bio.birthday
 | 
			
		||||
  }));
 | 
			
		||||
 | 
			
		||||
  /* generate worksheet and workbook */
 | 
			
		||||
  const worksheet = XLSX.utils.json_to_sheet(rows);
 | 
			
		||||
  const workbook = XLSX.utils.book_new();
 | 
			
		||||
  XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
 | 
			
		||||
 | 
			
		||||
  /* fix headers */
 | 
			
		||||
  XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
 | 
			
		||||
 | 
			
		||||
  /* calculate column width */
 | 
			
		||||
  const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
 | 
			
		||||
  worksheet["!cols"] = [ { wch: max_width } ];
 | 
			
		||||
 | 
			
		||||
  /* create an XLSX file and try to save to Presidents.xlsx */
 | 
			
		||||
  if(typeof XLSX.set_fs != "undefined") XLSX.set_fs(require("fs"));
 | 
			
		||||
  XLSX.writeFile(workbook, "Presidents.xlsx");
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user