forked from sheetjs/docs.sheetjs.com
		
	chakra-hb
This commit is contained in:
		
							parent
							
								
									2505d3b639
								
							
						
					
					
						commit
						3ab0c1ab67
					
				
							
								
								
									
										217
									
								
								docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										217
									
								
								docz/docs/03-demos/01-frontend/19-bundler/04-esbuild.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,217 @@ | ||||
| --- | ||||
| title: Bundling Sheets with ESBuild | ||||
| sidebar_label: ESBuild | ||||
| pagination_prev: demos/index | ||||
| pagination_next: demos/grid/index | ||||
| sidebar_position: 4 | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import Tabs from '@theme/Tabs'; | ||||
| import TabItem from '@theme/TabItem'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| [ESBuild](https://esbuild.github.io/) is a fast module bundler for JavaScript. | ||||
| It combines scripts and libraries into simple scripts for browsers and NodeJS. | ||||
| 
 | ||||
| [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing | ||||
| data from spreadsheets. | ||||
| 
 | ||||
| This demo uses ESBuild and SheetJS to export data. We'll explore two workflows: | ||||
| 
 | ||||
| - ["Browser"](#browser) explores how to import SheetJS libraries in a script and | ||||
| bundle with ESBuild for browser use. | ||||
| 
 | ||||
| - ["NodeJS"](#nodejs) explores how to import SheetJS libraries in a script and | ||||
| bundle with ESBuild for NodeJS use. | ||||
| 
 | ||||
| :::info pass | ||||
| 
 | ||||
| This demo focuses on integration details with the ESBuild bundler. | ||||
| 
 | ||||
| The demos follow the ["Export Tutorial"](/docs/getting-started/examples/export). | ||||
| The tutorial covers SheetJS library usage. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 October 19 against esbuild `0.19.5` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## Integration Details | ||||
| 
 | ||||
| [The "Frameworks" section](/docs/getting-started/installation/frameworks) covers | ||||
| installation with Yarn and other package managers. | ||||
| 
 | ||||
| ## Browser | ||||
| 
 | ||||
| ESBuild will bundle the SheetJS ECMAScript Module build: | ||||
| 
 | ||||
| ```js | ||||
| import { read, utils, writeFileXLSX } from 'xlsx'; | ||||
| ``` | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| The `xlsx.mjs` source file uses a subset of ES6 that `esbuild` understands and | ||||
| is able to transpile for older browsers. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Assuming the primary source file is `in.js`, the following command will bundle | ||||
| the script and generate `out.js`: | ||||
| 
 | ||||
| ```bash | ||||
| npx -y esbuild@0.19.5 in.js --bundle --outfile=out.js | ||||
| ``` | ||||
| 
 | ||||
| ### Browser Demo | ||||
| 
 | ||||
| 0) Prepare a blank project: | ||||
| 
 | ||||
| ```bash | ||||
| mkdir sheetjs-esbrowser | ||||
| cd sheetjs-esbrowser | ||||
| npm init -y | ||||
| ``` | ||||
| 
 | ||||
| 1) Install the tarball using a package manager: | ||||
| 
 | ||||
| <Tabs groupId="pm"> | ||||
|   <TabItem value="npm" label="npm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="pnpm" label="pnpm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="yarn" label="Yarn" default> | ||||
| <CodeBlock language="bash">{`\ | ||||
| yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 2) Download [`esbrowser.js`](pathname:///esbuild/esbrowser.js) and move to the | ||||
| project folder: | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://docs.sheetjs.com/esbuild/esbrowser.js | ||||
| ``` | ||||
| 
 | ||||
| 3) Create a small HTML page that loads the script.  Save to `index.html`: | ||||
| 
 | ||||
| ```html title="index.html" | ||||
| <body><script src="esb.browser.js"></script></body> | ||||
| ``` | ||||
| 
 | ||||
| 4) Create bundle: | ||||
| 
 | ||||
| ```bash | ||||
| npx -y esbuild@0.19.5 esbrowser.js --bundle --outfile=esb.browser.js | ||||
| ``` | ||||
| 
 | ||||
| 5) Start a local HTTP server: | ||||
| 
 | ||||
