6.5 KiB
title | pagination_prev | pagination_next |
---|---|---|
SvelteKit | demos/net/index | demos/mobile/index |
import current from '/version.js';
:::note
This demo covers SvelteKit. The Svelte demo covers general client-side strategies.
This demo uses "Base64 Loader" from the ViteJS demo.
:::
SvelteKit projects use ViteJS under the hood. They expose the vite.config.js
script. The ViteJS demo examples work as expected!
The following diagram depicts the workbook waltz:
flowchart LR
file[(workbook\nfile)]
subgraph SheetJS operations
base64(base64\nstring)
aoa(array of\nobjects)
end
html{{HTML\nTABLE}}
file --> |vite.config.js\ndata loader| base64
base64 --> |+page.server.js\nload function| aoa
aoa --> |+page.svelte\ncomponent| html
Integration
+page.server.js
scripts can be pre-rendered by exporting prerender
from the
script. If the SheetJS operations are performed in the server script, only the
results will be added to the generated pages!
For static site generation, @sveltejs/adapter-static
must be used.
Loader
:::note
The ViteJS demo used the query ?b64
to identify files. To play nice with
SvelteKit, this demo matches the file extensions directly.
:::
The loader should be added to vite.config.js
. The code is nearly identical to
the "Base64 Loader" ViteJS example.
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import { readFileSync } from 'fs';
export default defineConfig({
assetsInclude: ['**/*.numbers', '**/*.xlsx'],
plugins: [sveltekit(), {
name: "sheet-base64",
transform(code, id) {
if(!id.match(/\.(numbers|xlsx)$/)) return;
var data = readFileSync(id, "base64");
return `export default '${data}'`;
}
}]
});
Types
For VSCodium integration, types can be specified in src/app.d.ts
.
The example data loader returns Base64 strings. Declarations should be added for each file extension supported in the loader:
declare global {
declare module '*.numbers' {
const data: string;
export default data;
}
declare module '*.xlsx' {
const data: string;
export default data;
}
}
Data Processing
For static sites, SheetJS operations should be run in +page.server.js
.
Assuming pres.xlsx
is stored in the data
directory from the project root,
the relative import
import b64 from "../../data/pres.xlsx"
will return a Base64 string which can be parsed in the script. The workbook
object can be post-processed using utility functions. The following example
uses sheet_to_json
to generate arrays of row objects for each worksheet. The
data presented to the page will be an object whose keys are worksheet names:
import b64 from "../../data/pres.xlsx";
import { read, utils } from "xlsx";
export const prerender = true;
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
const wb = read(b64);
/** @type {[string, any[]][]} */
const data = wb.SheetNames.map(n => [n, utils.sheet_to_json(wb.Sheets[n])]);
return Object.fromEntries(data);
}
Data Rendering
The shape of the data is determined by the loader. The example loader returns an object whose keys are worksheet names and whose values are arrays of objects.
Using standard Svelte patterns, HTML tables can be generated from the data:
<script>
/** @type {import('./$types').PageData} */
export let data;
/* `pres` will be the data from Sheet1 */
/** @type {Array<{Name: string, Index: number}>}*/
export let pres = data["Sheet1"];
</script>
<h1>Presidents</h1>
<table><thead><th>Name</th><th>Index</th></thead><tbody>
{#each pres as p}<tr>
<td>{p.Name}</td>
<td>{p.Index}</td>
</tr>{/each}
</tbody></table>
When built using npm run build
, SvelteKit will perform the conversion and emit
a simple HTML table without any reference to the existing spreadsheet file!
Complete Example
:::note
This demo was tested on 2023 April 30 using SvelteKit 1.15.9
:::
Initial Setup
- Create a new site:
npm create svelte@latest sheetjs-svelte
cd sheetjs-svelte
npm i
When prompted:
Which Svelte app template?
selectSkeleton Project
Add type checking with TypeScript?
selectYes, using JavaScript with JSDoc
Select additional options
press Enter (do not select options)
- Fetch the example file
pres.xlsx
and move to adata
subdirectory in the root of the project:
mkdir -p data
curl -Lo data/pres.xlsx https://sheetjs.com/pres.xlsx
- Install the SheetJS library:
{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
-
Replace the contents of
vite.config.js
with the contents of the code block namedvite.config.js
in the "Loader" section -
Append the lines from
src/app.d.ts
snippet in the "Types" section to thesrc/app.d.ts
file. -
Replace the contents of
src/routes/+page.server.ts
with the contents of the code block namedsrc/routes/+page.server.ts
in "Data Processing" -
Replace the contents of
src/routes/+page.svelte
with the contents of the code block namedsrc/routes/+page.svelte
in "Data Rendering"
Live Reload
-
Open
data/pres.xlsx
in a spreadsheet editor like Apple Numbers or Excel. -
Start the development server:
npm run dev
Open the displayed URL (typically http://localhost:5173
) in a web browser and
observe that the data from the spreadsheet is displayed in the page.
- In the spreadsheet, set cell A7 to
SheetJS Dev
and cell B7 to47
. Save the file. After saving, the browser should automatically refresh with new data.
Static Site
- Stop the development server and install the static adapter:
npm install --save @sveltejs/adapter-static
- Edit
svelte.config.js
to use the new adapter:
-import adapter from '@sveltejs/adapter-auto';
+import adapter from '@sveltejs/adapter-static';
- Build the static site:
npm run build
- Open a web browser and access the displayed URL (
http://localhost:8080
). View the page source and confirm that the raw HTML table includes the data.