| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | ### Processing JSON and JS Data
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | JSON and JS data tend to represent single worksheets.  This section will use a | 
					
						
							| 
									
										
										
										
											2022-03-03 08:35:39 +00:00
										 |  |  | few utility functions to generate workbooks. | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-03 08:35:39 +00:00
										 |  |  | _Create a new Workbook_ | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var workbook = XLSX.utils.book_new(); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `book_new` utility function creates an empty workbook with no worksheets. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-03 08:35:39 +00:00
										 |  |  | Spreadsheet software generally require at least one worksheet and enforce the | 
					
						
							|  |  |  | requirement in the user interface.  This library enforces the requirement at | 
					
						
							|  |  |  | write time, throwing errors if an empty workbook is passed to write functions. | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  | **API** | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | _Create a worksheet from an array of arrays of JS values_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var worksheet = XLSX.utils.aoa_to_sheet(aoa, opts); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `aoa_to_sheet` utility function walks an "array of arrays" in row-major | 
					
						
							|  |  |  | order, generating a worksheet object.  The following snippet generates a sheet | 
					
						
							| 
									
										
										
										
											2022-03-03 08:35:39 +00:00
										 |  |  | with cell `A1` set to the string `A1`, cell `B1` set to `B1`, etc: | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var worksheet = XLSX.utils.aoa_to_sheet([ | 
					
						
							|  |  |  |   ["A1", "B1", "C1"], | 
					
						
							|  |  |  |   ["A2", "B2", "C2"], | 
					
						
							|  |  |  |   ["A3", "B3", "C3"] | 
					
						
							| 
									
										
										
										
											2022-03-03 08:35:39 +00:00
										 |  |  | ]); | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ["Array of Arrays Input"](#array-of-arrays-input) describes the function and the | 
					
						
							|  |  |  | optional `opts` argument in more detail. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _Create a worksheet from an array of JS objects_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var worksheet = XLSX.utils.json_to_sheet(jsa, opts); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `json_to_sheet` utility function walks an array of JS objects in order, | 
					
						
							|  |  |  | generating a worksheet object.  By default, it will generate a header row and | 
					
						
							|  |  |  | one row per object in the array.  The optional `opts` argument has settings to | 
					
						
							|  |  |  | control the column order and header output. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 06:10:24 +00:00
										 |  |  | ["Array of Objects Input"](#array-of-objects-input) describes the function and | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | the optional `opts` argument in more detail. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  | **Examples** | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ["Zen of SheetJS"](#the-zen-of-sheetjs) contains a detailed example "Get Data | 
					
						
							|  |  |  | from a JSON Endpoint and Generate a Workbook" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | [`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive | 
					
						
							|  |  |  | data grid for previewing and modifying structured data in the web browser.  The | 
					
						
							|  |  |  | [`xspreadsheet` demo](/demos/xspreadsheet) includes a sample script with the | 
					
						
							|  |  |  | `xtos` function for converting from x-spreadsheet data object to a workbook. | 
					
						
							|  |  |  | <https://oss.sheetjs.com/sheetjs/x-spreadsheet> is a live demo. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Records from a database query (SQL or no-SQL)</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | The [`database` demo](/demos/database/) includes examples of working with | 
					
						
							|  |  |  | databases and query results. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Numerical Computations with TensorFlow.js</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [`@tensorflow/tfjs`](@tensorflow/tfjs) and other libraries expect data in simple | 
					
						
							|  |  |  | arrays, well-suited for worksheets where each column is a data vector.  That is | 
					
						
							|  |  |  | the transpose of how most people use spreadsheets, where each row is a vector. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When recovering data from `tfjs`, the returned data points are stored in a typed | 
					
						
							|  |  |  | array.  An array of arrays can be constructed with loops. `Array#unshift` can | 
					
						
							|  |  |  | prepend a title row before the conversion: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | const XLSX = require("xlsx"); | 
					
						
							|  |  |  | const tf = require('@tensorflow/tfjs'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* suppose xs and ys are vectors (1D tensors) -> tfarr will be a typed array */ | 
					
						
							|  |  |  | const tfdata = tf.stack([xs, ys]).transpose(); | 
					
						
							|  |  |  | const shape = tfdata.shape; | 
					
						
							|  |  |  | const tfarr = tfdata.dataSync(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* construct the array of arrays */ | 
					
						
							|  |  |  | const aoa = []; | 
					
						
							|  |  |  | for(let j = 0; j < shape[0]; ++j) { | 
					
						
							|  |  |  |   aoa[j] = []; | 
					
						
							|  |  |  |   for(let i = 0; i < shape[1]; ++i) aoa[j][i] = tfarr[j * shape[1] + i]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* add headers to the top */ | 
					
						
							|  |  |  | aoa.unshift(["x", "y"]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* generate worksheet */ | 
					
						
							|  |  |  | const worksheet = XLSX.utils.aoa_to_sheet(aoa); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The [`array` demo](demos/array/) shows a complete example. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | ### Processing HTML Tables
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  | **API** | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | _Create a worksheet by scraping an HTML TABLE in the page_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var worksheet = XLSX.utils.table_to_sheet(dom_element, opts); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `table_to_sheet` utility function takes a DOM TABLE element and iterates | 
					
						
							|  |  |  | through the rows to generate a worksheet.  The `opts` argument is optional. | 
					
						
							|  |  |  | ["HTML Table Input"](#html-table-input) describes the function in more detail. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _Create a workbook by scraping an HTML TABLE in the page_ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var workbook = XLSX.utils.table_to_book(dom_element, opts); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `table_to_book` utility function follows the same logic as `table_to_sheet`. | 
					
						
							|  |  |  | After generating a worksheet, it creates a blank workbook and appends the | 
					
						
							|  |  |  | spreadsheet. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The options argument supports the same options as `table_to_sheet`, with the | 
					
						
							|  |  |  | addition of a `sheet` property to control the worksheet name.  If the property | 
					
						
							|  |  |  | is missing or no options are specified, the default name `Sheet1` is used. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  | **Examples** | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Here are a few common scenarios (click on each subtitle to see the code): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>HTML TABLE element in a webpage</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html | 
					
						
							|  |  |  | <!-- include the standalone script and shim.  this uses the UNPKG CDN --> | 
					
						
							| 
									
										
										
										
											2022-04-12 11:59:15 +00:00
										 |  |  | <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js"></script> | 
					
						
							|  |  |  | <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script> | 
					
						
							| 
									
										
										
										
											2022-02-05 13:59:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | <!-- example table with id attribute --> | 
					
						
							|  |  |  | <table id="tableau"> | 
					
						
							|  |  |  |   <tr><td>Sheet</td><td>JS</td></tr> | 
					
						
							|  |  |  |   <tr><td>12345</td><td>67</td></tr> | 
					
						
							|  |  |  | </table> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <!-- this block should appear after the table HTML and the standalone script --> | 
					
						
							|  |  |  | <script type="text/javascript"> | 
					
						
							|  |  |  |   var workbook = XLSX.utils.table_to_book(document.getElementById("tableau")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* DO SOMETHING WITH workbook HERE */ | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Multiple tables on a web page can be converted to individual worksheets: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* create new workbook */ | 
					
						
							|  |  |  | var workbook = XLSX.utils.book_new(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* convert table "table1" to worksheet named "Sheet1" */ | 
					
						
							|  |  |  | var sheet1 = XLSX.utils.table_to_sheet(document.getElementById("table1")); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(workbook, sheet1, "Sheet1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* convert table "table2" to worksheet named "Sheet2" */ | 
					
						
							|  |  |  | var sheet2 = XLSX.utils.table_to_sheet(document.getElementById("table2")); | 
					
						
							|  |  |  | XLSX.utils.book_append_sheet(workbook, sheet2, "Sheet2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* workbook now has 2 worksheets */ | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Alternatively, the HTML code can be extracted and parsed: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var htmlstr = document.getElementById("tableau").outerHTML; | 
					
						
							|  |  |  | var workbook = XLSX.read(htmlstr, {type:"string"}); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Chrome/Chromium Extension</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The [`chrome` demo](demos/chrome/) shows a complete example and details the | 
					
						
							|  |  |  | required permissions and other settings. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In an extension, it is recommended to generate the workbook in a content script | 
					
						
							|  |  |  | and pass the object back to the extension: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* in the worker script */ | 
					
						
							|  |  |  | chrome.runtime.onMessage.addListener(function(msg, sender, cb) { | 
					
						
							|  |  |  |   /* pass a message like { sheetjs: true } from the extension to scrape */ | 
					
						
							|  |  |  |   if(!msg || !msg.sheetjs) return; | 
					
						
							|  |  |  |   /* create a new workbook */ | 
					
						
							|  |  |  |   var workbook = XLSX.utils.book_new(); | 
					
						
							|  |  |  |   /* loop through each table element */ | 
					
						
							|  |  |  |   var tables = document.getElementsByTagName("table") | 
					
						
							|  |  |  |   for(var i = 0; i < tables.length; ++i) { | 
					
						
							|  |  |  |     var worksheet = XLSX.utils.table_to_sheet(tables[i]); | 
					
						
							|  |  |  |     XLSX.utils.book_append_sheet(workbook, worksheet, "Table" + i); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* pass back to the extension */ | 
					
						
							|  |  |  |   return cb(workbook); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Server-Side HTML Tables with Headless Chrome</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The [`headless` demo](demos/headless/) includes a complete demo to convert HTML | 
					
						
							|  |  |  | files to XLSB workbooks.  The core idea is to add the script to the page, parse | 
					
						
							|  |  |  | the table in the page context, generate a `base64` workbook and send it back | 
					
						
							|  |  |  | for further processing: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | const XLSX = require("xlsx"); | 
					
						
							|  |  |  | const { readFileSync } = require("fs"), puppeteer = require("puppeteer"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const url = `https://sheetjs.com/demos/table`; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* get the standalone build source (node_modules/xlsx/dist/xlsx.full.min.js) */ | 
					
						
							|  |  |  | const lib = readFileSync(require.resolve("xlsx/dist/xlsx.full.min.js"), "utf8"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | (async() => { | 
					
						
							|  |  |  |   /* start browser and go to web page */ | 
					
						
							|  |  |  |   const browser = await puppeteer.launch(); | 
					
						
							|  |  |  |   const page = await browser.newPage(); | 
					
						
							|  |  |  |   await page.goto(url, {waitUntil: "networkidle2"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* inject library */ | 
					
						
							|  |  |  |   await page.addScriptTag({content: lib}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* this function `s5s` will be called by the script below, receiving the Base64-encoded file */ | 
					
						
							|  |  |  |   await page.exposeFunction("s5s", async(b64) => { | 
					
						
							|  |  |  |     const workbook = XLSX.read(b64, {type: "base64" }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* DO SOMETHING WITH workbook HERE */ | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* generate XLSB file in webpage context and send back result */ | 
					
						
							|  |  |  |   await page.addScriptTag({content: ` | 
					
						
							|  |  |  |     /* call table_to_book on first table */ | 
					
						
							|  |  |  |     var workbook = XLSX.utils.table_to_book(document.querySelector("TABLE")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* generate XLSX file */ | 
					
						
							|  |  |  |     var b64 = XLSX.write(workbook, {type: "base64", bookType: "xlsb"}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* call "s5s" hook exposed from the node process */ | 
					
						
							|  |  |  |     window.s5s(b64); | 
					
						
							|  |  |  |   `}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* cleanup */ | 
					
						
							|  |  |  |   await browser.close(); | 
					
						
							|  |  |  | })(); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>Server-Side HTML Tables with Headless WebKit</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The [`headless` demo](demos/headless/) includes a complete demo to convert HTML | 
					
						
							|  |  |  | files to XLSB workbooks using [PhantomJS](https://phantomjs.org/). The core idea | 
					
						
							|  |  |  | is to add the script to the page, parse the table in the page context, generate | 
					
						
							|  |  |  | a `binary` workbook and send it back for further processing: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | var XLSX = require('xlsx'); | 
					
						
							|  |  |  | var page = require('webpage').create(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* this code will be run in the page */ | 
					
						
							|  |  |  | var code = [ "function(){", | 
					
						
							|  |  |  |   /* call table_to_book on first table */ | 
					
						
							|  |  |  |   "var wb = XLSX.utils.table_to_book(document.body.getElementsByTagName('table')[0]);", | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* generate XLSB file and return binary string */ | 
					
						
							|  |  |  |   "return XLSX.write(wb, {type: 'binary', bookType: 'xlsb'});", | 
					
						
							|  |  |  | "}" ].join(""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | page.open('https://sheetjs.com/demos/table', function() { | 
					
						
							|  |  |  |   /* Load the browser script from the UNPKG CDN */ | 
					
						
							| 
									
										
										
										
											2022-04-12 11:59:15 +00:00
										 |  |  |   page.includeJs("https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js", function() { | 
					
						
							| 
									
										
										
										
											2022-02-08 09:50:51 +00:00
										 |  |  |     /* The code will return an XLSB file encoded as binary string */ | 
					
						
							|  |  |  |     var bin = page.evaluateJavaScript(code); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var workbook = XLSX.read(bin, {type: "binary"}); | 
					
						
							|  |  |  |     /* DO SOMETHING WITH workbook HERE */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     phantom.exit(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <details> | 
					
						
							|  |  |  |   <summary><b>NodeJS HTML Tables without a browser</b> (click to show)</summary> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | NodeJS does not include a DOM implementation and Puppeteer requires a hefty | 
					
						
							|  |  |  | Chromium build.  [`jsdom`](https://npm.im/jsdom) is a lightweight alternative: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | const XLSX = require("xlsx"); | 
					
						
							|  |  |  | const { readFileSync } = require("fs"); | 
					
						
							|  |  |  | const { JSDOM } = require("jsdom"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* obtain HTML string.  This example reads from test.html */ | 
					
						
							|  |  |  | const html_str = fs.readFileSync("test.html", "utf8"); | 
					
						
							|  |  |  | /* get first TABLE element */ | 
					
						
							|  |  |  | const doc = new JSDOM(html_str).window.document.querySelector("table"); | 
					
						
							|  |  |  | /* generate workbook */ | 
					
						
							|  |  |  | const workbook = XLSX.utils.table_to_book(doc); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | </details> | 
					
						
							|  |  |  | 
 |