docs.sheetjs.com/docz/docs/03-demos/11-static/10-astro.md

121 lines
3.2 KiB
Markdown
Raw Normal View History

2023-02-18 02:33:30 +00:00
---
title: AstroJS
pagination_prev: demos/extensions/index
pagination_next: demos/cli
---
:::note
This demo uses ["Base64 Loader"](/docs/demos/static/vitejs#base64-loader)
from the ViteJS demo.
:::
Astro is a site generator. Astro projects use ViteJS under the hood, and Astro
exposes project configuration through the `vite` property in `astro.config.mjs`.
The [ViteJS demo](/docs/demos/static/vitejs) 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.
```js title="astro.config.mjs"
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:
```ts title="src/env.d.ts"
/// <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
```js
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:
```jsx title="src/pages/index.astro"
---
/* -- 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!