Hi all,
I’d like to share gsheetplus, a Clojure library for working with Google Sheets. It provides both low-level API access and higher-level abstractions for common tasks.
Reading Sheets as Data
table/read-single-table reads a sheet into a seq of maps with automatic header normalization — “First Name” becomes :first-name:
(require '[gsheetplus.table :as table])
(table/read-single-table service spreadsheet-id “Sheet1” {})
;; => ({:first-name “Alice” :age 30} {:first-name “Bob” :age 25} …)
Options for filtering, stopping on blank rows, dropping metadata rows, and more. There’s also read-single-table-with-info for sheets that have key-value parameter rows above the
table, and split-tables for multi-section sheets.
For lower-level access, core/read-as-vec-vec returns raw vectors of vectors with automatic type coercion, and core/get-range gives you the underlying Google API response
directly.
Writing
Batch updates, grid writes with 0-based indexing, insert-and-populate, and append — all through a straightforward API.
Alloy — Template / Document Generation
The part I’m most excited about. Alloy is a template engine that uses Jinja-like syntax directly in Google Sheets cells. It evaluates expressions against a Clojure context map
and writes results back in place, preserving formatting:
(alloy/render-google-sheet service spreadsheet-id “Sheet1”
{:name “Alice”
:items [{:sku “A1” :qty 3} {:sku “B2” :qty 7}]}
nil)
Template cells support {{ expr }} for value substitution, {% for %} / {% if %} control flow that duplicates or removes rows, filters via {{ price | round:2 }}, dot-notation for
nested access, and custom extensions. Errors are collected rather than thrown, so you get a clean report of any issues.
This makes Google Sheets a practical target for report generation, invoices, or any structured document where non-technical users maintain the template layout.
Other bits
- Extensible cell-type conversion protocol (LocalDate, BigDecimal/currency, etc.)
- OpenTelemetry spans emitted automatically for I/O operations (no-ops if the agent isn’t present)
- Auth helper that takes any InputStream — works with file paths, classpath resources, or secrets managers
LLM / AI Agent Workflow
One use case I didn’t expect: these tools have been really helpful when working with LLMs. If your agent has access to a REPL or clj command line, Google Sheets turns out to be
a convenient way to get structured data into and out of the LLM context with minimal fuss — read a sheet as maps, transform, write results back. I use this regularly during
development.
Feedback and contributions welcome!