Illuminating Data with Lume
Lume is a lightweight unopinionated static site generator. It has a rich ecosystem of JavaScript-powered plugins1
SheetJS is a JavaScript library for reading and writing data from spreadsheets.
This demo uses Lume and SheetJS (through the official "Sheets" plugin) to pull data from a spreadsheet and display the content in an HTML table.
The "Complete Example" section includes a complete website powered by an XLSX spreadsheet.
Integration Details
The official "Sheets" plugin2 uses SheetJS to load data from spreadsheets.
Under the hood, the plugin uses the SheetJS read
3 method to parse files and
the sheet_to_json
4 method to generate arrays of objects.
Lume supports refreshing data during development. The generated static sites include the raw data without referencing the underlying spreadsheet files.
Installation
The sheets
plugin can be imported and invoked in _config.ts
:
import lume from "lume/mod.ts";
import sheets from "lume/plugins/sheets.ts";
const site = lume();
site.use(sheets());
export default site;
The lines are automatically added if sheets
plugin is enabled during setup.
Usage
Spreadsheet files added in the _data
subdirectory are accessible from template
files using the name stem.
For example, pres.xlsx
can be accessed
using the variable pres
in a template.
Single-Sheet Workbooks
When a workbook has one worksheet, the data is an array of row objects:
<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>
Multi-Sheet Workbooks
Reading the First Worksheet
The sheets
plugin accepts an options argument. If the sheets
property is
set to "first"
, then the plugin will expose row objects for the first sheet:
// the first sheet of each file will be parsed and converted to row objects
site.use(sheets({ sheets: "first" }));
Reading all Worksheets
The default behavior, when workbooks have multiple sheets, is to present objects whose keys are worksheet names and whose values are arrays of row objects.
For example, if pres.xlsx
had a sheet named "Presidents"
and another sheet
named "VicePresidents"
, then the following snippet would print data from the
"Presidents"
sheet:
<table><thead><tr><th>Name</th><th>Index</th></tr></thead>
<tbody>
{% for row in pres["Presidents"] %}
<tr>
<td>{{ row.Name }}</td>
<td>{{ row.Index }}</td>
</tr>
{% endfor %}
</tbody>
</table>
File Formats
As explained in the official plugin documentation5, the loader loads XLSX.
NUMBERS, and CSV files. Other extensions can be added through the extensions
property in the argument to the sheets
plugin:
site.use(sheets({
extensions: [".xlsx", ".xlsb", ".xls"]
}));
Complete Example
This demo was tested in the following environments:
Lume | Date |
---|---|
1.19.4 | 2024-03-16 |
2.1.2 | 2024-03-16 |
This example uses the Nunjucks template format. Lume plugins support additional template formats, including Markdown and JSX.
Initial Setup
-
Install Deno6
-
Create a stock site:
mkdir -p sheetjs-lume
cd sheetjs-lume
deno run -Ar https://deno.land/x/[email protected]/init.ts
When prompted, enter the following options:
Choose the configuration file format
: select_config.ts
Do you want to install some plugins now?
: selectYes
Select the plugins to install
: selectsheets
andnunjucks
Do you want to setup a CMS?
: selectMaybe later
The project will be configured and modules will be installed.
The nunjucks
plugin was included by default in Lume version 1.
- Download https://docs.sheetjs.com/pres.xlsx and place in a
_data
subfolder:
mkdir -p _data
curl -L -o _data/pres.xlsx https://docs.sheetjs.com/pres.xlsx
- Create a
index.njk
file that references the file:
<h2>Presidents</h2>
<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>
Since the file name is pres.xlsx
, the parameter name is pres
.
Live Refresh
- Run the development server:
deno task serve --port 7262
To verify the site, access the "Local" URL (typically http://localhost:7262
)
from a web browser. The page will show the contents of the spreadsheet.
- While the server is running, open
_data/pres.xlsx
in a spreadsheet editor.
Set cell A7
to "SheetJS Dev" and set B7
to 47
. Save the spreadsheet.
After saving the spreadsheet, the page will refresh and show the new contents.
Static Site
-
Stop the server (press CTRL+C in the terminal window).
-
Build the static site:
deno task lume
This will create a static site in the _site
folder
- Test the generated site by starting a web server:
npx http-server _site
The program will display a URL (typically http://localhost:8080
). Accessing
the page will show the contents of the spreadsheet.
View the page source and confirm that the page only includes an HTML table. No scripts are included in this page.
This site is self-contained and ready for deployment!
Footnotes
-
See "Installation" in the Deno documentation ↩