| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | --- | 
					
						
							|  |  |  | title: ViteJS | 
					
						
							| 
									
										
										
										
											2023-02-28 11:40:44 +00:00
										 |  |  | pagination_prev: demos/net/index | 
					
						
							|  |  |  | pagination_next: demos/mobile/index | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | sidebar_custom_props: | 
					
						
							|  |  |  |   type: bundler | 
					
						
							|  |  |  | --- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | import current from '/version.js'; | 
					
						
							| 
									
										
										
										
											2023-04-30 12:27:09 +00:00
										 |  |  | import CodeBlock from '@theme/CodeBlock'; | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | :::note | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This demo covers static asset imports. For processing files in the browser, the | 
					
						
							|  |  |  | ["Bundlers" demo](/docs/demos/bundler#vite) includes an example. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Loaders
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ViteJS supports static asset imports, but the default raw loader interprets data | 
					
						
							|  |  |  | as UTF-8 strings.  This corrupts binary formats like XLSX and XLS, but a custom | 
					
						
							|  |  |  | loader can override the default behavior. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note Recommendation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For simple tables of data, ["Pure Data Loader"](#pure-data-loader) is strongly | 
					
						
							|  |  |  | recommended.  The heavy work is performed at build time and the generated site | 
					
						
							|  |  |  | only includes the raw data. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For more complex parsing or display logic, ["Base64 Loader"](#base64-loader) is | 
					
						
							| 
									
										
										
										
											2023-04-30 12:27:09 +00:00
										 |  |  | preferable. Since the raw parsing logic is performed in the page, the library | 
					
						
							|  |  |  | will be included in the final bundle. | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Pure Data Loader
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | For a pure static site, a plugin can load data into an array of row objects. The | 
					
						
							|  |  |  | SheetJS work is performed in the plugin. The library is not loaded in the page! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="vite.config.js" | 
					
						
							|  |  |  | import { readFileSync } from 'fs'; | 
					
						
							|  |  |  | import { read, utils } from 'xlsx'; | 
					
						
							|  |  |  | import { defineConfig } from 'vite'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default defineConfig({ | 
					
						
							|  |  |  |   assetsInclude: ['**/*.xlsx'], // xlsx file should be treated as assets | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   plugins: [ | 
					
						
							|  |  |  |     { // this plugin handles ?sheetjs tags | 
					
						
							|  |  |  |       name: "vite-sheet", | 
					
						
							|  |  |  |       transform(code, id) { | 
					
						
							|  |  |  |         if(!id.match(/\?sheetjs$/)) return; | 
					
						
							|  |  |  |         var wb = read(readFileSync(id.replace(/\?sheetjs$/, ""))); | 
					
						
							|  |  |  |         var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |         return `export default JSON.parse('${JSON.stringify(data)}')`; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   ] | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This loader uses the query `sheetjs`: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="main.js" | 
					
						
							|  |  |  | import data from './data.xlsx?sheetjs'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | document.querySelector('#app').innerHTML = `<div><pre> | 
					
						
							|  |  |  | ${data.map(row => JSON.stringify(row)).join("\n")} | 
					
						
							|  |  |  | </pre></div>`; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Base64 Loader
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This loader pulls in data as a Base64 string that can be read with `XLSX.read`. | 
					
						
							|  |  |  | While this approach works, it is not recommended since it loads the library in | 
					
						
							|  |  |  | the front-end site. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="vite.config.js" | 
					
						
							|  |  |  | import { readFileSync } from 'fs'; | 
					
						
							|  |  |  | import { defineConfig } from 'vite'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default defineConfig({ | 
					
						
							|  |  |  |   assetsInclude: ['**/*.xlsx'], // mark that xlsx file should be treated as assets | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   plugins: [ | 
					
						
							|  |  |  |     { // this plugin handles ?b64 tags | 
					
						
							|  |  |  |       name: "vite-b64-plugin", | 
					
						
							|  |  |  |       transform(code, id) { | 
					
						
							|  |  |  |         if(!id.match(/\?b64$/)) return; | 
					
						
							|  |  |  |         var path = id.replace(/\?b64/, ""); | 
					
						
							|  |  |  |         var data = readFileSync(path, "base64"); | 
					
						
							|  |  |  |         return `export default '${data}'`; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   ] | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When importing using the `b64` query, the raw Base64 string will be exposed. | 
					
						
							|  |  |  | This can be read directly with `XLSX.read` in JS code: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="main.js" | 
					
						
							|  |  |  | import { read, utils } from "xlsx"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* reference workbook */ | 
					
						
							|  |  |  | import b64 from './data.xlsx?b64'; | 
					
						
							|  |  |  | /* parse workbook and export first sheet to CSV */ | 
					
						
							|  |  |  | const wb = read(b64); | 
					
						
							|  |  |  | const wsname = wb.SheetNames[0]; | 
					
						
							|  |  |  | const csv = utils.sheet_to_csv(wb.Sheets[wsname]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | document.querySelector('#app').innerHTML = `<div><pre> | 
					
						
							|  |  |  | <b>${wsname}</b> | 
					
						
							|  |  |  | ${csv} | 
					
						
							|  |  |  | </pre></div>`; | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ## Complete Demo
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :::note | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-30 12:27:09 +00:00
										 |  |  | This demo was tested on 2023 April 30 against `vite v4.3.3`. | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Initial Setup
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-30 12:27:09 +00:00
										 |  |  | 1) Create a new site with the `vue-ts` template and install the SheetJS package: | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-30 12:27:09 +00:00
										 |  |  | <CodeBlock language="bash">{`\ | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | npm create vite@latest sheetjs-vite -- --template vue-ts | 
					
						
							|  |  |  | cd sheetjs-vite | 
					
						
							|  |  |  | npm install | 
					
						
							| 
									
										
										
										
											2023-04-30 12:27:09 +00:00
										 |  |  | npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | 
					
						
							|  |  |  | </CodeBlock> | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 2) Replace `vite.config.ts` with the following: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```js title="vite.config.ts" | 
					
						
							|  |  |  | import { defineConfig } from 'vite' | 
					
						
							|  |  |  | import vue from '@vitejs/plugin-vue' | 
					
						
							|  |  |  | import { readFileSync } from 'fs'; | 
					
						
							|  |  |  | import { read, utils } from 'xlsx'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default defineConfig({ | 
					
						
							|  |  |  |   assetsInclude: ['**/*.xlsx'], // xlsx file should be treated as assets | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   plugins: [ | 
					
						
							|  |  |  |     vue(), | 
					
						
							|  |  |  |     { // this plugin handles ?sheetjs tags | 
					
						
							|  |  |  |       name: "vite-sheet", | 
					
						
							|  |  |  |       transform(code, id) { | 
					
						
							|  |  |  |         if(!id.match(/\?sheetjs$/)) return; | 
					
						
							|  |  |  |         var wb = read(readFileSync(id.replace(/\?sheetjs$/, ""))); | 
					
						
							|  |  |  |         var data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); | 
					
						
							|  |  |  |         return `export default JSON.parse('${JSON.stringify(data)}')`; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     { // this plugin handles ?b64 tags | 
					
						
							|  |  |  |       name: "vite-b64-plugin", | 
					
						
							|  |  |  |       transform(code, id) { | 
					
						
							|  |  |  |         if(!id.match(/\?b64$/)) return; | 
					
						
							|  |  |  |         var path = id.replace(/\?b64/, ""); | 
					
						
							|  |  |  |         var data = readFileSync(path, "base64"); | 
					
						
							|  |  |  |         return `export default '${data}'`; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   ] | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) Make a `data` folder and download <https://sheetjs.com/pres.xlsx> : | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | mkdir -p data | 
					
						
							|  |  |  | curl -L -o data/pres.xlsx https://sheetjs.com/pres.xlsx | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Pure Data Test
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 4) Run the dev server: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | npm run dev | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Open a browser window to the displayed URL (typically http://localhost:5173 ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 5) Replace the component `src/components/HelloWorld.vue` with: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html title="src/components/HelloWorld.vue" | 
					
						
							|  |  |  | <script setup lang="ts"> | 
					
						
							|  |  |  | // @ts-ignore | 
					
						
							|  |  |  | import data from '../../data/pres.xlsx?sheetjs'; | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <template> | 
					
						
							|  |  |  |   <table> | 
					
						
							|  |  |  |     <tr><th>Name</th><th>Index</th></tr> | 
					
						
							|  |  |  |     <tr v-for="(row,R) in data" v-bind:key="R"> | 
					
						
							|  |  |  |       <td>{{row.Name}}</td> | 
					
						
							|  |  |  |       <td>{{row.Index}}</td> | 
					
						
							|  |  |  |     </tr> | 
					
						
							|  |  |  |   </table> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Save and refresh the page.  A data table should be displayed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 6) Stop the dev server and build the site | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | npm run build | 
					
						
							|  |  |  | npx http-server dist/ | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-30 12:27:09 +00:00
										 |  |  | The terminal will display a url like `http://127.0.0.1:8080` . Access that page | 
					
						
							| 
									
										
										
										
											2023-01-15 03:36:13 +00:00
										 |  |  | with a web browser. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 7) To confirm that only the raw data is present in the page, view the page | 
					
						
							|  |  |  | source.  The code will reference some script like `/assets/index-HASH.js`. | 
					
						
							|  |  |  | Open that script.  Searching for `Bill Clinton` reveals the following: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | JSON.parse('[{"Name":"Bill Clinton","Index":42} | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Searching for `BESSELJ` should reveal no results.  The SheetJS scripts are not | 
					
						
							|  |  |  | included in the final site! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Base64 Test
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 8) Run the dev server: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | npm run dev | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Open a browser window to the displayed URL. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 9) Replace the component `src/components/HelloWorld.vue` with: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```html title="src/components/HelloWorld.vue" | 
					
						
							|  |  |  | <script setup lang="ts"> | 
					
						
							|  |  |  | // @ts-ignore | 
					
						
							|  |  |  | import b64 from '../../data/pres.xlsx?b64'; | 
					
						
							|  |  |  | import { read, utils } from "xlsx"; | 
					
						
							|  |  |  | /* parse workbook and convert first sheet to row array */ | 
					
						
							|  |  |  | const wb = read(b64); | 
					
						
							|  |  |  | const ws = wb.Sheets[wb.SheetNames[0]]; | 
					
						
							|  |  |  | interface IPresident { Name: string; Index: number; }; | 
					
						
							|  |  |  | const data = utils.sheet_to_json<IPresident>(ws); | 
					
						
							|  |  |  | </script> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <template> | 
					
						
							|  |  |  |   <table> | 
					
						
							|  |  |  |     <tr><th>Name</th><th>Index</th></tr> | 
					
						
							|  |  |  |     <tr v-for="(row,R) in data" v-bind:key="R"> | 
					
						
							|  |  |  |       <td>{{row.Name}}</td> | 
					
						
							|  |  |  |       <td>{{row.Index}}</td> | 
					
						
							|  |  |  |     </tr> | 
					
						
							|  |  |  |   </table> | 
					
						
							|  |  |  | </template> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 10) Stop the dev server and build the site | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | npm run build | 
					
						
							|  |  |  | npx http-server dist/ | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The terminal will display a url like http://127.0.0.1:8080.  Access that page | 
					
						
							|  |  |  | with a web browser. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 11) To confirm that only the raw data is present in the page, view the page | 
					
						
							|  |  |  | source.  The code will reference some script like `/assets/index-HASH.js`. | 
					
						
							|  |  |  | Open that script.  Searching for `Bill Clinton` should yield no results. | 
					
						
							|  |  |  | Searching for `BESSELJ` should match the code: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 425:"BESSELJ" | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The SheetJS library is embedded in the final site. |