--- title: GatsbyJS pagination_prev: demos/extensions/index pagination_next: demos/cloudata/index sidebar_custom_props: type: native --- import current from '/version.js'; Gatsby is a framework for creating websites. It uses React components for page templates and GraphQL for loading data. [`gatsby-transformer-excel`](https://www.gatsbyjs.com/plugins/gatsby-transformer-excel/) is a transformer that generates GraphQL nodes for each row of each worksheet. The plugin is officially supported by the Gatsby team. The plugin documentation includes examples and more detailed usage instructions. :::note `gatsby-transformer-excel` is maintained by the Gatsby core team and all bugs should be directed to the main Gatsby project. If it is determined to be a bug in the parsing logic, issues should then be raised with the SheetJS project. ::: :::caution `gatsby-transformer-excel` uses an older version of the library. It can be overridden through a `package.json` override in the latest versions of NodeJS:
{`\
{
  "overrides": {
    "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
  }
}`}
::: ## GraphQL details `gatsby-transformer-excel` generates nodes for each data row of each worksheet. Under the hood, it uses [`sheet_to_json`](/docs/api/utilities#array-output) to generate row objects using the headers in the first row as keys. ![pres.xlsx](pathname:///pres.png) Assuming the file name is `pres.xlsx` and the data is stored in "Sheet1", the following nodes will be created: ```js [ { Name: "Bill Clinton", Index: 42, type: "PresXlsxSheet1" }, { Name: "GeorgeW Bush", Index: 43, type: "PresXlsxSheet1" }, { Name: "Barack Obama", Index: 44, type: "PresXlsxSheet1" }, { Name: "Donald Trump", Index: 45, type: "PresXlsxSheet1" }, { Name: "Joseph Biden", Index: 46, type: "PresXlsxSheet1" }, ] ``` The type is a proper casing of the file name concatenated with the sheet name. The following query pulls the `Name` and `Index` fields from each row: ```graphql { allPresXlsxSheet1 { # "all" followed by type edges { node { # each line in this block should be a field in the data Name Index } } } } ``` ## GatsbyJS Demo :::note This demo was tested on 2022 November 11 against `create-gatsby@3.0.0`. The generated project used `gatsby@5.0.0` and `react@18.2.0`. ::: ### Project setup 1) Run `npm init gatsby -- -y sheetjs-gatsby` to create the template site. 2) Follow the on-screen instructions for starting the local development server: ```bash cd sheetjs-gatsby npm run develop ``` Open a web browser to the displayed URL (typically `http://localhost:8000/`) 3) Edit `package.json` and add the highlighted lines in the JSON object:
{`\
{
  // highlight-start
  "overrides": {
    "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
  },
  // highlight-end
  "name": "sheetjs-gatsby",
  "version": "1.0.0",
`}
4) Install the library and plugins:
{`\
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
npm i --save gatsby-transformer-excel gatsby-source-filesystem
`}
5) Edit `gatsby-config.js` and add the following lines to the `plugins` array: ```js plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `data`, path: `${__dirname}/src/data/`, }, }, `gatsby-transformer-excel`, ], ``` Stop and restart the development server process (`npm run develop`). 6) Make a `src/data` directory, download , and move the downloaded file into the new folder: ```bash mkdir -p src/data curl -L -o src/data/pres.xlsx https://sheetjs.com/pres.xlsx ``` ### GraphiQL test 7) Open the GraphiQL editor at `http://localhost:8000/___graphql`. There is an editor in the left pane. Paste the following query into the editor: ```graphql { allPresXlsxSheet1 { edges { node { Name Index } } } } ``` Press the Execute Query button and data should show up in the right pane: ![GraphiQL Screenshot](pathname:///gatsby/graphiql.png) ### React page 8) Create a new file `src/pages/pres.js` that uses the query and displays the result: ```jsx title="src/pages/pres.js" import { graphql } from "gatsby" import * as React from "react" export const query = graphql`query { allPresXlsxSheet1 { edges { node { Name Index } } } }`; const PageComponent = ({data}) => { return (
{JSON.stringify(data, 2, 2)}
); }; export default PageComponent; ``` After saving the file, access `http://localhost:8000/pres`. The displayed JSON is the data that the component receives: ```js { "allPresXlsxSheet1": { "edges": [ { "node": { "Name": "Bill Clinton", "Index": 42 } }, // .... ``` 9) Change `PageComponent` to display a table based on the data: ```jsx title="src/pages/pres.js" import { graphql } from "gatsby" import * as React from "react" export const query = graphql`query { allPresXlsxSheet1 { edges { node { Name Index } } } }`; // highlight-start const PageComponent = ({data}) => { const rows = data.allPresXlsxSheet1.edges.map(r => r.node); return ( {rows.map(row => ( ))}
NameIndex
{row.Name} {row.Index}
); }; // highlight-end export default PageComponent; ``` Going back to the browser, `http://localhost:8000/pres` will show a table: ![Data in Table](pathname:///gatsby/table1.png) ### Live refresh 10) Open the file `src/data/pres.xlsx` in Excel or LibreOffice or Numbers. Add a new row at the end of the file: ![New Row in File](pathname:///gatsby/pres2.png) Save the file and notice that the table has refreshed with the new data: ![Updated Table](pathname:///gatsby/table2.png) ### Static site 11) Stop the development server and run `npm run build`. Once the build is finished, the display will confirm that the `/pres` route is static: ``` Pages ┌ src/pages/404.js │ ├ /404/ │ └ /404.html ├ src/pages/index.js │ └ / └ src/pages/pres.js └ /pres/ ╭────────────────────────────────────────────────────────────────╮ │ │ │ (SSG) Generated at build time │ │ D (DSG) Deferred static generation - page generated at runtime │ │ ∞ (SSR) Server-side renders at runtime (uses getServerData) │ │ λ (Function) Gatsby function │ │ │ ╰────────────────────────────────────────────────────────────────╯ ``` The built page will be placed in `public/pres/index.html`. Open the page with a text editor and search for "SheetJS" to verify raw HTML was generated: ```html SheetJS Dev47 ```