forked from sheetjs/docs.sheetjs.com
		
	
		
			
	
	
		
			284 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			284 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								title: ViteJS
							 | 
						||
| 
								 | 
							
								pagination_prev: demos/extensions/index
							 | 
						||
| 
								 | 
							
								pagination_next: demos/gsheet
							 | 
						||
| 
								 | 
							
								sidebar_custom_props:
							 | 
						||
| 
								 | 
							
								  type: bundler
							 | 
						||
| 
								 | 
							
								---
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:::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
							 | 
						||
| 
								 | 
							
								preferable. Since the raw parsing logic is performed in the page,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### 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
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This demo was tested on 2023 January 14 against `vite v4.0.4`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:::
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Initial Setup
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1) Create a new site using the `vue-ts` template:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```bash
							 | 
						||
| 
								 | 
							
								npm create vite@latest sheetjs-vite -- --template vue-ts
							 | 
						||
| 
								 | 
							
								cd sheetjs-vite
							 | 
						||
| 
								 | 
							
								npm install
							 | 
						||
| 
								 | 
							
								npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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/
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The terminal will display a url like http://127.0.0.1:8080.  Access that page
							 | 
						||
| 
								 | 
							
								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.
							 |