forked from sheetjs/docs.sheetjs.com
		
	synthetic-dom
This commit is contained in:
		
							parent
							
								
									23cb01e318
								
							
						
					
					
						commit
						a36dee9eeb
					
				
							
								
								
									
										186
									
								
								docz/docs/03-demos/03-net/09-dom.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										186
									
								
								docz/docs/03-demos/03-net/09-dom.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,186 @@ | ||||
| --- | ||||
| title: Synthetic DOM | ||||
| --- | ||||
| 
 | ||||
| import current from '/version.js'; | ||||
| import CodeBlock from '@theme/CodeBlock'; | ||||
| 
 | ||||
| `table_to_book` / `table_to_sheet` / `sheet_add_dom` act on HTML DOM elements. | ||||
| Traditionally there is no DOM in server-side environments. | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| The most robust approach for server-side processing is to automate a headless | ||||
| web browser. ["Browser Automation"](/docs/demos/net/headless) includes demos. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| This demo covers synthetic DOM implementations for non-browser platforms. | ||||
| 
 | ||||
| ## NodeJS | ||||
| 
 | ||||
| ### JSDOM | ||||
| 
 | ||||
| JSDOM is a DOM implementation for NodeJS. Given an HTML string, a reference to | ||||
| the table element plays nice with the SheetJS DOM methods: | ||||
| 
 | ||||
| ```js | ||||
| const XLSX = require("xlsx"); | ||||
| const { JSDOM } = require("jsdom"); | ||||
| 
 | ||||
| /* parse HTML */ | ||||
| const dom = new JSDOM(html_string); | ||||
| /* get first TABLE element */ | ||||
| const tbl = dom.window.document.querySelector("table"); | ||||
| /* generate workbook */ | ||||
| const workbook = XLSX.utils.table_to_book(tbl); | ||||
| XLSX.writeFile(workbook, "SheetJSDOM.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| <details open><summary><b>Complete Demo</b> (click to hide)</summary> | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 May 18 against JSDOM `22.0.0` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Install SheetJS and JSDOM libraries: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz jsdom@22.0.0`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 2) Save the following script to `SheetJSDOM.js`: | ||||
| 
 | ||||
| ```js title="SheetJSDOM.js" | ||||
| const XLSX = require("xlsx"); | ||||
| const { readFileSync } = require("fs"); | ||||
| const { JSDOM } = require("jsdom"); | ||||
| 
 | ||||
| /* obtain HTML string.  This example reads from SheetJSTable.html */ | ||||
| const html_str = readFileSync("SheetJSTable.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); | ||||
| XLSX.writeFile(workbook, "SheetJSDOM.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| 3) Download [the sample `SheetJSTable.html`](pathname:///dom/SheetJSTable.html): | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://docs.sheetjs.com/dom/SheetJSTable.html | ||||
| ``` | ||||
| 
 | ||||
| 4) Run the script: | ||||
| 
 | ||||
| ```bash | ||||
| node SheetJSDOM.js | ||||
| ``` | ||||
| 
 | ||||
| The script will create a file `SheetJSDOM.xlsx` that can be opened. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### CheerioJS | ||||
| 
 | ||||
| :::caution | ||||
| 
 | ||||
