2023-02-18 02:33:30 +00:00
|
|
|
---
|
|
|
|
title: AstroJS
|
2023-02-28 11:40:44 +00:00
|
|
|
pagination_prev: demos/net/index
|
|
|
|
pagination_next: demos/mobile/index
|
2023-02-18 02:33:30 +00:00
|
|
|
---
|
|
|
|
|
2023-04-27 09:12:19 +00:00
|
|
|
import current from '/version.js';
|
|
|
|
|
2023-02-18 02:33:30 +00:00
|
|
|
:::note
|
|
|
|
|
|
|
|
This demo uses ["Base64 Loader"](/docs/demos/static/vitejs#base64-loader)
|
|
|
|
from the ViteJS demo.
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
2023-02-22 04:38:10 +00:00
|
|
|
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](/docs/demos/static/vitejs) examples work as expected!
|
2023-02-18 02:33:30 +00:00
|
|
|
|
|
|
|
## 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!
|
|
|
|
|
2023-02-22 04:38:10 +00:00
|
|
|
### Loader
|
2023-02-18 02:33:30 +00:00
|
|
|
|
|
|
|
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' {
|
2023-04-18 20:26:59 +00:00
|
|
|
const data: string;
|
|
|
|
export default data;
|
2023-02-18 02:33:30 +00:00
|
|
|
}
|
|
|
|
declare module '*.xlsx' {
|
2023-04-18 20:26:59 +00:00
|
|
|
const data: string;
|
|
|
|
export default data;
|
2023-02-18 02:33:30 +00:00
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2023-02-22 04:38:10 +00:00
|
|
|
### Astro Frontmatter
|
2023-02-18 02:33:30 +00:00
|
|
|
|
|
|
|
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!
|
2023-02-22 04:38:10 +00:00
|
|
|
|
|
|
|
## Complete Example
|
|
|
|
|
|
|
|
:::note
|
|
|
|
|
|
|
|
This demo was tested on 2023 February 21 using AstroJS `v2.0.14`
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
0) Disable Astro telemetry:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npx astro telemetry disable
|
|
|
|
```
|
|
|
|
|
|
|
|
1) Create a new site using the `docs` template:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npm create astro@latest -- --template docs --yes ./sheetjs-astro
|
|
|
|
cd sheetjs-astro
|
|
|
|
```
|
|
|
|
|
|
|
|
2) Fetch the example file [`pres.numbers`](https://sheetjs.com/pres.numbers):
|
|
|
|
|
|
|
|
```bash
|
|
|
|
mkdir -p src/data
|
|
|
|
curl -Lo src/data/pres.numbers https://sheetjs.com/pres.numbers
|
|
|
|
```
|
|
|
|
|
|
|
|
3) Install the SheetJS library:
|
|
|
|
|
2023-04-27 09:12:19 +00:00
|
|
|
<pre><code parentName="pre" {...{"className": "language-bash"}}>{`\
|
|
|
|
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
|
|
|
</code></pre>
|
2023-02-22 04:38:10 +00:00
|
|
|
|
|
|
|
4) Replace `src/pages/index.astro` with the following:
|
|
|
|
|
|
|
|
```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>
|
|
|
|
<tbody>
|
|
|
|
{data.map(row => (<tr>
|
|
|
|
<td>{row.Name}</td><td>{row.Index}</td>
|
|
|
|
</tr>))}
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
```
|
|
|
|
|
|
|
|
5) Append the following lines to `src/env.d.ts`:
|
|
|
|
|
|
|
|
```ts title="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;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
6) Add the highlighted lines to `astro.config.mjs`:
|
|
|
|
|
|
|
|
```js title="astro.config.mjs"
|
2023-02-24 07:46:48 +00:00
|
|
|
// highlight-start
|
|
|
|
/* import `readFileSync` at the top of the script*/
|
|
|
|
import { readFileSync } from 'fs';
|
|
|
|
// highlight-end
|
|
|
|
import { defineConfig } from 'astro/config';
|
|
|
|
|
|
|
|
|
2023-02-22 04:38:10 +00:00
|
|
|
export default defineConfig({
|
|
|
|
// highlight-start
|
2023-02-24 07:46:48 +00:00
|
|
|
/* this vite section should be added as a property of the object */
|
2023-02-22 04:38:10 +00:00
|
|
|
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: [
|
|
|
|
```
|
|
|
|
|
|
|
|
7) Build the static site:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npx astro build
|
|
|
|
```
|
|
|
|
|
|
|
|
AstroJS will place the generated site in the `dist` subfolder.
|
|
|
|
|
|
|
|
8) Start a web server to host the static site:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
npx http-server dist
|
|
|
|
```
|
|
|
|
|
|
|
|
Open a web browser and access the displayed URL (usually http://localhost:8080).
|
2023-04-19 20:03:23 +00:00
|
|
|
View the page source and confirm that no JS was added to the page. It only
|
2023-04-24 08:50:42 +00:00
|
|
|
contains the content from the file in an HTML table.
|