| ```bash | ||||
| npx http-server . | ||||
| ``` | ||||
| 
 | ||||
| Access the displayed URL (typically `http://localhost:8080`) with a web browser. | ||||
| It should attempt to download `Presidents.xlsx` | ||||
| 
 | ||||
| ## NodeJS | ||||
| 
 | ||||
| ESBuild will bundle the SheetJS ECMAScript Module build: | ||||
| 
 | ||||
| ```js | ||||
| import { read, utils, write } from 'xlsx'; | ||||
| ``` | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| To read and write files on the local filesystem using the SheetJS `readFile` and | ||||
| `writeFile` methods[^1], the `fs` module must be manually added: | ||||
| 
 | ||||
| ```js | ||||
| import { set_fs, readFile } from 'xlsx'; | ||||
| import * as fs from 'fs'; | ||||
| set_fs(fs); | ||||
| 
 | ||||
| /* read pres.numbers in the same directory as the script */ | ||||
| const wb = readFile("pres.numbers"); | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Assuming the primary source file is `in.js`, the following command will bundle | ||||
| the script for NodeJS and generate `out.js`: | ||||
| 
 | ||||
| ```bash | ||||
| npx -y esbuild@0.19.5 in.js --bundle --platform=node --outfile=out.js | ||||
| ``` | ||||
| 
 | ||||
| ### NodeJS Demo | ||||
| 
 | ||||
| :::info pass | ||||
| 
 | ||||
| This demo script uses `fetch` and requires Node 18+. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 0) Prepare a blank project: | ||||
| 
 | ||||
| ```bash | ||||
| mkdir sheetjs-esbnode | ||||
| cd sheetjs-esbnode | ||||
| npm init -y | ||||
| ``` | ||||
| 
 | ||||
| 1) Install the tarball using a package manager: | ||||
| 
 | ||||
| <Tabs groupId="pm"> | ||||
|   <TabItem value="npm" label="npm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="pnpm" label="pnpm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="yarn" label="Yarn" default> | ||||
| <CodeBlock language="bash">{`\ | ||||
| yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 2) Download [`esbnode.js`](pathname:///esbuild/esbnode.js) and move to the | ||||
| project folder: | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://docs.sheetjs.com/esbuild/esbnode.js | ||||
| ``` | ||||
| 
 | ||||
| 3) Create bundle: | ||||
| 
 | ||||
| ```bash | ||||
| npx -y esbuild@0.19.5 esbnode.js --bundle --platform=node --outfile=esb.node.js | ||||
| ``` | ||||
| 
 | ||||
| 4) Run the bundle: | ||||
| 
 | ||||
| ```bash | ||||
| node esb.node.js | ||||
| ``` | ||||
| 
 | ||||
| The process will generate `Presidents.xlsx` in the project directory. Open the | ||||
| file in a spreadsheet editor. | ||||
| 
 | ||||
| [^1]: The SheetJS [`readFile`](/docs/api/parse-options) and [`writeFile`](/docs/api/write-options) methods use the NodeJS `fs` module when available. It is not automatically loaded in the ECMAScript Module builds. | ||||
| @ -111,7 +111,9 @@ _cb = function(evt) { /* ... do work here ... */ }; | ||||
| 
 | ||||
| :::caution pass | ||||
| 
 | ||||
| While SystemJS works in NodeJS, the built-in `require` should be preferred. | ||||
| **It is strongly recommended to use the NodeJS `require` method when possible.** | ||||
| 
 | ||||
| This demo is relevant for legacy projects that use the SystemJS NodeJS loader. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
|  | ||||
| @ -209,187 +209,9 @@ Integration details are included [in the "AMD" installation](/docs/getting-start | ||||
| 
 | ||||
| Complete Examples are included [in the "Dojo" demo](/docs/demos/frontend/legacy#dojo-toolkit) | ||||
| 
 | ||||
| #### esbuild | ||||
| 
 | ||||
| ## esbuild | ||||
| 
 | ||||
| The `xlsx.mjs` source file uses a subset of ES6 that `esbuild` understands and | ||||
| is able to transpile for older browsers. | ||||
| 
 | ||||
| Both the `node` and `browser` platforms work out of the box. | ||||
| 
 | ||||
| <details><summary><b>Complete Example</b> (click to show)</summary> | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 May 07 against esbuild `0.17.18` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| <Tabs> | ||||
|   <TabItem value="browser" label="Browser"> | ||||
| 
 | ||||
| 1) Install the tarball using a package manager: | ||||
| 
 | ||||
| <Tabs groupId="pm"> | ||||
|   <TabItem value="npm" label="npm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="pnpm" label="pnpm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="yarn" label="Yarn" default> | ||||
| <CodeBlock language="bash">{`\ | ||||
| yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 2) Save the following to `esbrowser.js`: | ||||
| 
 | ||||
