Skip to main content

Eleventy

Eleventy is a telemetry-free static site generator. The data pipeline can be augmented with custom data file parsers.

SheetJS is a JavaScript library for reading and writing data from spreadsheets.

This demo uses Eleventy and SheetJS to pull data from a spreadsheet and display the content in a page. We'll explore how to load SheetJS libraries in a custom data file format parser and generate arrays of objects for use in pages.

The following diagram depicts the workbook waltz:

No Telemetry

The author has publicly stated that Eleventy does not embed any telemetry or data collection.1

Integration Details

The SheetJS NodeJS module can be loaded in .eleventy.js and used in custom data file format parsers.

Data File Parser

Custom data file parsers must be registered in .eleventy.js

The Eleventy config addDataExtension method2 accepts a list of file extensions and a parser configuration object.

The parser object must include the options read: true and encoding: null . Eleventy will read files and pass raw Buffer objects to the parser callback.

The parser callback can parse the raw Buffer data with the SheetJS read method3. The method returns a workbook object4.

In this example, the parser will use the SheetJS sheet_to_json method5 to generate an array of objects from the data in the first worksheet:

.eleventy.js
const XLSX = require("xlsx");

/* list of file extensions */
const exts = [ "numbers", "xlsx", "xlsb", "xls" ].join(", ");

module.exports = (eleventyConfig) => {
eleventyConfig.addDataExtension(exts, {
/* read file and pass raw Buffer object to parser */
encoding: null, read: true,

/* parser callback */
parser: (contents) => {
/* contents is the data stored as a Buffer */
const wb = XLSX.read(contents);
/* generate array of row objects from first worksheet */
return XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
}
});
};

Usage

Spreadsheet files added in the _data subdirectory are accessible from template files using the name stem.

For example, pres.numbers can be accessed using the variable pres in a template:

index.njk
<table><thead><tr><th>Name</th><th>Index</th></tr></thead>
<tbody>
{% for row in pres %}
<tr>
<td>{{ row.Name }}</td>
<td>{{ row.Index }}</td>
</tr>
{% endfor %}
</tbody>
</table>

Complete Example

Tested Deployments

This demo was tested in the following environments:

EleventyDate
2.0.12024-03-15
3.0.0-alpha.52024-03-15

Project Setup

  1. Create a new project:
mkdir sheetjs-11ty
cd sheetjs-11ty
npm init -y
  1. Install Eleventy and SheetJS libraries:
npm i --save https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz @11ty/[email protected]
  1. Make a new _data subdirectory in the project. Download the example file pres.xlsx into _data:
mkdir _data
curl -Lo _data/pres.xlsx https://sheetjs.com/pres.xlsx
  1. Download the following files to the project folder:
curl -L -o .eleventy.js https://docs.sheetjs.com/eleventy/_eleventy.js
curl -LO https://docs.sheetjs.com/eleventy/index.njk

Live Reload

  1. Start the live reloading server:
npx @11ty/eleventy --serve

The server will generate index.html from index.njk and show the server URL:

[11ty] Writing _site/index.html from ./index.njk
[11ty] Wrote 1 file in 0.23 seconds (v2.0.1)
[11ty] Watching…
[11ty] Server at http://localhost:8080/ <-- this is the URL
  1. Open the URL in a web browser. The page should include a table.

  2. Open _data/pres.xlsx in a spreadsheet editor. Add a row to the bottom of the "Sheet1" sheet (set A7 to "SheetJS Dev" and B7 to 47). Save the file.

The server log will note that the file changed:

[11ty] File changed: _data/pres.xlsx
[11ty] Writing _site/index.html from ./index.njk

The browser will refresh to show the new data.

Static Site

  1. Stop the live reload server and build the static site:
npx @11ty/eleventy

Eleventy will place the generated site in the _site subfolder.

  1. Start a web server to host the static site:
npx http-server _site

Open a web browser and access the displayed URL ( http://localhost:8080 ). View the page source and confirm that no JS was added to the page. It only contains the content from the file in an HTML table.

Footnotes

  1. See the "Telemetry" section of the site generator review from the author of Eleventy. When this page was last checked, the author proudly asserted that Eleventy had "No known Telemetry or data collection".

  2. See "Custom Data File Formats" in the Eleventy documentation.

  3. See read in "Reading Files"

  4. See "Workbook Object" for more details on the SheetJS workbook object.

  5. See sheet_to_json in "Utilities"