--- title: ViteJS Spreadsheet Plugins sidebar_class_name: red sidebar_label: ViteJS description: Make static websites from spreadsheets using ViteJS. Seamlessly integrate data into your website using SheetJS. Empower non-technical people to write content from Excel. pagination_prev: demos/net/index pagination_next: demos/mobile/index sidebar_custom_props: type: bundler --- import current from '/version.js'; import CodeBlock from '@theme/CodeBlock'; [ViteJS](https://vitejs.dev/) is a build tool for generating static websites. It has a robust JavaScript-powered plugin system[^1]. [SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing data from spreadsheets. This demo uses ViteJS and SheetJS to pull data from a spreadsheet and display the content in an HTML table. We'll explore how to load SheetJS in a ViteJS plugin and evaluate data loading strategies. The ["Complete Demo"](#complete-demo) section creates a complete website powered by a XLSX spreadsheet. :::info pass This demo covers use cases where data is available at build time. This flow is suitable for end of week or end of month (EOM) reports published in HTML tables. For processing user-submitted files in the browser, the [ViteJS "Bundlers" demo](/docs/demos/frontend/bundler/vitejs) shows client-side bundling of SheetJS libraries. The ["ReactJS" demo](/docs/demos/frontend/react) shows example sites using ViteJS with the ReactJS starter. ::: ## Plugins ViteJS supports static asset imports[^2], but the default raw loader interprets data as UTF-8 strings. This corrupts binary formats including XLSX and XLS. A custom loader can bypass the raw loader and directly read files. Since a custom loader must be used, some data processing work can be performed by the loader. Three approaches are explored in this demo. The following diagrams show the ViteJS data flow. The pink "Main Script import" boxes represent the division between the loader and the main script. The green "SheetJS Operations" boxes represent the steps performed by SheetJS libraries.
| [HTML](#html-plugin) | [Data](#pure-data-plugin) | [Base64](#base64-plugin) |
|---|---|---|
| ```mermaid flowchart TB file[(workbook\nfile)] buffer(NodeJS\nBuffer) sheetjs[[SheetJS Operations]] tabeller{{HTML\nString}} handoff[[Main Script import]] html{{HTML\nTABLE}} style handoff fill:#FFC7CE style sheetjs fill:#C6EFCE file --> buffer buffer --> sheetjs sheetjs --> tabeller tabeller --> handoff handoff --------> html ``` | ```mermaid flowchart TB file[(workbook\nfile)] buffer(NodeJS\nBuffer) sheetjs[[SheetJS Operations]] aoo(array of\nobjects) handoff[[Main Script import]] import(array of\nobjects) html{{HTML\nTABLE}} style handoff fill:#FFC7CE style sheetjs fill:#C6EFCE file --> buffer buffer --> sheetjs sheetjs --> aoo aoo --> handoff handoff ------> import import --> html ``` | ```mermaid flowchart TB file[(workbook\nfile)] base64(Base64\nString) handoff[[Main Script import]] import(Base64\nString) sheetjs[[SheetJS Operations]] aoo(array of\nobjects) html{{HTML\nTABLE}} style handoff fill:#FFC7CE style sheetjs fill:#C6EFCE file --> base64 base64 ------> handoff handoff --> import import --> sheetjs sheetjs --> aoo aoo --> html ``` |
| Name | Index |
|---|---|
| ${row.Name} | ${row.Index} |
| Name | Index |
|---|---|
| ${row.Name} | ${row.Index} |
| Name | Index |
|---|---|
| {{row.Name}} | {{row.Index}} |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
**As it affects the project template, this is a bug in ViteJS.**
The simplest workaround is to force upgrade the `vue-tsc` dependency:
```bash
npm i vue-tsc@latest
```
:::
7) To confirm that only the raw data is present in the page, view the page
source. The code will reference a script `/assets/index-HASH.js` where `HASH` is
a string of characters. Open that script.
Searching for `Bill Clinton` reveals the following:
```js
{"Name":"Bill Clinton","Index":42}
```
Searching for `BESSELJ` should reveal no results. The SheetJS scripts are not
included in the final site!
:::info pass
ViteJS also supports "Server-Side Rendering". In SSR, only the HTML table
would be added to the final page. Details are covered in the ViteJS docs[^10].
:::
### HTML Test
8) Run the dev server:
```bash
npm run dev
```
Open a browser window to the displayed URL (typically `http://localhost:5173` )
9) Replace the component `src/components/HelloWorld.vue` with:
```html title="src/components/HelloWorld.vue"
```
Save and refresh the page. A data table should be displayed
10) Stop the dev server and build the site
```bash
npm run build
npx http-server dist/
```
The terminal will display a URL, typically `http://127.0.0.1:8080` . Access
that page with a web browser.
:::caution pass
When this demo was tested against ViteJS `2.9.18`, the build failed:
```
src/App.vue:8:3 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
8
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
**As it affects the project template, this is a bug in ViteJS.**
The simplest workaround is to force upgrade the `vue-tsc` dependency:
```bash
npm i vue-tsc@latest
```
:::
11) To confirm that only the raw HTML is present in the page, view the page
source. The code will reference a script `/assets/index-HASH.js` where `HASH` is
a string of characters. Open that script.
Searching for `Bill Clinton` reveals the following encoded HTML element:
```
| Name | Index |
|---|---|
| {{row.Name}} | {{row.Index}} |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
**As it affects the project template, this is a bug in ViteJS.**
The simplest workaround is to force upgrade the `vue-tsc` dependency:
```bash
npm i vue-tsc@latest
```
:::
15) To confirm that the object data is not present in the page, view the page
source. The code will reference a script `/assets/index-HASH.js` where `HASH` is
a string of characters. Open that script.
Searching for `BESSELJ` should match the code:
```
425:"BESSELJ"
```
Searching for `Bill Clinton` should yield no results. The SheetJS library is
embedded in the final site and the data is parsed when the page is loaded.
[^1]: See ["Using Plugins"](https://vitejs.dev/guide/using-plugins.html) in the ViteJS documentation.
[^2]: See ["Static Asset Handling"](https://vitejs.dev/guide/assets.html) in the ViteJS documentation.
[^3]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^4]: See [`sheet_to_html` in "Utilities"](/docs/api/utilities/html#html-table-output)
[^5]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^6]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
[^7]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^8]: See [the "base64" type in "Reading Files"](/docs/api/parse-options#input-type)
[^9]: See [`examples/sheetjs-vite`](https://git.sheetjs.com/examples/sheetjs-vite/) on the SheetJS Git server.
[^10]: See ["Server-Side Rendering"](https://vitejs.dev/guide/ssr.html) in the ViteJS documentation.