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:
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:
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:
<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
This demo was tested in the following environments:
Eleventy | Date |
---|---|
2.0.1 | 2024-03-15 |
3.0.0-alpha.5 | 2024-03-15 |
Project Setup
- Create a new project:
mkdir sheetjs-11ty
cd sheetjs-11ty
npm init -y
- Install Eleventy and SheetJS libraries:
- Stable
- Alpha
npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz @11ty/[email protected]
npm i --save https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz @11ty/[email protected]
- Make a new
_data
subdirectory in the project. Download the example filepres.xlsx
into_data
:
mkdir _data
curl -Lo _data/pres.xlsx https://docs.sheetjs.com/pres.xlsx
- Download the following files to the project folder:
_eleventy.js
(rename to.eleventy.js
)index.njk
curl -L -o .eleventy.js https://docs.sheetjs.com/eleventy/_eleventy.js
curl -LO https://docs.sheetjs.com/eleventy/index.njk
Live Reload
- 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
-
Open the URL in a web browser. The page should include a table.
-
Open
_data/pres.xlsx
in a spreadsheet editor. Add a row to the bottom of the "Sheet1" sheet (setA7
to "SheetJS Dev" andB7
to47
). 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
- Stop the live reload server and build the static site:
npx @11ty/eleventy
Eleventy will place the generated site in the _site
subfolder.
- 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
-
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". ↩
-
See "Custom Data File Formats" in the Eleventy documentation. ↩
-
See "Workbook Object" for more details on the SheetJS workbook object. ↩