| ```js title="esbrowser.js" | ||||
| // highlight-next-line | ||||
| import { utils, version, writeFileXLSX } from 'xlsx'; | ||||
| 
 | ||||
| (async() => { | ||||
| /* 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 = utils.json_to_sheet(rows); | ||||
| const workbook = utils.book_new(); | ||||
| utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
| /* fix headers */ | ||||
| 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 */ | ||||
| writeFileXLSX(workbook, "Presidents.xlsx"); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| 3) Create a small HTML page that loads the script.  Save to `index.html`: | ||||
| 
 | ||||
| ```html title="index.html" | ||||
| <body><script src="esb.browser.js"></script></body> | ||||
| ``` | ||||
| 
 | ||||
| 4) Create bundle: | ||||
| 
 | ||||
| ```bash | ||||
| npx esbuild@0.17.18 esbrowser.js --bundle --outfile=esb.browser.js | ||||
| ``` | ||||
| 
 | ||||
| 5) Start a local HTTP server, then go to `http://localhost:8080/` | ||||
| 
 | ||||
| ```bash | ||||
| npx http-server . | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
|   <TabItem value="nodejs" label="NodeJS"> | ||||
| 
 | ||||
| 1) Install the tarball using a package manager: | ||||
| 
 | ||||
| <Tabs groupId="pm"> | ||||
|   <TabItem value="npm" label="npm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="pnpm" label="pnpm"> | ||||
| <CodeBlock language="bash">{`\ | ||||
| pnpm install https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
|   <TabItem value="yarn" label="Yarn" default> | ||||
| <CodeBlock language="bash">{`\ | ||||
| yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | ||||
| </CodeBlock> | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| 2) Save the following to `esbnode.js`: | ||||
| 
 | ||||
| ```js title="esbnode.js" | ||||
| // highlight-next-line | ||||
| import { set_fs, utils, version, writeFile } from 'xlsx'; | ||||
| // highlight-next-line | ||||
| import * as fs from 'fs'; | ||||
| // highlight-next-line | ||||
| set_fs(fs); | ||||
| 
 | ||||
| (async() => { | ||||
| /* 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 = utils.json_to_sheet(rows); | ||||
| const workbook = utils.book_new(); | ||||
| utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
| /* fix headers */ | ||||
| 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 */ | ||||
| writeFile(workbook, "Presidents.xlsx"); | ||||
| })(); | ||||
| ``` | ||||
| 
 | ||||
| 3) Create bundle: | ||||
| 
 | ||||
| ```bash | ||||
| npx esbuild@0.17.18 esbnode.js --bundle --platform=node --outfile=esb.node.js | ||||
| ``` | ||||
| 
 | ||||
| 4) Run the bundle: | ||||
| 
 | ||||
| ```bash | ||||
| node esb.node.js | ||||
| ``` | ||||
| 
 | ||||
|   </TabItem> | ||||
| </Tabs> | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| :::note pass | ||||
| 
 | ||||
| Bundling raw data is supported using the `binary` loader. For more advanced | ||||
| content workflows, [ViteJS](/docs/demos/static/vitejs) is the recommended tool. | ||||
| 
 | ||||
| ::: | ||||
| **[The exposition has been moved to a separate page.](/docs/demos/frontend/bundler/esbuild)** | ||||
| 
 | ||||
| ## Parcel | ||||
| 
 | ||||
|  | ||||
| @ -121,7 +121,7 @@ This demo was tested in the following deployments: | ||||
| | Architecture | Git Commit | Date       | | ||||
| |:-------------|:-----------|:-----------| | ||||
| | `darwin-x64` | `c3ead3f`  | 2023-08-26 | | ||||
| | `darwin-arm` | `c3ead3f`  | 2023-08-26 | | ||||
| | `darwin-arm` | `c3ead3f`  | 2023-10-19 | | ||||
| | `win10-x64`  | `c3ead3f`  | 2023-08-26 | | ||||
| | `linux-x64`  | `c3ead3f`  | 2023-10-11 | | ||||
| 
 | ||||
| @ -308,10 +308,9 @@ clang: error: no such file or directory: '/usr/local/opt/icu4c/lib/libicudata.a' | ||||
| This was fixed by creating a symbolic link: | ||||
| 
 | ||||
| ```bash | ||||
| cd /usr/local | ||||
| sudo mkdir -p opt | ||||
| cd opt | ||||
| sudo ln -s /opt/homebrew/opt/icu4c | ||||
| sudo mkdir -p /usr/local/opt | ||||
| sudo ln -s /opt/homebrew/opt/icu4c /usr/local/opt | ||||
| make | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
|  | ||||
| @ -118,7 +118,7 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues) | ||||
| 
 | ||||
