login
Holden Web
What you'll need to know tomorrow

The specification language

A specification is a TOML file with an [extract] table mapping the output keys you want to the values to pull from the spreadsheet:

[extract]
title  = "Summary!B2"                     # a single cell    -> scalar
hours  = "{Hours}"                        # a 2-column range -> object
prices = "{Prices | int}"                 # object, values coerced to int
sales  = "[Sales | records]"              # a table          -> list of objects
people = "[Grid | transpose | records]"   # a pipeline of transforms

Each value is an extraction expression: a reference to part of the workbook, optionally followed by a pipeline of functions.

The same expressions read Excel workbooks (.xlsx) and OpenDocument spreadsheets (.ods) alike — EDJAS chooses by file extension and nothing in a specification depends on which it is. That matters for public-sector data in particular, where some publications are released only as ODS: the MHCLG local-authority revenue outturn tables, for instance, have no Excel edition at all. An ODS file is a zip of XML, so reading one needs no dependency beyond the standard library. Named ranges defined in an ODS file are resolved exactly as Excel defined names are.

The three forms

Written asProducesFor example
ref the value of a single cell title = "Summary!B2"
[ref] the range as a list, or a list of row-lists tags = "[Tags]"
{ref} a two-column range as an object hours = "{Hours}"

The three kinds of reference

KindWritten asNotes
named range Prices survives layout changes; the recommended form
Excel Table name RevisionTriangles_Table1 the table's whole range, header included, wherever it lives
A1 range Summary!D3:E9 explicit coordinates, optionally sheet-qualified

Named ranges and tables are recommended over bare cell references: they survive layout changes. This also fits the way well-produced government and statistical spreadsheets are built, where the published data is laid out as named Excel Tables.

Resolution order is defined name, then table name, then a raw A1 reference. Excel keeps defined names and table names in one namespace and forbids collisions, so the order rarely matters in practice.

Quoting sheet names

A sheet name containing spaces or punctuation must be wrapped in single quotes, exactly as Excel writes it:

title  = "'Cover Sheet'!A1"
answer = "'Bob''s Data'!C3"     # an embedded apostrophe is doubled

The two kinds of quote mean different things inside an expression, and it is worth being precise about them:

Sheet names and defined names are matched case-insensitively, as Excel does.

Formula cells

A cell containing a formula yields its computed value, not the formula text, so extracting a total or an average works as you would expect. EDJAS reads the value Excel cached the last time it saved the workbook.

One consequence is worth knowing: a workbook that has never been recalculated in Excel — one produced entirely by another tool, say — has no cached value, and such a cell reads as null.

What is not supported

Multi-area (union) references — A1:A5,C1:C5, or a named range defined as one — are deliberately unsupported. A union has no single rectangular shape, so it has no unambiguous mapping to JSON. EDJAS reports it clearly rather than guessing; give each block its own key instead, which produces better-named output anyway.