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)