| 
									
										
										
										
											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-05-07 13:58:36 +00:00
										 |  |  | import CodeBlock from '@theme/CodeBlock'; | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 01:36:15 +00:00
										 |  |  | The following diagram depicts the workbook waltz: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```mermaid | 
					
						
							|  |  |  | flowchart LR | 
					
						
							|  |  |  |   file[(workbook\nfile)] | 
					
						
							|  |  |  |   subgraph SheetJS operations | 
					
						
							|  |  |  |     base64(base64\nstring) | 
					
						
							|  |  |  |     aoo(array of\nobjects) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  |   html{{HTML\nTABLE}} | 
					
						
							|  |  |  |   file --> |astro.config.mjs\nvite data loader| base64 | 
					
						
							|  |  |  |   base64 --> |index.astro\nfrontmatter| aoo | 
					
						
							|  |  |  |   aoo --> |index.astro\ntemplate body| html | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-02 02:17:56 +00:00
										 |  |  | :::warning Telemetry | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Astro enables telemetry by default. The tool has an option to disable telemetry: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```bash | 
					
						
							|  |  |  | npx astro telemetry disable | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ::: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2023-06-03 09:10:50 +00:00
										 |  |  |   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-05-07 13:58:36 +00:00
										 |  |  | <CodeBlock language="bash">{`\ | 
					
						
							| 
									
										
										
										
											2023-04-27 09:12:19 +00:00
										 |  |  | npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`} | 
					
						
							| 
									
										
										
										
											2023-05-07 13:58:36 +00:00
										 |  |  | </CodeBlock> | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 03:40:40 +00:00
										 |  |  | Open a web browser and access the displayed URL ( `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. |