| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | title: VueJS | 
					
						
							| 
									
										
										
										
											2023-01-10 00:31:37 +00:00
										 |  |  | pagination_prev: demos/index | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | pagination_next: demos/grid/index | 
					
						
							| 
									
										
										
										
											2023-01-10 00:31:37 +00:00
										 |  |  | sidebar_position: 2 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | import current from '/version.js'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-28 04:57:47 +00:00
										 |  |  | VueJS is a JS library for building user interfaces. | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-25 08:22:28 +00:00
										 |  |  | This demo covers common VueJS data flow ideas and strategies.  Single-File | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | Components (SFC) and VueJS familiarity is assumed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Other demos cover general VueJS deployments, including: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | - [Static Site Generation powered by NuxtJS](/docs/demos/static/nuxtjs) | 
					
						
							| 
									
										
										
										
											2023-01-05 23:33:49 +00:00
										 |  |  | - [iOS and Android applications powered by Quasar](/docs/demos/mobile/quasar) | 
					
						
							|  |  |  | - [Desktop application powered by Tauri](/docs/demos/desktop/tauri) | 
					
						
							| 
									
										
										
										
											2023-04-24 08:50:42 +00:00
										 |  |  | - [`vue3-table-lite` UI component](/docs/demos/grid/vtl) | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Installation
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 05:45:37 +00:00
										 |  |  | [The "Frameworks" section](/docs/getting-started/installation/frameworks) covers | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | installation with Yarn and other package managers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The library can be imported directly from JS or JSX code with: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | import { read, utils, writeFile } from 'xlsx'; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Internal State
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The various SheetJS APIs work with various data shapes.  The preferred state | 
					
						
							|  |  |  | depends on the application. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Array of Objects
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Typically, some users will create a spreadsheet with source data that should be | 
					
						
							|  |  |  | loaded into the site.  This sheet will have known columns.  For example, our | 
					
						
							|  |  |  | [presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" / "Index" columns: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This naturally maps to an array of typed objects, as in the TS example below: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```ts | 
					
						
							|  |  |  | import { read, utils } from 'xlsx'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | interface President { | 
					
						
							|  |  |  |   Name: string; | 
					
						
							|  |  |  |   Index: number; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer(); | 
					
						
							|  |  |  | const wb = read(f); | 
					
						
							|  |  |  | const data = utils.sheet_to_json<President>(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  | console.log(data); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `data` will be an array of objects: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | [ | 
					
						
							|  |  |  |   { Name: "Bill Clinton", Index: 42 }, | 
					
						
							|  |  |  |   { Name: "GeorgeW Bush", Index: 43 }, | 
					
						
							|  |  |  |   { Name: "Barack Obama", Index: 44 }, | 
					
						
							|  |  |  |   { Name: "Donald Trump", Index: 45 }, | 
					
						
							|  |  |  |   { Name: "Joseph Biden", Index: 46 } | 
					
						
							|  |  |  | ] | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | A component will typically map over the data. The following example generates | 
					
						
							|  |  |  | a TABLE with a row for each President: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html title="src/SheetJSVueAoO.vue" | 
					
						
							|  |  |  | <script setup> | 
					
						
							|  |  |  | import { ref, onMounted } from "vue"; | 
					
						
							| 
									
										
										
										
											2022-08-19 06:42:18 +00:00
										 |  |  | import { read, utils, writeFileXLSX } from 'xlsx'; | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | const rows = ref([]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | onMounted(async() => { | 
					
						
							|  |  |  |   /* Download from https://sheetjs.com/pres.numbers */ | 
					
						
							|  |  |  |   const f = await fetch("https://sheetjs.com/pres.numbers"); | 
					
						
							|  |  |  |   const ab = await f.arrayBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* parse workbook */ | 
					
						
							|  |  |  |   const wb = read(ab); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* update data */ | 
					
						
							|  |  |  |   rows.value = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-08-19 06:42:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* get state data and export to XLSX */ | 
					
						
							|  |  |  | function exportFile() { | 
					
						
							|  |  |  |   const ws = utils.json_to_sheet(rows.value); | 
					
						
							|  |  |  |   const wb = utils.book_new(); | 
					
						
							|  |  |  |   utils.book_append_sheet(wb, ws, "Data"); | 
					
						
							|  |  |  |   writeFileXLSX(wb, "SheetJSVueAoO.xlsx"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <template> | 
					
						
							|  |  |  |   <table><thead><th>Name</th><th>Index</th></thead><tbody> | 
					
						
							|  |  |  |     <tr v-for="(row, idx) in rows" :key="idx"> | 
					
						
							|  |  |  |       <td>{{ row.Name }}</td> | 
					
						
							|  |  |  |       <td>{{ row.Index }}</td> | 
					
						
							|  |  |  |     </tr> | 
					
						
							| 
									
										
										
										
											2022-08-19 06:42:18 +00:00
										 |  |  |   </tbody><tfoot><td colSpan={2}> | 
					
						
							|  |  |  |     <button @click="exportFile">Export XLSX</button> | 
					
						
							|  |  |  |   </td></tfoot></table> | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | </template> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | <details open><summary><b>How to run the example</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | :::note | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 08:30:20 +00:00
										 |  |  | This demo was last run on 2023 April 06 using `vue@3.2.47`.  When running | 
					
						
							|  |  |  | `npm init`, the package `create-vue@3.6.1` was installed. | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 08:53:04 +00:00
										 |  |  | 1) Run `npm init vue@latest -- sheetjs-vue --default`. | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 2) Install the SheetJS dependency and start the dev server: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | 
					
						
							| 
									
										
										
										
											2022-11-11 08:53:04 +00:00
										 |  |  | cd sheetjs-vue | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | npm install | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz | 
					
						
							|  |  |  | npm run dev`} | 
					
						
							|  |  |  | </code></pre> | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 3) Open a web browser and access the displayed URL (`http://localhost:5173`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 4) Replace `src/App.vue` with the `src/SheetJSVueAoO.vue` example. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 08:53:04 +00:00
										 |  |  | The page will refresh and show a table with an Export button.  Click the button | 
					
						
							|  |  |  | and the page will attempt to download `SheetJSVueAoA.xlsx`. There may be a delay | 
					
						
							|  |  |  | since Vite will try to optimize the SheetJS library on the fly. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 5) Build the site with `npm run build`, then test with `npx http-server dist`. | 
					
						
							|  |  |  | Access `http://localhost:8080` with a web browser to test the bundled site. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | ### HTML
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The main disadvantage of the Array of Objects approach is the specific nature | 
					
						
							|  |  |  | of the columns.  For more general use, passing around an Array of Arrays works. | 
					
						
							|  |  |  | However, this does not handle merge cells well! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The `sheet_to_html` function generates HTML that is aware of merges and other | 
					
						
							|  |  |  | worksheet features.  VueJS `v-html` attribute allows assignment of `innerHTML` | 
					
						
							|  |  |  | attribute, effectively inserting the code into the page: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html title="src/SheetJSVueHTML.vue" | 
					
						
							|  |  |  | <script setup> | 
					
						
							|  |  |  | import { ref, onMounted } from "vue"; | 
					
						
							| 
									
										
										
										
											2022-08-19 06:42:18 +00:00
										 |  |  | import { read, utils, writeFileXLSX } from 'xlsx'; | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | const html = ref(""); | 
					
						
							| 
									
										
										
										
											2022-08-19 06:42:18 +00:00
										 |  |  | const tableau = ref(); | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | onMounted(async() => { | 
					
						
							|  |  |  |   /* Download from https://sheetjs.com/pres.numbers */ | 
					
						
							|  |  |  |   const f = await fetch("https://sheetjs.com/pres.numbers"); | 
					
						
							|  |  |  |   const ab = await f.arrayBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* parse workbook */ | 
					
						
							|  |  |  |   const wb = read(ab); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* update data */ | 
					
						
							|  |  |  |   html.value = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-08-19 06:42:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* get live table and export to XLSX */ | 
					
						
							|  |  |  | function exportFile() { | 
					
						
							|  |  |  |   const wb = utils.table_to_book(tableau.value.getElementsByTagName("TABLE")[0]) | 
					
						
							|  |  |  |   writeFileXLSX(wb, "SheetJSVueHTML.xlsx"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <template> | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  |   <div ref="tableau" v-html="html"></div> | 
					
						
							| 
									
										
										
										
											2022-08-19 06:42:18 +00:00
										 |  |  |   <button @click="exportFile">Export XLSX</button> | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | </template> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | <details open><summary><b>How to run the example</b> (click to show)</summary> | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | :::note | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-07 08:30:20 +00:00
										 |  |  | This demo was last run on 2023 April 06 using `vue@3.2.47`.  When running | 
					
						
							|  |  |  | `npm init`, the package `create-vue@3.6.1` was installed. | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 08:53:04 +00:00
										 |  |  | 1) Run `npm init vue@latest -- sheetjs-vue --default`. | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 2) Install the SheetJS dependency and start the dev server: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | <pre><code parentName="pre" {...{"className": "language-bash"}}>{`\ | 
					
						
							| 
									
										
										
										
											2022-11-11 08:53:04 +00:00
										 |  |  | cd sheetjs-vue | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | npm install | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz | 
					
						
							|  |  |  | npm run dev`} | 
					
						
							|  |  |  | </code></pre> | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 3) Open a web browser and access the displayed URL (`http://localhost:5173`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 4) Replace `src/App.vue` with the `src/SheetJSVueHTML.vue` example. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 08:53:04 +00:00
										 |  |  | The page will refresh and show a table with an Export button.  Click the button | 
					
						
							|  |  |  | and the page will attempt to download `SheetJSVueHTML.xlsx`. There may be a delay | 
					
						
							|  |  |  | since Vite will try to optimize the SheetJS library on the fly. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 5) Build the site with `npm run build`, then test with `npx http-server dist`. | 
					
						
							|  |  |  | Access `http://localhost:8080` with a web browser to test the bundled site. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-03 21:14:12 +00:00
										 |  |  | </details> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | ### Rows and Columns
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Some data grids and UI components split worksheet state in two parts: an array | 
					
						
							|  |  |  | of column attribute objects and an array of row objects.  The former is used to | 
					
						
							|  |  |  | generate column headings and for indexing into the row objects. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The safest approach is to use an array of arrays for state and to generate | 
					
						
							| 
									
										
										
										
											2022-08-23 03:20:02 +00:00
										 |  |  | column objects that map to A1-Style column headers. | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 08:50:42 +00:00
										 |  |  | The [`vue3-table-lite` demo](/docs/demos/grid/vtl#rows-and-columns-bindings) | 
					
						
							|  |  |  | generates rows and columns objects with the following structure: | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```js | 
					
						
							|  |  |  | /* rows are generated with a simple array of arrays */ | 
					
						
							|  |  |  | rows.value = utils.sheet_to_json(worksheet, { header: 1 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* column objects are generated based on the worksheet range */ | 
					
						
							|  |  |  | const range = utils.decode_range(ws["!ref"]||"A1"); | 
					
						
							|  |  |  | columns.value = Array.from({ length: range.e.c + 1 }, (_, i) => ({ | 
					
						
							|  |  |  |   /* for an array of arrays, the keys are "0", "1", "2", ... */ | 
					
						
							|  |  |  |   field: String(i), | 
					
						
							|  |  |  |   /* column labels: encode_col translates 0 -> "A", 1 -> "B", 2 -> "C", ... */ | 
					
						
							|  |  |  |   label: XLSX.utils.encode_col(i) | 
					
						
							|  |  |  | })); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Legacy Deployments
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-30 05:45:37 +00:00
										 |  |  | [The Standalone Scripts](/docs/getting-started/installation/standalone) play nice | 
					
						
							| 
									
										
										
										
											2022-08-18 08:41:34 +00:00
										 |  |  | with legacy deployments that do not use a bundler. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The legacy demos show a simple VueJS component.  It is written in ES5 syntax. | 
					
						
							|  |  |  | The pages are not minified and "View Source" should be used to inspect. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | - [VueJS version 2](pathname:///vue/index2.html) | 
					
						
							|  |  |  | - [VueJS version 3](pathname:///vue/index3.html) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | There is a shared component [`SheetJS-vue.js`](pathname:///vue/SheetJS-vue.js) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::caution | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The entire demo is designed to run in Internet Explorer and does not reflect | 
					
						
							|  |  |  | modern design patterns. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: |