| - [`browserify`](/docs/demos/frontend/bundler#browserify) | ||||
| - [`bun`](/docs/demos/frontend/bundler#bun) | ||||
| - [`esbuild`](/docs/demos/frontend/bundler#esbuild) | ||||
| - [`esbuild`](/docs/demos/frontend/bundler/esbuild) | ||||
| - [`parcel`](/docs/demos/frontend/bundler#parcel) | ||||
| - [`requirejs`](/docs/demos/frontend/bundler/requirejs) | ||||
| - [`rollup`](/docs/demos/frontend/bundler#rollup) | ||||
|  | ||||
							
								
								
									
										37
									
								
								docz/static/esbuild/esbnode.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										37
									
								
								docz/static/esbuild/esbnode.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| import { set_fs, utils, writeFile } from 'xlsx'; | ||||
| import * as fs from 'fs'; | ||||
| set_fs(fs); | ||||
| 
 | ||||
| (async() => { | ||||
| /* 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 = utils.json_to_sheet(rows); | ||||
| const workbook = utils.book_new(); | ||||
| utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
| /* fix headers */ | ||||
| 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 */ | ||||
| writeFile(workbook, "Presidents.xlsx"); | ||||
| })(); | ||||
							
								
								
									
										35
									
								
								docz/static/esbuild/esbrowser.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										35
									
								
								docz/static/esbuild/esbrowser.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| import { utils, writeFileXLSX } from 'xlsx'; | ||||
| 
 | ||||
| (async() => { | ||||
| /* 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 = utils.json_to_sheet(rows); | ||||
| const workbook = utils.book_new(); | ||||
| utils.book_append_sheet(workbook, worksheet, "Dates"); | ||||
| 
 | ||||
| /* fix headers */ | ||||
| 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 */ | ||||
| writeFileXLSX(workbook, "Presidents.xlsx"); | ||||
| })(); | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user