DEV Community

Guillermo Contreras
Guillermo Contreras

Posted on

How to generate an Excel report in .NET with zero dependencies

You need to hand a user a real .xlsx file — styled, with a total that's actually
computed. Here's how, in .NET, with Matios.Spreadsheet —
an Office Open XML engine built only on the BCL. Zero dependencies, MIT.

Install

dotnet add package Matios.Spreadsheet
Enter fullscreen mode Exit fullscreen mode

A styled report with a computed total

using Matios.Spreadsheet;
using Matios.Spreadsheet.Styling;

using var pkg = new SpreadsheetPackage();
var s = pkg.Workbook.Worksheets.Add("Sales");

// header row
s["A1"].Value = "Product";
s["B1"].Value = "Revenue";
foreach (var c in new[] { "A1", "B1" })
{
    s[c].Style.Font.Bold = true;
    s[c].Style.Font.Color = Colors.White;
    s[c].Style.Fill.BackgroundColor = Colors.Navy;
}

// data
s["A2"].Value = "Coffee"; s["B2"].Value = 1240;
s["A3"].Value = "Tea";    s["B3"].Value = 980;

// total — the formula is computed in memory, no Excel involved
s["A4"].Value = "Total";
s["B4"].Formula = "SUM(B2:B3)";
pkg.Calculate();
Console.WriteLine(s["B4"].Value);   // 2220

pkg.SaveAs("report.xlsx");
Enter fullscreen mode Exit fullscreen mode

That's a valid .xlsx that opens clean in Excel — no "we found a problem /
repair" prompt. The built-in evaluator handles SUM, AVERAGE, IF, ROUND
and friends, so you get results without opening a spreadsheet app.

Big exports? Stream it

For hundreds of thousands of rows, the streaming path writes each row straight to
the archive and keeps memory flat:

using var wb = StreamingWorkbook.Create("big.xlsx");
var s = wb.AddSheet("Transactions");

for (int i = 1; i <= 1_000_000; i++)
    s.AddRow($"Product {i}", DateTime.Today.AddDays(i % 30), i * 100.0);
Enter fullscreen mode Exit fullscreen mode

On a 1,000,000-cell workbook this is ~3.2× faster and uses ~3.2× less memory than
building the whole model in memory (~1.58M cells/s on my machine — relative,
hardware-dependent).

Read one back

using var loaded = SpreadsheetPackage.Load("report.xlsx");
var sheet = loaded.Workbook.Worksheets[0];

Console.WriteLine(sheet["A2"].Value);    // Coffee
Console.WriteLine(sheet["B4"].Formula);  // SUM(B2:B3)
Enter fullscreen mode Exit fullscreen mode

There's more

Number formats, borders, charts, pivots, conditional formatting, data validation,
images, merged cells and round-trip (parts you didn't touch are preserved).

Docs, examples and benchmarks → spreadsheet.matios.cl.
It's one of a small family of zero-dependency, MIT packages for .NET — the rest at
matios.cl.

If you try it, I'd love your feedback — issues and stars welcome. 🙌

Top comments (0)