5.9 KiB
title | pagination_prev | pagination_next |
---|---|---|
AstroJS | demos/net/index | demos/mobile/index |
:::note
This demo uses "Base64 Loader" from the ViteJS demo.
:::
Astro is a site generator. Astro projects use ViteJS under the hood. They expose
project configuration through the vite
property in astro.config.mjs
. The
ViteJS demo examples work as expected!
Integration
:::note
The ViteJS demo used the query ?b64
to identify files. To play nice with
Astro, this demo matches the file extensions directly.
:::
Since Astro performs per-page heavy lifting at build time, it is recommended to use the Base64 string loader to get file data and parse with the SheetJS library in the relevant pages. If the SheetJS operations are performed in frontmatter, only the results will be added to the generated pages!
Loader
The loader should be added to astro.config.mjs
under the vite
key.
import { readFileSync } from 'fs';
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
// this tells astro which extensions to handle
assetsInclude: ['**/*.numbers', '**/*.xlsx'],
plugins: [
{ // this plugin presents the data as a Base64 string
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/env.d.ts
.
This data loader returns Base64 strings:
/// <reference types="astro/client" />
declare module '*.numbers' {
const data: string;
export default data;
}
declare module '*.xlsx' {
const data: string;
export default data;
}
Astro Frontmatter
Typically projects store files in src/pages
. Assuming pres.numbers
is stored
in the src/data
directory in the project, the relative import
import b64 from "../data/pres.numbers"
will return a Base64 string which can be parsed in the frontmatter. The workbook
object can be post-processed using utility functions. The following example
uses sheet_to_json
to generate row objects that are rendered as table rows:
---
/* -- the code in the frontmatter is only run at build time -- */
import { read, utils } from "xlsx";
/* parse workbook */
import b64 from "../data/pres.numbers";
const wb = read(b64, {type: "base64"});
/* generate row objects */
interface IPresident {
Name: string;
Index: number;
}
const data = utils.sheet_to_json<IPresident>(wb.Sheets[wb.SheetNames[0]]);
---
<html>
<body>
<h3>Presidents</h3>
<table>
<thead><tr><th>Name</th><th>Index</th></tr></thead>
{/* Display each row object as a TR within the TBODY element */}
<tbody>{data.map(row => (
<tr><td>{row.Name}</td><td>{row.Index}</td></tr>
))}</tbody>
</table>
</body>
</html>
When built using npx astro build
, Astro 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 February 21 using AstroJS v2.0.14
:::
- Disable Astro telemetry:
npx astro telemetry disable
- Create a new site using the
docs
template:
npm create astro@latest -- --template docs --yes ./sheetjs-astro
cd sheetjs-astro
- Fetch the example file
pres.numbers
:
mkdir -p src/data
curl -Lo src/data/pres.numbers https://sheetjs.com/pres.numbers
- Install the SheetJS library:
npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
- Replace
src/pages/index.astro
with the following:
---
/* -- the code in the frontmatter is only run at build time -- */
import { read, utils } from "xlsx";
/* parse workbook */
import b64 from "../data/pres.numbers";
const wb = read(b64, {type: "base64"});
/* generate row objects */
interface IPresident {
Name: string;
Index: number;
}
const data = utils.sheet_to_json<IPresident>(wb.Sheets[wb.SheetNames[0]]);
---
<html>
<body>
<h3>Presidents</h3>
<table>
<thead><tr><th>Name</th><th>Index</th></tr></thead>
<tbody>
{data.map(row => (<tr>
<td>{row.Name}</td><td>{row.Index}</td>
</tr>))}
</tbody>
</table>
</body>
</html>
- Append the following lines to
src/env.d.ts
:
/* add to the end of the file */
declare module '*.numbers' {
const data: string;
export default data;
}
declare module '*.xlsx' {
const data: string;
export default data;
}
- Add the highlighted lines to
astro.config.mjs
:
// highlight-start
/* import `readFileSync` at the top of the script*/
import { readFileSync } from 'fs';
// highlight-end
import { defineConfig } from 'astro/config';
export default defineConfig({
// highlight-start
/* this vite section should be added as a property of the object */
vite: {
// this tells astro which extensions to handle
assetsInclude: ['**/*.numbers', '**/*.xlsx'],
plugins: [
{ // this plugin presents the data as a Base64 string
name: "sheet-base64",
transform(code, id) {
if(!id.match(/\.(numbers|xlsx)$/)) return;
var data = readFileSync(id, "base64");
return `export default '${data}'`;
}
}
]
},
// highlight-end
integrations: [
- Build the static site:
npx astro build
AstroJS will place the generated site in the dist
subfolder.
- Start a web server to host the static site:
npx http-server dist
Open a web browser and access the displayed URL (usually http://localhost:8080). View the page source and confirm that no JS was added to the page. It only contains the content from the file in an HTML table.