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! |