forked from sheetjs/docs.sheetjs.com
121 lines
3.2 KiB
Markdown
121 lines
3.2 KiB
Markdown
|
---
|
||
|
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!
|