[ANN] gsheetplus — Clojure wrappers for Google Sheets API + template engine

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.

Repo: GitHub - mlimotte/gsheetplus: Low-level and high-level wrapper to work with Google Sheets. Reading, writing and sheet management. · GitHub

Feedback and contributions welcome!

1 Like