forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			375 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			375 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								sidebar_position: 3
							 | 
						||
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								# Complete Example
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SheetJS presents a simple JS interface that works with "Array of Arrays" and
							 | 
						||
| 
								 | 
							
								"Array of JS Objects".  The API functions are building blocks that should be
							 | 
						||
| 
								 | 
							
								combined with other JS APIs to solve problems.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The discussion focuses on the problem solving mindset.  API details are covered
							 | 
						||
| 
								 | 
							
								in other parts of the documentation.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The goal of this example is to generate a XLSB workbook of US President names
							 | 
						||
| 
								 | 
							
								and birthdays.  [Click here](#live-demo) to jump to the live demo
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Acquire Data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Raw Data
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[The raw data is available in JSON form](https://theunitedstates.io/congress-legislators/executive.json).
							 | 
						||
| 
								 | 
							
								For convenience, it has been [mirrored here](https://sheetjs.com/executive.json)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The data result is an Array of objects.  This is the data for John Adams:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  "id": { /* (data omitted) */ },
							 | 
						||
| 
								 | 
							
								  "name": {
							 | 
						||
| 
								 | 
							
								    "first": "John",          // <-- first name
							 | 
						||
| 
								 | 
							
								    "last": "Adams"           // <-- last name
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  "bio": {
							 | 
						||
| 
								 | 
							
								    "birthday": "1735-10-19", // <-- birthday
							 | 
						||
| 
								 | 
							
								    "gender": "M"
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  "terms": [
							 | 
						||
| 
								 | 
							
								    { "type": "viceprez", /* (other fields omitted) */ },
							 | 
						||
| 
								 | 
							
								    { "type": "viceprez", /* (other fields omitted) */ },
							 | 
						||
| 
								 | 
							
								    { "type": "prez", /* (other fields omitted) */ }
							 | 
						||
| 
								 | 
							
								  ]
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Filtering for Presidents
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The dataset includes Aaron Burr, a Vice President who was never President!
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`Array#filter` creates a new array with the desired rows.  A President served
							 | 
						||
| 
								 | 
							
								at least one term with `type` set to `"prez"`.  To test if a particular row has
							 | 
						||
| 
								 | 
							
								at least one `"prez"` term, `Array#some` is another native JS function.  The
							 | 
						||
| 
								 | 
							
								complete filter would be:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const prez = raw_data.filter(row => row.terms.some(term => term.type === "prez"));
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Reshaping the Array
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For this example, the name will be the first name combined with the last name
							 | 
						||
| 
								 | 
							
								(`row.name.first + " " + row.name.last`) and the birthday will be the subfield
							 | 
						||
| 
								 | 
							
								`row.bio.birthday`.  Using `Array#map`, the dataset can be massaged in one call:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const rows = prez.map(row => ({
							 | 
						||
| 
								 | 
							
								  name: row.name.first + " " + row.name.last,
							 | 
						||
| 
								 | 
							
								  birthday: row.bio.birthday
							 | 
						||
| 
								 | 
							
								}));
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The result is an array of "simple" objects with no nesting:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								[
							 | 
						||
| 
								 | 
							
								  { name: "George Washington", birthday: "1732-02-22" },
							 | 
						||
| 
								 | 
							
								  { name: "John Adams", birthday: "1735-10-19" },
							 | 
						||
| 
								 | 
							
								  // ... one row per President
							 | 
						||
| 
								 | 
							
								]
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Create a Workbook
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								With the cleaned dataset, `XLSX.utils.json_to_sheet` generates a worksheet:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const worksheet = XLSX.utils.json_to_sheet(rows);
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`XLSX.utils.book_new` creates a new workbook and `XLSX.utils.book_append_sheet`
							 | 
						||
| 
								 | 
							
								appends a worksheet to the workbook. The new worksheet will be called "Dates":
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const workbook = XLSX.utils.book_new();
							 | 
						||
| 
								 | 
							
								XLSX.utils.book_append_sheet(workbook, worksheet, "Dates");
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Clean up Workbook
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The data is in the workbook and can be exported.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								There are multiple opportunities for improvement: the headers can be renamed and
							 | 
						||
| 
								 | 
							
								the column widths can be adjusted.  [SheetJS Pro](https://sheetjs.com/pro) offers
							 | 
						||
| 
								 | 
							
								additional styling options like cell styling and frozen rows.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Changing Header Names</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								By default, `json_to_sheet` creates a worksheet with a header row. In this case,
							 | 
						||
| 
								 | 
							
								the headers come from the JS object keys: "name" and "birthday".
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The headers are in cells A1 and B1.  `XLSX.utils.sheet_add_aoa` can write text
							 | 
						||
| 
								 | 
							
								values to the existing worksheet starting at cell A1:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								XLSX.utils.sheet_add_aoa(worksheet, [["Name", "Birthday"]], { origin: "A1" });
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Changing Column Widths</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Some of the names are longer than the default column width.  Column widths are
							 | 
						||
| 
								 | 
							
								set by setting the `"!cols"` worksheet property.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The following line sets the width of column A to approximately 10 characters:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								worksheet["!cols"] = [ { wch: 10 } ]; // set column A width to 10 characters
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								One `Array#reduce` call over `rows` can calculate the maximum width:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const max_width = rows.reduce((w, r) => Math.max(w, r.name.length), 10);
							 | 
						||
| 
								 | 
							
								worksheet["!cols"] = [ { wch: max_width } ];
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Export a File
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`XLSX.writeFile` creates a spreadsheet file and tries to write it to the system.
							 | 
						||
| 
								 | 
							
								In the browser, it will try to prompt the user to download the file.  In NodeJS,
							 | 
						||
| 
								 | 
							
								it will write to the local directory.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								XLSX.writeFile(workbook, "Presidents.xlsb");
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Live Demo
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```jsx live
							 | 
						||
| 
								 | 
							
								function Presidents() { return ( <button onClick={async () => {
							 | 
						||
| 
								 | 
							
								  /* fetch JSON data and parse */
							 | 
						||
| 
								 | 
							
								  const url = "https://sheetjs.com/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.xlsb */
							 | 
						||
| 
								 | 
							
								  XLSX.writeFile(workbook, "Presidents.xlsb");
							 | 
						||
| 
								 | 
							
								}}><b>Click to Generate file!</b></button> ); }
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Run the Demo Locally
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import Tabs from '@theme/Tabs';
							 | 
						||
| 
								 | 
							
								import TabItem from '@theme/TabItem';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<Tabs>
							 | 
						||
| 
								 | 
							
								  <TabItem value="browser" label="Browser">
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Save the following script to `snippet.html` and open the page.  The page must be
							 | 
						||
| 
								 | 
							
								hosted (no `file:///` access).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<https://sheetjs.com/pres.html> is a hosted version of the page.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```html
							 | 
						||
| 
								 | 
							
								<body>
							 | 
						||
| 
								 | 
							
								<script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
							 | 
						||
| 
								 | 
							
								<script>
							 | 
						||
| 
								 | 
							
								(async() => {
							 | 
						||
| 
								 | 
							
								  /* fetch JSON data and parse */
							 | 
						||
| 
								 | 
							
								  const url = "https://sheetjs.com/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.xlsb */
							 | 
						||
| 
								 | 
							
								  XLSX.writeFile(workbook, "Presidents.xlsb");
							 | 
						||
| 
								 | 
							
								})();
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								<body>
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								  </TabItem>
							 | 
						||
| 
								 | 
							
								  <TabItem value="nodejs" label="NodeJS">
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Install the dependencies:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```bash
							 | 
						||
| 
								 | 
							
								$ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Save the following script to `snippet.js` and run `node snippet.js`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(async() => {
							 | 
						||
| 
								 | 
							
								  /* fetch JSON data and parse */
							 | 
						||
| 
								 | 
							
								  const url = "https://sheetjs.com/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.xlsb */
							 | 
						||
| 
								 | 
							
								  XLSX.writeFile(workbook, "Presidents.xlsb");
							 | 
						||
| 
								 | 
							
								})();
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Native `fetch` support was added in NodeJS 18.  For older versions of NodeJS,
							 | 
						||
| 
								 | 
							
								the script will throw an error `fetch is not defined`.  A third-party library
							 | 
						||
| 
								 | 
							
								like `axios` presents a similar API for fetching data:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<details><summary><b>Example using axios</b> (click to show)</summary>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Install the dependencies:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```bash
							 | 
						||
| 
								 | 
							
								$ npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The differences in the script are highlighted below.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const XLSX = require("xlsx");
							 | 
						||
| 
								 | 
							
								// highlight-next-line
							 | 
						||
| 
								 | 
							
								const axios = require("axios");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(async() => {
							 | 
						||
| 
								 | 
							
								  /* fetch JSON data and parse */
							 | 
						||
| 
								 | 
							
								  const url = "https://sheetjs.com/executive.json";
							 | 
						||
| 
								 | 
							
								  // highlight-next-line
							 | 
						||
| 
								 | 
							
								  const raw_data = (await axios(url, {responseType: "json"})).data;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  /* 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.xlsb */
							 | 
						||
| 
								 | 
							
								  XLSX.writeFile(workbook, "Presidents.xlsb");
							 | 
						||
| 
								 | 
							
								})();
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								</details>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  </TabItem>
							 | 
						||
| 
								 | 
							
								  <TabItem value="deno" label="Deno">
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Save the following script to `snippet.ts` and run with
							 | 
						||
| 
								 | 
							
								`deno run --allow-net --allow-write snippet.ts`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// @deno-types="https://cdn.sheetjs.com/xlsx-latest/package/types/index.d.ts"
							 | 
						||
| 
								 | 
							
								import * as XLSX from 'https://cdn.sheetjs.com/xlsx-latest/package/xlsx.mjs';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* fetch JSON data and parse */
							 | 
						||
| 
								 | 
							
								const url = "https://sheetjs.com/executive.json";
							 | 
						||
| 
								 | 
							
								const raw_data = await (await fetch(url)).json();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* filter for the Presidents */
							 | 
						||
| 
								 | 
							
								const prez = raw_data.filter((row: any) => row.terms.some((term: any) => term.type === "prez"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* flatten objects */
							 | 
						||
| 
								 | 
							
								const rows = prez.map((row: any) => ({
							 | 
						||
| 
								 | 
							
								  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: number, r: any) => Math.max(w, r.name.length), 10);
							 | 
						||
| 
								 | 
							
								worksheet["!cols"] = [ { wch: max_width } ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* create an XLSX file and try to save to Presidents.xlsb */
							 | 
						||
| 
								 | 
							
								XLSX.writeFile(workbook, "Presidents.xlsb");
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  </TabItem>
							 | 
						||
| 
								 | 
							
								</Tabs>
							 |