| Cheerio does not support a number of fundamental properties out of the box. They | ||||
| can be shimmed, but it is strongly recommended to use a more compliant library. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| CheerioJS provides a DOM-like framework for NodeJS. Given an HTML string, a | ||||
| reference to the table element works with the SheetJS DOM methods with some | ||||
| prototype fixes. [`SheetJSCheerio.js`](pathname:///dom/SheetJSCheerio.js) is a | ||||
| complete script. | ||||
| 
 | ||||
| <details><summary><b>Complete Demo</b> (click to show)</summary> | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 May 18 against Cheerio `1.0.0-rc.12` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Install SheetJS and CheerioJS libraries: | ||||
| 
 | ||||
| <CodeBlock language="bash">{`\ | ||||
| npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz cheerio@1.0.0-rc.12`} | ||||
| </CodeBlock> | ||||
| 
 | ||||
| 2) Download [the sample script `SheetJSCheerio.js`](pathname:///dom/SheetJSCheerio.js): | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://docs.sheetjs.com/dom/SheetJSCheerio.js | ||||
| ``` | ||||
| 
 | ||||
| 3) Download [the sample `SheetJSTable.html`](pathname:///dom/SheetJSTable.html): | ||||
| 
 | ||||
| ```bash | ||||
| curl -LO https://docs.sheetjs.com/dom/SheetJSTable.html | ||||
| ``` | ||||
| 
 | ||||
| 4) Run the script: | ||||
| 
 | ||||
| ```bash | ||||
| node SheetJSCheerio.js | ||||
| ``` | ||||
| 
 | ||||
| The script will create a file `SheetJSCheerio.xlsx` that can be opened. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Other Platforms | ||||
| 
 | ||||
| ### DenoDOM | ||||
| 
 | ||||
| DenoDOM provides a DOM framework for Deno. Given an HTML string, a reference to | ||||
| the table element works with the SheetJS DOM methods after patching the object. | ||||
| 
 | ||||
| This example fetches [a sample table](pathname:///dom/SheetJSTable.html): | ||||
| 
 | ||||
| ```ts title="SheetJSDenoDOM.ts" | ||||
| // @deno-types="https://cdn.sheetjs.com/xlsx-0.19.3/package/types/index.d.ts" | ||||
| import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.19.3/package/xlsx.mjs'; | ||||
| 
 | ||||
| import { DOMParser } from 'https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts'; | ||||
| 
 | ||||
| const doc = new DOMParser().parseFromString( | ||||
| 	await (await fetch('https://docs.sheetjs.com/dom/SheetJSTable.html')).text(), | ||||
|   "text/html", | ||||
| )!; | ||||
| // highlight-start | ||||
| const tbl = doc.querySelector("table"); | ||||
| 
 | ||||
| /* patch DenoDOM element */ | ||||
| tbl.rows = tbl.querySelectorAll("tr"); | ||||
| tbl.rows.forEach(row => row.cells = row.querySelectorAll("td, th")) | ||||
| 
 | ||||
| /* generate workbook */ | ||||
| const workbook = XLSX.utils.table_to_book(tbl); | ||||
| // highlight-end | ||||
| XLSX.writeFile(workbook, "SheetJSDenoDOM.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| <details open><summary><b>Complete Demo</b> (click to hide)</summary> | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| This demo was last tested on 2023 May 18 against DenoDOM `0.1.38` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| 1) Save the previous codeblock to `SheetJSDenoDOM.ts`. | ||||
| 
 | ||||
| 2) Run the script with `--allow-net` and `--allow-write` entitlements: | ||||
| 
 | ||||
| ```bash | ||||
| deno run --allow-net --allow-write SheetJSDenoDOM.ts | ||||
| ``` | ||||
| 
 | ||||
| The script will create a file `SheetJSDenoDOM.xlsx` that can be opened. | ||||
| 
 | ||||
| </details> | ||||
| @ -702,8 +702,8 @@ var worksheet = XLSX.utils.aoa_to_sheet([ | ||||
| ]); | ||||
| ``` | ||||
| 
 | ||||
| ["Array of Arrays Input"](/docs/api/utilities#array-of-arrays-input) describes the function and the | ||||
| optional `opts` argument in more detail. | ||||
| ["Array of Arrays Input"](/docs/api/utilities#array-of-arrays-input) describes | ||||
| the function and the optional `opts` argument in more detail. | ||||
| 
 | ||||
| 
 | ||||
| _Create a worksheet from an array of JS objects_ | ||||
| @ -752,7 +752,8 @@ 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"](/docs/api/utilities#html-table-input) describes the function in more detail. | ||||
| ["HTML Table Input"](/docs/api/utilities/html#html-table-input) describes the | ||||
| function in more detail. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -860,19 +861,7 @@ chrome.runtime.onMessage.addListener(function(msg, sender, cb) { | ||||
|   <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`** 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); | ||||
| ``` | ||||
| Chromium build.  The ["Synthetic DOM"](/docs/demos/net/dom) demo includes | ||||
| examples for NodeJS. | ||||
| 
 | ||||
| </details> | ||||
|  | ||||
| @ -23,41 +23,60 @@ formats, the library will guess the number format. | ||||
| | WK\*              |       | Binary encoding        | | ||||
| | WQ\* / WB\* / QPW |       | Binary encoding        | | ||||
| | DBF               |       | Implied by field types | | ||||
| | HTML              |   *   | Special override       | | ||||
| | CSV               |   *   | N/A                    | | ||||
| | PRN               |   *   | N/A                    | | ||||
| | DIF               |   *   | N/A                    | | ||||
| | RTF               |   *   | N/A                    | | ||||
| 
 | ||||
| Asterisks (*) mark formats that mix content and presentation. Synthetic number | ||||
| formats may be generated for special values. | ||||
| Asterisks (*) mark formats that mix content and presentation. Writers will use | ||||
| formatted values if cell objects include formatted text or number formats. | ||||
| Parsers may guess number formats for special values. | ||||
| 
 | ||||
| The letter R (R) marks features parsed but not written in the format. | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| The following example generates a file with some common number formats: | ||||
| This example generates a worksheet with common number formats. `sheet_to_html` | ||||
| uses the number formats in generating the HTML table. The "Export" button | ||||
| generates workbooks with number formatting. | ||||
| 
 | ||||
| ```jsx live | ||||
| function SheetJSSimpleNF(props) { | ||||
|   const xport = React.useCallback(async () => { | ||||
|   const [ws, setWS] = React.useState(); | ||||
|   const fmt = React.useRef(null); | ||||
| 
 | ||||
|   /* when the page is loaded, create worksheet and show table */ | ||||
|   React.useEffect(() => { | ||||
|     /* Create worksheet from simple data */ | ||||
|     const ws = XLSX.utils.aoa_to_sheet([ | ||||
|       ["Currency", 3.5], | ||||
|       ["Thousands", 7262], | ||||
|       ["Percent", 0.0219] | ||||
|       ["General",   54337      ], | ||||
|       ["Currency",      3.5    ], | ||||
|       ["Thousands",  7262      ], | ||||
|       ["Percent",       0.0219 ], | ||||
|     ]); | ||||
|     /* assign number formats */ | ||||
|     ws["B1"].z = '"$"#,##0_);\\("$"#,##0\\)'; | ||||
|     ws["B2"].z = '#,##0'; | ||||
|     ws["B3"].z = "0.00%"; | ||||
| 
 | ||||
|     /* assign number formats */ | ||||
|     ws["B2"].z = '"$"#,##0.00_);\\("$"#,##0.00\\)'; | ||||
|     ws["B3"].z = '#,##0'; | ||||
|     ws["B4"].z = "0.00%"; | ||||
| 
 | ||||
|     setWS(ws); | ||||
|   }, []); | ||||
| 
 | ||||
|   const xport = (fmt) => { | ||||
|     /* Export to file (start a download) */ | ||||
|     const wb = XLSX.utils.book_new(); | ||||
|     XLSX.utils.book_append_sheet(wb, ws, "Formats"); | ||||
|     XLSX.writeFile(wb, "SheetJSSimpleNF.xlsx"); | ||||
|   }); | ||||
|     XLSX.writeFile(wb, `SheetJSSimpleNF.${fmt}`); | ||||
|   }; | ||||
| 
 | ||||
|   return ( <button onClick={xport}><b>Export XLSX!</b></button> ); | ||||
|   const fmts = ["xlsx", "xls", "csv", "xlsb", "html", "ods"]; | ||||
|   return ( <> | ||||
|     <select ref={fmt}>{fmts.map(fmt => (<option value={fmt}>{fmt}</option>))}</select> | ||||
|     <button onClick={()=>xport(fmt.current.value)}><b>Export!</b></button> | ||||
|     <div dangerouslySetInnerHTML={{__html: ws && XLSX.utils.sheet_to_html(ws) || "" }}/> | ||||
|   </> ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| @ -70,9 +89,8 @@ To simplify editing, the applications will store the underlying values and the | ||||
| number formats separately. For example, `$3.50` will be represented as the value | ||||
| `3.5` with a number format that mandates a `$` sigil and 2 decimal places. | ||||
| 
 | ||||
| Some file formats like CSV only support the formatted text. Native formats for | ||||
| spreadsheet applications including Lotus 1-2-3 and Excel will store the value | ||||
| and number format separately. | ||||
| CSV and other formats only support the formatted text. Applications reading CSV | ||||
| files are expected to interpret the values as numbers or dates. | ||||
| 
 | ||||
| ### Dates and Times | ||||
| 
 | ||||
| @ -115,18 +133,17 @@ function SheetJSExtractNF(props) { | ||||
|   return ( <> | ||||
|     <input type="file" onChange={async(e) => { | ||||
|       /* parse workbook with cellNF: true */ | ||||
|       const file = e.target.files[0]; | ||||
|       const data = await file.arrayBuffer(); | ||||
|       const wb = XLSX.read(data, {cellNF: true}); | ||||
|       const wb = XLSX.read(await e.target.files[0].arrayBuffer(), {cellNF: true}); | ||||
| 
 | ||||
|       /* look at each cell in each worksheet */ | ||||
|       const formats = {}; | ||||
|       wb.SheetNames.forEach(n => { | ||||
|         var ws = wb.Sheets[n]; if(!ws || !ws["!ref"]) return; | ||||
|         var ref = XLSX.utils.decode_range(ws["!ref"]); | ||||
|         for(var R = 0; R <= ref.e.r; ++R) for(var C = 0; C <= ref.e.c; ++C) { | ||||
|           var addr = XLSX.utils.encode_cell({r:R,c:C}); | ||||
|           if(!ws[addr] || !ws[addr].z) continue; | ||||
|           if(formats[ws[addr].z]) continue; | ||||
|           if(!ws[addr] || !ws[addr].z || formats[ws[addr].z]) continue; | ||||
|           /* when a new format is found, save the address */ | ||||
|           formats[ws[addr].z] = `'${n}'!${addr}`; | ||||
|           setRows(Object.entries(formats)); | ||||
|         } | ||||
| @ -216,3 +233,6 @@ set of formats as "Accounting".  The exact formats in `en-US` are listed below: | ||||
| For other locales, the formats can be discovered by creating a file with the | ||||
| desired format and testing with [the Number Format Strings demo](#number-format-strings) | ||||
| 
 | ||||
| ### HTML Override | ||||
| 
 | ||||
| [**This feature is discussed in the HTML utilities section**](/docs/api/utilities/html#value-override) | ||||
							
								
								
									
										388
									
								
								docz/docs/08-api/07-utilities/07-html.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										388
									
								
								docz/docs/08-api/07-utilities/07-html.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,388 @@ | ||||
| --- | ||||
| sidebar_position: 7 | ||||
| title: HTML | ||||
| --- | ||||
| 
 | ||||
| HTML is a common format for presenting data in the web. While the general read | ||||
| functions (`XLSX.read` and `XLSX.readFile`) can parse HTML strings and the write | ||||
| functions (`XLSX.write` and `XLSX.writeFile`) can generate HTML strings, the | ||||
| utility functions in this section can use DOM features. | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| SheetJS CE primarily focuses on data and number formatting. | ||||
| 
 | ||||
| [SheetJS Pro](https://sheetjs.com/pro) supports CSS text and cell styles in the | ||||
| HTML format and HTML table utilities. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| ## HTML Table Input | ||||
| 
 | ||||
| ### Create New Sheet | ||||
| 
 | ||||
| **Create a worksheet or workbook from a TABLE element** | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.table_to_sheet(elt, opts); | ||||
| var wb = XLSX.utils.table_to_book(elt, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet | ||||
| resembling the input table.  Numbers are parsed.  All other data will be stored | ||||
| as strings. | ||||
| 
 | ||||
| `XLSX.utils.table_to_book` produces a minimal workbook based on the worksheet. | ||||
| 
 | ||||
| Both functions accept options arguments: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`raw`        |          | If true, every cell will hold raw strings           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`cellDates`  |  false   | Store dates as type `d` (default is `n`)            | | ||||
| |`sheetRows`  |    0     | If >0, read the first `sheetRows` rows of the table | | ||||
| |`display`    |  false   | If true, hidden rows and cells will not be parsed   | | ||||
| 
 | ||||
| Exporting a table to a spreadsheet file in the web browser involves 3 steps: | ||||
| "find the table", "generate a workbook object", and "export to file". | ||||
| 
 | ||||
| For example, if the HTML table has `id` attribute set to `sheetjs`: | ||||
| 
 | ||||
| ```html | ||||
| <table id="sheetjs"> | ||||
|   <tr><th>Name</th><th>Index</th></tr> | ||||
|   <tr><td>Barack Obama</td><td>44</td></tr> | ||||
|   <tr><td>Donald Trump</td><td>45</td></tr> | ||||
|   <tr><td>Joseph Biden</td><td>46</td></tr> | ||||
| </table> | ||||
| ``` | ||||
| 
 | ||||
| `document.getElementById("sheetjs")` is a live reference to the table. | ||||
| 
 | ||||
| ```js | ||||
| /* find the table element in the page */ | ||||
| var tbl = document.getElementById('sheetjs'); | ||||
| /* create a workbook */ | ||||
| var wb = XLSX.utils.table_to_book(tbl); | ||||
| /* export to file */ | ||||
| XLSX.writeFile(wb, "SheetJSTable.xlsx"); | ||||
| ``` | ||||
| 
 | ||||
| <details open><summary><b>Demo</b> (click to hide)</summary> | ||||
| 
 | ||||
| This HTML table has id set to `sheetjs`: | ||||
| 
 | ||||
| <table id="sheetjs"> | ||||
|   <tr><th>Name</th><th>Index</th></tr> | ||||
|   <tr><td>Barack Obama</td><td>44</td></tr> | ||||
|   <tr><td>Donald Trump</td><td>45</td></tr> | ||||
|   <tr><td>Joseph Biden</td><td>46</td></tr> | ||||
| </table> | ||||
| 
 | ||||
| ```jsx live | ||||
| function SheetJSExportTable() { return ( <button onClick={() => { | ||||
|   /* find the table element in the page */ | ||||
|   var tbl = document.getElementById('sheetjs'); | ||||
|   /* create a workbook */ | ||||
|   var wb = XLSX.utils.table_to_book(tbl); | ||||
|   /* export to file */ | ||||
|   XLSX.writeFile(wb, "SheetJSTable.xlsx"); | ||||
| }}><b>Export XLSX!</b></button> ); } | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### Add to Sheet | ||||
| 
 | ||||
| **Add data from a TABLE element to an existing worksheet** | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_dom(ws, elt, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_dom` takes a table DOM element and updates an existing | ||||
| worksheet object.  It follows the same process as `table_to_sheet` and accepts | ||||
| an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`raw`        |          | If true, every cell will hold raw strings           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`cellDates`  |  false   | Store dates as type `d` (default is `n`)            | | ||||
| |`sheetRows`  |    0     | If >0, read the first `sheetRows` rows of the table | | ||||
| |`display`    |  false   | If true, hidden rows and cells will not be parsed   | | ||||
| 
 | ||||
| `origin` is expected to be one of: | ||||
| 
 | ||||
| | `origin`         | Description                                               | | ||||
| | :--------------- | :-------------------------------------------------------- | | ||||
| | (cell object)    | Use specified cell (cell object)                          | | ||||
| | (string)         | Use specified cell (A1-Style cell)                        | | ||||
| | (number >= 0)    | Start from the first column at specified row (0-indexed)  | | ||||
| | -1               | Append to bottom of worksheet starting on first column    | | ||||
| | (default)        | Start from cell `A1`                                      | | ||||
| 
 | ||||
| 
 | ||||
| A common use case for `sheet_add_dom` involves adding multiple tables to a | ||||
| single worksheet, usually with a few blank rows in between each table: | ||||
| 
 | ||||
| ```js | ||||
| /* get "table1" and create worksheet */ | ||||
| const table1 = document.getElementById('table1'); | ||||
| const ws = XLSX.utils.table_to_sheet(table1); | ||||
| 
 | ||||
| /* get "table2" and append to the worksheet */ | ||||
| const table2 = document.getElementById('table2'); | ||||
| // highlight-next-line | ||||
| XLSX.utils.sheet_add_dom(ws, table2, {origin: -1}); | ||||
| ``` | ||||
| 
 | ||||
| <details><summary><b>Multi-table Export Example</b> (click to show)</summary> | ||||
| 
 | ||||
| This demo creates a worksheet that should look like the screenshot below: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| The `create_gap_rows` helper function expands the worksheet range, adding blank | ||||
| rows between the data tables. | ||||
| 
 | ||||
| ```jsx live | ||||
| function MultiTable() { | ||||
|   const headers = ["Table 1", "Table2", "Table 3"]; | ||||
| 
 | ||||
|   /* Callback invoked when the button is clicked */ | ||||
|   const xport = React.useCallback(async () => { | ||||
|     /* This function creates gap rows */ | ||||
|     function create_gap_rows(ws, nrows) { | ||||
|       var ref = XLSX.utils.decode_range(ws["!ref"]);       // get original range | ||||
|       ref.e.r += nrows;                                    // add to ending row | ||||
|       ws["!ref"] = XLSX.utils.encode_range(ref);           // reassign row | ||||
|     } | ||||
| 
 | ||||
|     /* first table */ | ||||
|     const ws = XLSX.utils.aoa_to_sheet([[headers[0]]]); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table1'), {origin: -1}); | ||||
|     create_gap_rows(ws, 1); // one row gap after first table | ||||
| 
 | ||||
|     /* second table */ | ||||
|     XLSX.utils.sheet_add_aoa(ws, [[headers[1]]], {origin: -1}); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table2'), {origin: -1}); | ||||
|     create_gap_rows(ws, 2); // two rows gap after second table | ||||
| 
 | ||||
|     /* third table */ | ||||
|     XLSX.utils.sheet_add_aoa(ws, [[headers[2]]], {origin: -1}); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table3'), {origin: -1}); | ||||
| 
 | ||||
|     /* create workbook and export */ | ||||
|     const wb = XLSX.utils.book_new(); | ||||
|     XLSX.utils.book_append_sheet(wb, ws, "Export"); | ||||
|     XLSX.writeFile(wb, "SheetJSMultiTablexport.xlsx"); | ||||
|   }); | ||||
| 
 | ||||
|   return ( <> | ||||
|     <button onClick={xport}><b>Export XLSX!</b></button><br/><br/> | ||||
|     <b>{headers[0]}</b><br/> | ||||
|     <table id="table1"> | ||||
|       <tr><td>A2</td><td>B2</td></tr> | ||||
|       <tr><td>A3</td><td>B3</td></tr> | ||||
|     </table> | ||||
|     <b>{headers[1]}</b><br/> | ||||
|     <table id="table2"> | ||||
|       <tr><td>A6</td><td>B6</td><td>C6</td></tr> | ||||
|       <tr><td>A7</td><td>B7</td><td>C7</td></tr> | ||||
|     </table> | ||||
|     <br/> | ||||
|     <b>{headers[2]}</b><br/> | ||||
|     <table id="table3"> | ||||
|       <tr><td>A11</td><td>B11</td></tr> | ||||
|       <tr><td>A12</td><td>B12</td></tr> | ||||
|     </table> | ||||
|   </> ); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### HTML Strings | ||||
| 
 | ||||
| **Create a worksheet or workbook from HTML string** | ||||
| 
 | ||||
| `table_to_book` / `table_to_sheet` / `sheet_add_dom` act on HTML DOM elements. | ||||
| Starting from an HTML string, there are two parsing approaches: | ||||
| 
 | ||||
| A) Table Phantasm: create a DIV whose `innerHTML` is set to the HTML string, | ||||
| generate worksheet using the DOM element, then remove the DIV: | ||||
| 
 | ||||
| ```js | ||||
| /* create element from the source */ | ||||
| var elt = document.createElement("div"); | ||||
| elt.innerHTML = html_source; | ||||
| document.body.appendChild(elt); | ||||
| 
 | ||||
| /* generate worksheet */ | ||||
| var ws = XLSX.utils.table_to_sheet(elt.getElementsByTagName("TABLE")[0]); | ||||
| 
 | ||||
| /* remove element */ | ||||
| document.body.removeChild(elt); | ||||
| ``` | ||||
| 
 | ||||
| <details><summary><b>Phantasm Demo</b> (click to show)</summary> | ||||
| 
 | ||||
| The `html` variable in the demo is an editable HTML string | ||||
| 
 | ||||
| ```jsx live | ||||
| function SheetJSTablePhantasm() { | ||||
|   /* HTML stored as a string */ | ||||
|   const html = `\ | ||||
| <table> | ||||
|   <tr><th>Name</th><th>Index</th></tr> | ||||
|   <tr><td>Barack Obama</td><td>44</td></tr> | ||||
|   <tr><td>Donald Trump</td><td>45</td></tr> | ||||
|   <tr><td>Joseph Biden</td><td>46</td></tr> | ||||
| </table> | ||||
| `; | ||||
|   return ( <> | ||||
|     <button onClick={() => { | ||||
|       /* create element from the source */ | ||||
|       var elt = document.createElement("div"); | ||||
|       elt.innerHTML = html; | ||||
|       document.body.appendChild(elt); | ||||
| 
 | ||||
|       /* generate workbook */ | ||||
|       var tbl = elt.getElementsByTagName("TABLE")[0]; | ||||
|       var wb = XLSX.utils.table_to_book(tbl); | ||||
| 
 | ||||
|       /* remove element */ | ||||
|       document.body.removeChild(elt); | ||||
| 
 | ||||
|       /* generate file */ | ||||
|       XLSX.writeFile(wb, "SheetJSTablePhantasm.xlsx"); | ||||
|     }}><b>Export XLSX!</b></button> | ||||
|     <pre><b>HTML:</b><br/>{html}</pre> | ||||
|   </>); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| B) Raw HTML: use `XLSX.read` to read the text in the same manner as CSV. | ||||
| 
 | ||||
| ```js | ||||
| var wb = XLSX.read(html_source, { type: "string" }); | ||||
| var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| ``` | ||||
| 
 | ||||
| <details><summary><b>Raw HTML Demo</b> (click to show)</summary> | ||||
| 
 | ||||
| The `html` variable in the demo is an editable HTML string | ||||
| 
 | ||||
| ```jsx live | ||||
| function SheetJSRawHTMLToXLSX() { | ||||
|   /* HTML stored as a string */ | ||||
|   const html = `\ | ||||
| <table> | ||||
|   <tr><th>Name</th><th>Index</th></tr> | ||||
|   <tr><td>Barack Obama</td><td>44</td></tr> | ||||
|   <tr><td>Donald Trump</td><td>45</td></tr> | ||||
|   <tr><td>Joseph Biden</td><td>46</td></tr> | ||||
| </table> | ||||
| `; | ||||
|   return ( <> | ||||
|     <button onClick={() => { | ||||
|       /* read HTML string */ | ||||
|       var wb = XLSX.read(html, {type: "string"}); | ||||
| 
 | ||||
|       /* generate file */ | ||||
|       XLSX.writeFile(wb, "SheetJSRawHTML.xlsx"); | ||||
|     }}><b>Export XLSX!</b></button> | ||||
|     <pre><b>HTML:</b><br/>{html}</pre> | ||||
|   </>); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Value Override | ||||
| 
 | ||||
| When the `raw: true` option is specified, the parser will generate text cells. | ||||
| When the option is not specified or when it is set to false, the parser will | ||||
| try to interpret the text of each TD element. | ||||
| 
 | ||||
| To override the conversion for a specific cell, the following data attributes | ||||
| can be added to the individual TD elements: | ||||
| 
 | ||||
| | Attribute | Description                                                  | | ||||
| |:----------|:-------------------------------------------------------------| | ||||
| | `data-t`  | Override [Cell Type](/docs/csf/cell#data-types)              | | ||||
| | `data-v`  | Override Cell Value                                          | | ||||
| | `data-z`  | Override [Number Format](/docs/csf/features/nf)              | | ||||
| 
 | ||||
| For example: | ||||
| 
 | ||||
| ```html | ||||
| <!-- Parser interprets value as `new Date("2012-12-03")` default date format --> | ||||
| <td>2012-12-03</td> | ||||
| 
 | ||||
| <!-- String cell "2012-12-03" --> | ||||
| <td data-t="s">2012-12-03</td> | ||||
| 
 | ||||
| <!-- Numeric cell with the correct date code and General format --> | ||||
| <td data-t="n" data-v="41246">2012-12-03</td> | ||||
| 
 | ||||
| <!-- Traditional Excel Date 2012-12-03 with style yyyy-mm-dd --> | ||||
| <td data-t="n" data-v="41246" data-z="yyyy-mm-dd">2012-12-03</td> | ||||
| ``` | ||||
| 
 | ||||
| <details open><summary><b>HTML Value Examples</b> (click to hide)</summary> | ||||
| 
 | ||||
| ```jsx live | ||||
| function SheetJSHTMLValueOverride() { | ||||
|   /* HTML stored as a string */ | ||||
|   const html = `\ | ||||
| <table> | ||||
|   <tr><th>Cell</th><th>data-t</th><th>data-v</th><th>data-z</th></tr> | ||||
|   <tr><td>2012-12-03</td><td/><td/><td/></tr> | ||||
|   <tr><td data-t="s">2012-12-03</td><td>s</td><td/><td/></tr> | ||||
|   <tr><td data-t="n" data-v="41246">2012-12-03</td><td>n</td><td>41246</td><td/></tr> | ||||
|   <tr><td data-t="n" data-v="41246" data-z="yyyy-mm-dd">2012-12-03</td><td>n</td><td>41246</td><td>yyyy-mm-dd</td></tr> | ||||
| </table> | ||||
| `; | ||||
|   return ( <> | ||||
|     <button onClick={() => { | ||||
|       /* create element from the source */ | ||||
|       var elt = document.createElement("div"); | ||||
|       elt.innerHTML = html; | ||||
|       document.body.appendChild(elt); | ||||
| 
 | ||||
|       /* generate workbook */ | ||||
|       var tbl = elt.getElementsByTagName("TABLE")[0]; | ||||
|       var wb = XLSX.utils.table_to_book(tbl); | ||||
| 
 | ||||
|       /* remove element */ | ||||
|       document.body.removeChild(elt); | ||||
| 
 | ||||
|       /* generate file */ | ||||
|       XLSX.writeFile(wb, "SheetJSHTMLValueOverride.xlsx"); | ||||
|     }}><b>Export XLSX!</b></button> | ||||
|     <pre><b>HTML String:</b><br/>{html}<br/><b>TABLE:</b></pre> | ||||
|     <div dangerouslySetInnerHTML={{__html: html}}/> | ||||
|   </>); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ### Synthetic DOM | ||||
| 
 | ||||
| `table_to_book` / `table_to_sheet` / `sheet_add_dom` act on HTML DOM elements. | ||||
| Traditionally there is no DOM in server-side environments including NodeJS. | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| The simplest approach for server-side processing is to automate a headless web | ||||
| browser. ["Browser Automation"](/docs/demos/net/headless) covers some browsers. | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| Some ecosystems provide DOM-like frameworks that are compatible with SheetJS. | ||||
| Examples are included in the ["Synthetic DOM"](/docs/demos/net/dom) demo | ||||
| @ -276,187 +276,11 @@ function SheetJSHeaderOrder() { | ||||
| 
 | ||||
| ## HTML Table Input | ||||
| 
 | ||||
| **Create a worksheet or workbook from a TABLE element** | ||||
| 
 | ||||
| ```js | ||||
| var ws = XLSX.utils.table_to_sheet(elt, opts); | ||||
| var wb = XLSX.utils.table_to_book(elt, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.table_to_sheet` takes a table DOM element and returns a worksheet | ||||
| resembling the input table.  Numbers are parsed.  All other data will be stored | ||||
| as strings. | ||||
| 
 | ||||
| `XLSX.utils.table_to_book` produces a minimal workbook based on the worksheet. | ||||
| 
 | ||||
| Both functions accept options arguments: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`raw`        |          | If true, every cell will hold raw strings           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`cellDates`  |  false   | Store dates as type `d` (default is `n`)            | | ||||
| |`sheetRows`  |    0     | If >0, read the first `sheetRows` rows of the table | | ||||
| |`display`    |  false   | If true, hidden rows and cells will not be parsed   | | ||||
| 
 | ||||
| 
 | ||||
| To generate the example sheet, assuming the table has ID `sheetjs`: | ||||
| 
 | ||||
| ```js | ||||
| var tbl = document.getElementById('sheetjs'); | ||||
| var ws = XLSX.utils.table_to_sheet(tbl); | ||||
| ``` | ||||
| 
 | ||||
| :::note | ||||
| 
 | ||||
| `table_to_book` and `table_to_sheet` act on HTML DOM elements.  Starting from | ||||
| an HTML string, there are two parsing approaches: | ||||
| 
 | ||||
| A) Table Phantasm: create a DIV with the desired HTML. | ||||
| 
 | ||||
| ```js | ||||
| /* create element from the source */ | ||||
| var elt = document.createElement("div"); | ||||
| elt.innerHTML = html_source; | ||||
| document.body.appendChild(elt); | ||||
| 
 | ||||
| /* generate worksheet */ | ||||
| var ws = XLSX.utils.table_to_sheet(elt.getElementsByTagName("TABLE")[0]); | ||||
| 
 | ||||
| /* remove element */ | ||||
| document.body.removeChild(elt); | ||||
| ``` | ||||
| 
 | ||||
| B) Raw HTML: use `XLSX.read` to read the text in the same manner as CSV. | ||||
| 
 | ||||
| ```js | ||||
| var wb = XLSX.read(html_source, { type: "string" }); | ||||
| var ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| ``` | ||||
| 
 | ||||
| ::: | ||||
| 
 | ||||
| **Add data from a TABLE element to an existing worksheet** | ||||
| 
 | ||||
| ```js | ||||
| XLSX.utils.sheet_add_dom(ws, elt, opts); | ||||
| ``` | ||||
| 
 | ||||
| `XLSX.utils.sheet_add_dom` takes a table DOM element and updates an existing | ||||
| worksheet object.  It follows the same process as `table_to_sheet` and accepts | ||||
| an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| |`raw`        |          | If true, every cell will hold raw strings           | | ||||
| |`dateNF`     |  FMT 14  | Use specified date format in string output          | | ||||
| |`cellDates`  |  false   | Store dates as type `d` (default is `n`)            | | ||||
| |`sheetRows`  |    0     | If >0, read the first `sheetRows` rows of the table | | ||||
| |`display`    |  false   | If true, hidden rows and cells will not be parsed   | | ||||
| 
 | ||||
| `origin` is expected to be one of: | ||||
| 
 | ||||
| | `origin`         | Description                                               | | ||||
| | :--------------- | :-------------------------------------------------------- | | ||||
| | (cell object)    | Use specified cell (cell object)                          | | ||||
| | (string)         | Use specified cell (A1-Style cell)                        | | ||||
| | (number >= 0)    | Start from the first column at specified row (0-indexed)  | | ||||
| | -1               | Append to bottom of worksheet starting on first column    | | ||||
| | (default)        | Start from cell `A1`                                      | | ||||
| 
 | ||||
| 
 | ||||
| A common use case for `sheet_add_dom` involves adding multiple tables to a | ||||
| single worksheet, usually with a few blank rows in between each table: | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| ```jsx live | ||||
| function MultiTable() { | ||||
|   const headers = ["Table 1", "Table2", "Table 3"]; | ||||
| 
 | ||||
|   /* Callback invoked when the button is clicked */ | ||||
|   const xport = React.useCallback(async () => { | ||||
|     /* This function creates gap rows */ | ||||
|     function create_gap_rows(ws, nrows) { | ||||
|       var ref = XLSX.utils.decode_range(ws["!ref"]);       // get original range | ||||
|       ref.e.r += nrows;                                    // add to ending row | ||||
|       ws["!ref"] = XLSX.utils.encode_range(ref);           // reassign row | ||||
|     } | ||||
| 
 | ||||
|     /* first table */ | ||||
|     const ws = XLSX.utils.aoa_to_sheet([[headers[0]]]); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table1'), {origin: -1}); | ||||
|     create_gap_rows(ws, 1); // one row gap after first table | ||||
| 
 | ||||
|     /* second table */ | ||||
|     XLSX.utils.sheet_add_aoa(ws, [[headers[1]]], {origin: -1}); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table2'), {origin: -1}); | ||||
|     create_gap_rows(ws, 2); // two rows gap after second table | ||||
| 
 | ||||
|     /* third table */ | ||||
|     XLSX.utils.sheet_add_aoa(ws, [[headers[2]]], {origin: -1}); | ||||
|     XLSX.utils.sheet_add_dom(ws, document.getElementById('table3'), {origin: -1}); | ||||
| 
 | ||||
|     /* create workbook and export */ | ||||
|     const wb = XLSX.utils.book_new(); | ||||
|     XLSX.utils.book_append_sheet(wb, ws, "Export"); | ||||
|     XLSX.writeFile(wb, "SheetJSMultiTablexport.xlsx"); | ||||
|   }); | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <button onClick={xport}><b>Export XLSX!</b></button><br/><br/> | ||||
|       <b>{headers[0]}</b><br/> | ||||
|       <table id="table1"> | ||||
|         <tr><td>A2</td><td>B2</td></tr> | ||||
|         <tr><td>A3</td><td>B3</td></tr> | ||||
|       </table> | ||||
|       <b>{headers[1]}</b><br/> | ||||
|       <table id="table2"> | ||||
|         <tr><td>A6</td><td>B6</td><td>C6</td></tr> | ||||
|         <tr><td>A7</td><td>B7</td><td>C7</td></tr> | ||||
|       </table> | ||||
|       <br/> | ||||
|       <b>{headers[2]}</b><br/> | ||||
|       <table id="table3"> | ||||
|         <tr><td>A11</td><td>B11</td></tr> | ||||
|         <tr><td>A12</td><td>B12</td></tr> | ||||
|       </table> | ||||
|     </> | ||||
|   ); | ||||
| } | ||||
| ``` | ||||
| [**This has been moved to a separate page**](/docs/api/utilities/html#html-table-input) | ||||
| 
 | ||||
| ### Value Override | ||||
| 
 | ||||
| When the `raw: true` option is specified, the parser will generate text cells. | ||||
| When the option is not specified or when it is set to false, the parser will | ||||
| try to interpret the text of each TD element. | ||||
| 
 | ||||
| To override the conversion for a specific cell, the following data attributes | ||||
| can be added to the individual TD elements: | ||||
| 
 | ||||
| | Attribute | Description                                                  | | ||||
| |:----------|:-------------------------------------------------------------| | ||||
| | `data-t`  | Override [Cell Type](/docs/csf/cell#data-types)              | | ||||
| | `data-v`  | Override Cell Value                                          | | ||||
| | `data-z`  | Override [Number Format](/docs/csf/features/nf)              | | ||||
| 
 | ||||
| For example: | ||||
| 
 | ||||
| ```html | ||||
| <!-- Parser interprets value as `new Date("2012-12-03")` default date format --> | ||||
| <td>2012-12-03</td> | ||||
| 
 | ||||
| <!-- String cell "2012-12-03" --> | ||||
| <td data-t="s">2012-12-03</td> | ||||
| 
 | ||||
| <!-- Numeric cell with the correct date code and General format --> | ||||
| <td data-t="n" data-v="41246">2012-12-03</td> | ||||
| 
 | ||||
| <!-- Traditional Excel Date 2012-12-03 with style yyyy-mm-dd --> | ||||
| <td data-t="n" data-v="41246" data-z="yyyy-mm-dd">2012-12-03</td> | ||||
| ``` | ||||
| [**This has been moved to a separate page**](/docs/api/utilities/html#value-override) | ||||
| 
 | ||||
| ## Delimiter-Separated Output | ||||
| 
 | ||||
|  | ||||
| @ -51,6 +51,14 @@ The following are described in [`A1` Utilities](/docs/csf/general#utilities) | ||||
| - `encode_cell / decode_cell` converts cell addresses. | ||||
| - `encode_range / decode_range` converts cell ranges. | ||||
| 
 | ||||
| The following are described in ["HTML" section of "Utility Functions"](/docs/api/utilities/html): | ||||
| 
 | ||||
| **Reading from HTML:** | ||||
| 
 | ||||
| - `table_to_sheet` converts a DOM TABLE element to a worksheet. | ||||
| - `table_to_book` converts a DOM TABLE element to a worksheet. | ||||
| - `sheet_add_dom` adds data from a DOM TABLE element to an existing worksheet. | ||||
| 
 | ||||
| The following are described in the [Utility Functions](/docs/api/utilities): | ||||
| 
 | ||||
| **Constructing:** | ||||
| @ -62,10 +70,8 @@ The following are described in the [Utility Functions](/docs/api/utilities): | ||||
| 
 | ||||
| - `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. | ||||
| - `json_to_sheet` converts an array of JS objects to a worksheet. | ||||
| - `table_to_sheet` converts a DOM TABLE element to a worksheet. | ||||
| - `sheet_add_aoa` adds an array of arrays of JS data to an existing worksheet. | ||||
| - `sheet_add_json` adds an array of JS objects to an existing worksheet. | ||||
| - `sheet_add_dom` adds data from a DOM TABLE element to an existing worksheet. | ||||
| 
 | ||||
| **Exporting:** | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										23
									
								
								docz/static/dom/SheetJSCheerio.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										23
									
								
								docz/static/dom/SheetJSCheerio.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| const XLSX = require("xlsx"); | ||||
| const { readFileSync } = require("fs"); | ||||
| const cheerio = require("cheerio"); | ||||
| 
 | ||||
| /* obtain HTML string.  This example reads from test.html */ | ||||
| const html_str = readFileSync("SheetJSTable.html", "utf8"); | ||||
| /* get first TABLE element */ | ||||
| const $ = cheerio.load(html_str); | ||||
| const doc = $("TABLE").first()[0]; | ||||
| 
 | ||||
| /* FIX THE CHEERIO LIBRARY */ | ||||
| Object.defineProperty(doc.__proto__, "tagName", { get: function() { return Object.entries(this).find(r => r[0] == "tagName" || r[0] == "name")[1].toUpperCase(); }}); | ||||
| Object.defineProperty(doc.__proto__, "rows", { get: function() { return $(this).children("tbody").children("tr"); }}); | ||||
| Object.defineProperty(doc.__proto__, "cells", { get: function() { return $(this).children("td, th"); }}); | ||||
| Object.defineProperty(doc.__proto__, "ownerDocument", { get: function() { return {}; }}); | ||||
| doc.__proto__.hasAttribute = function(name) { return Object.hasOwnProperty.call(this.attribs, name); } | ||||
| doc.__proto__.getAttribute = function(name) { return this.attribs[name]; } | ||||
| Object.defineProperty(doc.__proto__, "innerHTML", { get: function() { return $(this).prop('innerHTML'); }}); | ||||
| doc.__proto__.getElementsByTagName = function(name) { return ($(this).children(name))} | ||||
| 
 | ||||
| /* generate workbook */ | ||||
| const workbook = XLSX.utils.table_to_book(doc); | ||||
| XLSX.writeFile(workbook, "SheetJSCheerio.xlsx"); | ||||
							
								
								
									
										46
									
								
								docz/static/dom/SheetJSTable.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										46
									
								
								docz/static/dom/SheetJSTable.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| <!DOCTYPE html> | ||||
| <!-- vim: set ts=2: --> | ||||
| <html> | ||||
| 
 | ||||
| <head> | ||||
|   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||||
|   <meta http-equiv="Content-Security-Policy" content="script-src 'self' https:"> | ||||
|   <meta name="robots" content="noindex"> | ||||
|   <title>SheetJS Table Example</title> | ||||
| </head> | ||||
| 
 | ||||
| <body> | ||||
|   <table id="data-table"> | ||||
|     <tbody> | ||||
|       <tr> | ||||
|         <td id="data-table-A1"><span contenteditable="true">This</span></td> | ||||
|         <td id="data-table-B1"><span contenteditable="true">is</span></td> | ||||
|         <td id="data-table-C1"><span contenteditable="true">a</span></td> | ||||
|         <td id="data-table-D1"><span contenteditable="true">Test</span></td> | ||||
|       </tr> | ||||
|       <tr> | ||||
|         <td id="data-table-A2"><span contenteditable="true">வணக்கம்</span></td> | ||||
|         <td id="data-table-B2"><span contenteditable="true">สวัสดี</span></td> | ||||
|         <td id="data-table-C2"><span contenteditable="true">你好</span></td> | ||||
|         <td id="data-table-D2"><span contenteditable="true">가지마</span></td> | ||||
|       </tr> | ||||
|       <tr> | ||||
|         <td id="data-table-A3"><span contenteditable="true">1</span></td> | ||||
|         <td id="data-table-B3"><span contenteditable="true">2</span></td> | ||||
|         <td id="data-table-C3"><span contenteditable="true">3</span></td> | ||||
|         <td id="data-table-D3"><span contenteditable="true">4</span></td> | ||||
|       </tr> | ||||
|       <tr> | ||||
|         <td id="data-table-A4"><span contenteditable="true">Click</span></td> | ||||
|         <td id="data-table-B4"><span contenteditable="true">to</span></td> | ||||
|         <td id="data-table-C4"><span contenteditable="true">edit</span></td> | ||||
|         <td id="data-table-D4"><span contenteditable="true">cells</span></td> | ||||
|       </tr> | ||||
|       <tr> | ||||
|         <td colspan="4"><a href="https://sheetjs.com">Generated by SheetJS</a></td> | ||||
|       </tr> | ||||
|     </tbody> | ||||
|   </table> | ||||
| </body> | ||||
| 
 | ||||
| </html> | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user