Matios.Spreadsheet
0.1.0
dotnet add package Matios.Spreadsheet --version 0.1.0
NuGet\Install-Package Matios.Spreadsheet -Version 0.1.0
<PackageReference Include="Matios.Spreadsheet" Version="0.1.0" />
<PackageVersion Include="Matios.Spreadsheet" Version="0.1.0" />
<PackageReference Include="Matios.Spreadsheet" />
paket add Matios.Spreadsheet --version 0.1.0
#r "nuget: Matios.Spreadsheet, 0.1.0"
#:package Matios.Spreadsheet@0.1.0
#addin nuget:?package=Matios.Spreadsheet&version=0.1.0
#tool nuget:?package=Matios.Spreadsheet&version=0.1.0
<p align="center"> <img src="./assets/icon.png" alt="Matios.Spreadsheet" width="160"/> </p>
<h1 align="center">Matios.Spreadsheet</h1>
<p align="center"> Dependency-free <code>.xlsx</code> for .NET — read, write and stream Office Open XML,<br> with a fluent, high-level API, styling, charts, pivots and a built-in formula evaluator. </p>
<p align="center"> <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"> <img src="https://img.shields.io/badge/dependencies-0-brightgreen.svg" alt="Zero dependencies"> <img src="https://img.shields.io/badge/.NET-10.0-512BD4.svg" alt=".NET 10"> <img src="https://img.shields.io/badge/tests-97%20passing-brightgreen.svg" alt="97 tests passing"> <img src="https://github.com/MatiosSpa/matios-spreadsheet/actions/workflows/ci.yml/badge.svg" alt="CI"> · <a href="./README.es.md">Español</a> </p>
Excel®is a trademark of Microsoft and is not used in this package. Matios.Spreadsheet builds on the open Office Open XML (.xlsx) standard (ECMA-376), reading and writing the ZIP-of-XML directly.
What is OOXML?
An .xlsx file is not a binary blob — it is an OPC package: a ZIP full of XML parts
(the SpreadsheetML dialect of Office Open XML, standardized as ECMA-376 / ISO 29500).
You don't need Excel installed to produce one — only to read and write ZIP + XML, both of which
ship in the BCL. Matios.Spreadsheet is a small, self-contained engine over exactly that.
Why Matios.Spreadsheet
| Zero dependencies | Built only on the BCL (System.IO.Compression + System.Xml). Nothing else, ever. |
| Own OOXML engine | A small, readable engine you can audit — no third-party library pulled into your build. |
| Read and write | Load real Excel files (values, formulas + cached results, styles) and write them back. |
| Streaming built in | Row-by-row writer/reader with flat memory — ~3× faster and ~3× less memory than the DOM path on a 1M-cell workbook. |
| Computes formulas | A bounded in-memory evaluator (SUM, IF, refs, ranges…) — get results without opening Excel. |
| Round-trips templates | Open a workbook with charts/logos, fill in data, save — the parts you didn't touch are preserved. |
| Verified against Excel | Every feature is validated by opening the generated file in real Excel (no "repair" prompt). |
Quick start
dotnet add package Matios.Spreadsheet
using Matios.Spreadsheet;
using var pkg = new SpreadsheetPackage();
var sheet = pkg.Workbook.Worksheets.Add("Sales");
sheet["A1"].Value = "Product";
sheet["B1"].Value = "Amount";
sheet["A1:B1"].Style.Font.Bold = true;
sheet["A2"].Value = "Coffee";
sheet["B2"].Value = 1500.50;
sheet["B2"].Style.NumberFormat.Format = "#,##0.00";
pkg.SaveAs("sales.xlsx");
Usage
Styling and number formats
using Matios.Spreadsheet.Styling;
var s = pkg.Workbook.Worksheets.Add("Styled");
s["A1"].Value = "Title";
s["A1"].Style.Font.Bold = true;
s["A1"].Style.Font.Size = 14;
s["A1"].Style.Font.Color = Colors.White;
s["A1"].Style.Fill.BackgroundColor = Colors.Navy;
s["A1"].Style.Border.SetAll(BorderStyle.Thin, Colors.Black);
s["A1"].Style.HorizontalAlignment = HorizontalAlignment.Center;
s["B2"].Value = new DateTime(2026, 7, 8);
s["B2"].Style.NumberFormat.Format = "dd/MM/yyyy";
s["C2"].Value = 0.1537;
s["C2"].Style.NumberFormat.Format = "0.0%";
Formulas + the built-in evaluator
s["A1"].Value = 10; s["A2"].Value = 20;
s["A3"].Formula = "SUM(A1:A2)*2"; // stored as text; Excel recalculates on open
pkg.Calculate(); // ...or compute it yourself, no Excel needed
Console.WriteLine(s["A3"].Value); // 60
Supports arithmetic, comparisons, &, cell/range/sheet references, and
SUM AVERAGE MIN MAX COUNT COUNTA IF ROUND ABS AND OR CONCAT (circular refs → #REF!).
Reading
using var loaded = SpreadsheetPackage.Load("sales.xlsx"); // also: Stream, byte[], FileInfo
var sheet = loaded.Workbook.Worksheets[0];
Console.WriteLine(sheet["A2"].Value); // "Coffee"
Console.WriteLine(sheet["B4"].Formula); // "SUM(B2:B3)"
Console.WriteLine(sheet["B4"].Value); // cached result Excel left behind
Streaming (large files, flat memory)
using var wb = StreamingWorkbook.Create("big.xlsx");
var s = wb.AddSheet("Data");
s.AddRow("Product", "Amount");
for (int i = 1; i <= 1_000_000; i++)
s.AddRow($"Product {i}", i * 1.5);
// StreamingReader.Open(...) reads huge files row by row the same way
Tables, conditional formatting, data validation
s.AddTable("A1:C10", "Sales").Style("TableStyleMedium9");
s.AddConditionalFormat("C2:C10").ColorScale(Colors.Red, Colors.Yellow, Colors.Green);
s.AddDataValidation("D2:D10").List("New", "In progress", "Done");
s.FreezePanes(1, 0);
Charts, images and pivots
s.AddChart(ChartType.Column).WithTitle("Sales")
.Categories("Data!A2:A6").AddSeries("Data!B2:B6", "2026").At(1, 5, 15, 12);
s.AddImage("logo.png").MoveTo(1, 1); // one-cell anchor (PNG/JPEG)
report.AddPivotTable("Data!A1:C100", "A1") // basic pivot: sum by category
.RowField("Category").DataField("Amount");
Round-trip a template (preserve what you didn't touch)
using var pkg = SpreadsheetPackage.Load("template-with-chart.xlsx");
pkg.Workbook.Worksheets[0]["B2"].Value = 999; // fill in your data
pkg.SaveAs("filled.xlsx"); // the chart, theme, macros… survive
Feature matrix
| Supported | Not (yet) |
|---|---|
Read/write .xlsx (OOXML) |
.xls (legacy binary), .xlsb |
| Values: text, number, bool, date | — |
| Formulas (as text) + in-memory evaluator | Full Excel function library (bounded set only) |
| Per-cell styles: font, fill, border, number format, alignment | — |
| Merges, column width, row height, outline grouping | — |
| Freeze panes, auto-filter, tables | — |
| Conditional formatting, data validation | — |
| Hyperlinks, comments (notes), defined names, print setup, sheet protection | — |
| Images (PNG/JPEG), charts (column/bar/line/area/pie/scatter) | — |
| Pivot tables (one row field + SUM) | Multiple data/column fields, filters |
| Streaming write & read | — |
| Round-trip passthrough of unknown parts | Re-authoring a loaded file with brand-new objects |
Everything supported is validated by opening the file in real Excel — no repair prompt.
Performance
Two write paths: the DOM (SpreadsheetPackage) builds the whole book in memory (full API:
styles, formulas, charts, pivots, round-trip), and streaming (StreamingWorkbook) writes each
row straight to the ZIP with flat memory. On a 1,000,000-cell workbook (.NET 10 Release):
| Mode | Write | Throughput | Memory |
|---|---|---|---|
DOM (SpreadsheetPackage) |
~2,045 ms | ~0.49 M cells/s | ~877 MB |
Streaming (StreamingWorkbook) |
~631 ms | ~1.58 M cells/s | ~272 MB |
Streaming is ~3.2× faster and allocates ~3.2× less memory — use it for large exports; use the DOM for small/medium workbooks that need the full API. Numbers vary by machine (relative reference, not absolute).
Reproduce with the benchmarks project
(BenchmarkDotNet):
# rigorous run (BenchmarkDotNet + memory diagnoser)
dotnet run -c Release --project benchmarks/Matios.Spreadsheet.Benchmarks
# quick snapshot (Stopwatch + GC): quick [rows] [cols]
dotnet run -c Release --project benchmarks/Matios.Spreadsheet.Benchmarks -- quick 20000 10
More in docs/BENCHMARKS.md.
Repository structure
matios-spreadsheet/
├── README.md · README.es.md · LICENSE
├── assets/ # package icon
├── src/Matios.Spreadsheet/
│ ├── (SpreadsheetPackage, Workbook, Worksheet, Range)
│ ├── Styling/ # CellStyle, Colors, enums
│ ├── Features/ # Table, Chart, Image, PivotTable, DataValidation, ...
│ ├── Streaming/ # StreamingWorkbook / StreamingReader
│ └── Internal/ # the OOXML engine (writer, reader, style/chart/pivot/formula)
├── tests/Matios.Spreadsheet.Tests/
├── samples/Matios.Spreadsheet.Samples/ # runnable examples, one class per scenario
├── benchmarks/Matios.Spreadsheet.Benchmarks/ # BenchmarkDotNet: DOM vs streaming
├── conformance/ # golden fixtures + cases
└── docs/ # design, benchmarks, OOXML notes
Building and running
No special tooling — just the .NET 10 SDK:
dotnet build src/Matios.Spreadsheet/Matios.Spreadsheet.csproj
dotnet test tests/Matios.Spreadsheet.Tests/Matios.Spreadsheet.Tests.csproj
Try the examples — open samples/Matios.Spreadsheet.Samples/Program.cs, uncomment one
example and run it (each writes a .xlsx under bin/.../output):
dotnet run --project samples/Matios.Spreadsheet.Samples
Status
Functionally complete: reading, writing, streaming, styling, formulas, tables, validation, conditional formatting, images, charts, pivots, comments and template round-tripping — all covered by 97 green tests and verified against real Excel. NuGet packaging is the last step before a public release.
Documentation
docs/DESIGN.md— design and the OOXML approach.docs/BENCHMARKS.md— DOM vs streaming numbers.docs/ooxml-notes.md— notes on the.xlsxformat.
Contributing
See CONTRIBUTING.md and the CODE_OF_CONDUCT.md. Issues and pull requests are welcome.
License
MIT © Matios SpA.
💛 Support
Matios.Spreadsheet is free and MIT-licensed. If it saves you time, you can support its ongoing development:
<details> <summary><strong>🪙 Donate with crypto</strong></summary>
<br>
| Network | Address |
|---|---|
| Ethereum / EVM (ETH, USDC, …) | 0x5ea6F302Fb8a9865540FfCC42F7264c996532dC3 |
| Bitcoin (native SegWit) | bc1qv43are3facy6lyuzp5qpdqpt8x7tcz2cx3aspe |
| Solana (SOL, SPL) | BYtfMGEoxBLf5DMPoLyebUJpEh1hW9jGEvjiaEiuRmjw |
| TRON (USDT-TRC20) | TFHuJKpPNZcdEPsfCknDpvY6CzQbpWYGUv |
</details>
Every contribution helps keep the project maintained — thank you 🙏
Español
Prefer Spanish? Read the Spanish version.
<p align="center"> <strong>Matios.Spreadsheet</strong><br> Pure BCL · Own OOXML engine · Verified against Excel. </p>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 119 | 7/10/2026 |