Skip to main content
ClaudeWave
Kookerella-Ltd avatar
Kookerella-Ltd

Kookerella.FsOpenXmlDsl

View on GitHub

A typesafe F# DSL for building and reading Excel workbooks, with round-trip read/write and F# code generation.

ToolsOfficial Registry0 stars0 forksF#MITUpdated today
ClaudeWave Trust Score
87/100
Trusted
Passed
  • Open-source license (MIT)
  • Actively maintained (<30d)
  • Clear description
  • Documented (README)
Last scanned: 8/24/2026
Get started
Method: Clone
Terminal
git clone https://github.com/Kookerella-Ltd/Kookerella.FsOpenXmlDsl
1. Clone the repository.
2. Follow the README for installation and usage instructions.
Use cases

Tools overview

# Kookerella.FsOpenXmlDsl

A typesafe F# DSL for building Excel workbooks, interpreted into calls against the
[DocumentFormat.OpenXml](https://github.com/dotnet/Open-XML-SDK) SDK. The DSL is a plain
data model (records/DUs with structural equality) — the interpreter (`Writer`) compiles it
to OOXML, and the reverse transform (`Reader`) parses an existing `.xlsx` back into the
same DSL.

See [MAPPING.md](MAPPING.md) for exactly which SpreadsheetML features map 1:1, which are
approximated, and which aren't modeled yet.

## Layout

- `src/Kookerella.FsOpenXmlDsl` — the library.
  - `Reference.fs` — `CellRef` and `"A1"`-style address conversions.
  - `Styles.fs` — cell formatting: `Color`, `FontStyle`, `FillStyle`, `BorderStyle`,
    `AlignmentStyle`, `NumberFormat`, `CellProtection`, `CellStyle`.
  - `Validation.fs` — conditional formatting and data validation: `ComparisonOperator`
    (shared by both), `ConditionalFormatRule`, `ValidationKind`, `ValidationAlert`, and the
    `ConditionalFormatEntry`/`DataValidationEntry` records stored on `Worksheet`.
  - `Hyperlinks.fs` — `HyperlinkTarget` (external URL/`mailto:` vs. internal same-workbook
    reference) and the `HyperlinkEntry` record stored on `Worksheet`.
  - `Comments.fs` — `CommentEntry` (classic cell comments, i.e. current Excel's "Notes" -
    see MAPPING.md for the modern threaded-comments gap).
  - `Protection.fs` — `SheetProtection`, the sheet-level protection flags stored on
    `Worksheet` (pairs with `CellStyle.Protection` for per-cell locking), and
    `WorkbookProtection`, the workbook-level structure/window protection flags stored on
    `Workbook`.
  - `DefinedNames.fs` — `DefinedNameScope`/`DefinedNameEntry`, stored on `Workbook` rather
    than `Worksheet` - the one DSL concept that's genuinely workbook-level.
  - `PageSetup.fs` — print settings: `PageOrientation`, `PaperSize`, `PrintScaling`,
    `PageMargins`, and the `PageSetup` record stored on `Worksheet`.
  - `Tables.fs` — Excel Tables: `TableColumn`, `TableStyle`, and the `TableEntry` record
    stored as a list on `Worksheet` (a sheet can have several).
  - `Sparklines.fs` — in-cell mini-charts: `SparklineType`, `SparklineStyle`,
    `SparklineCell`, and the `SparklineGroupEntry` record stored as a list on `Worksheet`
    (a sheet can have several independently-styled groups).
  - `Charts.fs` — column/bar/line/pie charts: `ChartType`, `ChartSeries`, and the
    `ChartEntry` record stored as a list on `Worksheet` (a sheet can have several).
  - `Images.fs` — raster images: `ImageFormat` and the `ImageEntry` record (raw file
    bytes plus a cell-range anchor) stored as a list on `Worksheet`.
  - `PivotTables.fs` — `PivotAggregation` and the `PivotTableEntry` record (source range,
    row/column/value fields, an anchor cell) stored as a list on `Worksheet`.
  - `Model.fs` — `CellValue`, `Cell`, `Worksheet`, `Workbook` (including `Workbook.
    VbaProject`, a macro-enabled workbook's raw `vbaProject.bin` bytes - see its own doc
    comment; there's no dedicated `Macros.fs` since it's a single opaque field, not a new
    type).
  - `Builders.fs` — ergonomic helpers: plain functional constructors (`cellA1`, ...) for
    the canonical model, plus the `SheetItem`/`CellEntry` types (each a single simple DU
    case with optional fields) and the `sheet` fold function - a small tree-shaped "AST
    for building a sheet" (rows of cells, plus sheet-level facts like column widths,
    merges, conditional formats, data validations, hyperlinks, comments, autofilter, and
    sheet protection) that mirrors how SpreadsheetML itself nests. `SheetDsl` is what you
    actually write against: `cell`/`row`/`autoFilter`/`conditionalFormat`/
    `dataValidation`/`hyperlink`/`comment` members with real optional parameters (`?col`,
    `?style`, `?index`, the data validation alert fields, `?tooltip`, `?author`) - no
    builder objects, no separate "styled" function, no `None`-noise for the common case.
    (`Protect` is the one `SheetItem` case with no smart constructor - `SheetProtection`
    is a plain record you build the usual F# way, `{ SheetProtection.Default with ... }`.)
  - `Interpreter/StyleRegistry.fs` — interns fonts/fills/borders/number formats into a
    shared OOXML stylesheet (internal).
  - `Interpreter/ChartWriter.fs` / `ChartReader.fs` — charts' own DSL ↔ DrawingML/ChartML
    translation, split out from `Writer.fs`/`Reader.fs` given how much larger that one
    feature's OOXML surface is than everything else combined (internal).
  - `Interpreter/ImageWriter.fs` / `ImageReader.fs` — images' own DSL ↔ DrawingML
    translation (internal).
  - `Interpreter/DrawingWriter.fs` / `DrawingReader.fs` — own the one `DrawingsPart`/
    `<drawing>` relationship a worksheet gets when it has charts and/or images, since both
    features share that one drawing canvas rather than each managing their own (internal).
  - `Interpreter/PivotTableWriter.fs` / `PivotTableReader.fs` — pivot tables' own group-by
    + aggregate engine plus DSL ↔ OOXML translation (`pivotCacheDefinition`/
    `pivotCacheRecords`/`pivotTableDefinition`), split out from `Writer.fs`/`Reader.fs` the
    same way charts and images are (internal).
  - `Interpreter/Writer.fs` — DSL → OOXML (internal).
  - `Interpreter/Reader.fs` — OOXML → DSL, the reverse transform (internal).
  - `Interpreter/CodeGen.fs` — DSL → F# *source text*: renders a `Workbook` back out as a
    self-contained `.fsx` script that rebuilds an equivalent file when run (internal).
  - `Api.fs` — the public `Workbook.save` / `saveToStream` / `load` / `loadFromStream` /
    `generateScript` entry points.
- `tests/Kookerella.FsOpenXmlDsl.Tests` — one test per feature, each validating the produced file
  against the OOXML schema (`DocumentFormat.OpenXml.Validation.OpenXmlValidator`) and
  asserting an exact round trip back through the DSL. Each test also writes the workbook
  it builds to `Examples/<test name>/output.xlsx` (checked into the repo), so every
  feature has a real, openable `.xlsx` demonstrating it - a browsable gallery, not just
  assertions. Each scenario also gets an `Examples/<test name>/script.fsx` - see
  "Regenerating a file as F# source" below - which a separate, slower `Category=Slow` test
  group actually executes via `dotnet fsi` and verifies against the committed `.xlsx`.
  `Assets/` holds the one test fixture too large to inline as a base64 literal like every
  other binary fixture in `Tests.fs` - a real `vbaProject.bin` extracted from a workbook
  actually saved by Excel, used by the macro example.
- `samples/Kookerella.FsOpenXmlDsl.Sample` — a small console app that builds a workbook, saves it,
  and reads it back.
- `src/Kookerella.CsOpenXmlDsl` — an idiomatic, immutable, fluent C# wrapper over this
  library, for callers who'd rather not touch F# discriminated unions/option types
  directly. Deliberately narrow first pass (cell values, formulas, basic styling, `Save`/
  `Load`) - see its own README for scope and an example. `tests/Kookerella.CsOpenXmlDsl.Tests`
  is its own C# xUnit suite, exercising the wrapper the way a real C# caller would rather
  than reusing the F# test project.
- `src/Kookerella.FsOpenXmlDsl.Mcp` — a local MCP (Model Context Protocol) server exposing
  this library's read/write/code-generation capabilities as tools any MCP-compatible AI
  agent can call directly - see its own README for the tool list and how to configure it.

## Quick start

```fsharp
open Kookerella.FsOpenXmlDsl
open type Kookerella.FsOpenXmlDsl.SheetDsl

let headerStyle =
    { CellStyle.Default with
        Font = Some { FontStyle.Default with Bold = true }
        Fill = Some { Color = Rgb(220uy, 220uy, 220uy) } }

let data =
    sheet
        "Sheet1"
        [ row [ cell (Text "Name", style = headerStyle)
                cell (Text "Amount", style = headerStyle) ]
          row [ cell (Text "Widgets")
                cell (Number 42.5, style = { CellStyle.Default with NumberFormat = Some TwoDecimal }) ]
          Freeze(1, 0) ]

workbook [ data ] |> Workbook.save "out.xlsx"

// Reverse transform:
let roundTripped = Workbook.load "out.xlsx"
```

`CellEntry` and `SheetItem`'s row case are each a single simple DU case with optional
fields (`Col`/`Index`) rather than separate "styled" or "explicit position" cases - `None`
means "the next column/row after the previous entry" (starting at 0), `Some n` jumps there
explicitly and sequential numbering resumes right after it. You don't construct the case
directly, though: `SheetDsl.cell`/`SheetDsl.row` are members with real optional
parameters (`?col`/`?style` on `cell`, `?index` on `row`) that hide the `None`s for
the common case - plain `let` functions can't have optional parameters in F#, which is why
this one bit of the DSL is a type. `open type Kookerella.FsOpenXmlDsl.SheetDsl` (alongside `open Kookerella.FsOpenXmlDsl`) brings `cell`/`row`
into scope unqualified, same as a module. Explicit column/row jumps go through the same
two members, just with the optional argument supplied: `cell (value, col = 2)` and
`row (cells, index = 4)`. `sheet` is the one fold that interprets the resulting item
list into the canonical `Worksheet` (the same relationship `Writer` has to OOXML). If you
already have cells pre-addressed by `CellRef` rather than grouped by row, `sheetOfCells`
builds a `Worksheet` directly from a flat `Cell list` instead.

**A `Formula` cell is `Formula(expression, cachedValue: float option)` - this library never
evaluates formulas itself, so `cachedValue` is the only number that will ever exist for that
cell until something else computes one.** Real Excel recalculates on open and overwrites it,
so leaving it `None` is fine if a human always opens the result in Excel first. It's *not*
safe for a headless pipeline - e.g. generating a workbook and piping it straight into a PDF
converter, another automated reader, or anything else that never opens it in real Excel.
Whether that downstream step shows

What people ask about Kookerella.FsOpenXmlDsl

What is Kookerella-Ltd/Kookerella.FsOpenXmlDsl?

+

Kookerella-Ltd/Kookerella.FsOpenXmlDsl is tools for the Claude AI ecosystem. A typesafe F# DSL for building and reading Excel workbooks, with round-trip read/write and F# code generation. It has 0 GitHub stars and its last recorded update is dated 2026-08-23.

How do I install Kookerella.FsOpenXmlDsl?

+

You can install Kookerella.FsOpenXmlDsl by cloning the repository (https://github.com/Kookerella-Ltd/Kookerella.FsOpenXmlDsl) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is Kookerella-Ltd/Kookerella.FsOpenXmlDsl safe to use?

+

Our security agent has analyzed Kookerella-Ltd/Kookerella.FsOpenXmlDsl and assigned a Trust Score of 87/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.

Who maintains Kookerella-Ltd/Kookerella.FsOpenXmlDsl?

+

Kookerella-Ltd/Kookerella.FsOpenXmlDsl is maintained by Kookerella-Ltd. The last recorded GitHub activity is dated 2026-08-23, with 0 open issues.

Are there alternatives to Kookerella.FsOpenXmlDsl?

+

Yes. On ClaudeWave you can browse similar tools at /categories/tools, sorted by popularity or recent activity.

Deploy Kookerella.FsOpenXmlDsl to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: Kookerella-Ltd/Kookerella.FsOpenXmlDsl
[![Featured on ClaudeWave](https://claudewave.com/api/badge/kookerella-ltd-kookerella-fsopenxmldsl)](https://claudewave.com/repo/kookerella-ltd-kookerella-fsopenxmldsl)
<a href="https://claudewave.com/repo/kookerella-ltd-kookerella-fsopenxmldsl"><img src="https://claudewave.com/api/badge/kookerella-ltd-kookerella-fsopenxmldsl" alt="Featured on ClaudeWave: Kookerella-Ltd/Kookerella.FsOpenXmlDsl" width="320" height="64" /></a>