Excel · C# walkthrough
A structured expense register
Export expenses as data people can filter and total. The example keeps dates and amounts typed, constrains category and status entry with lists, and freezes the heading area.
- Start with
- Expense dates, categories, amounts, and review status
- Generate
- XLSX

How it works
Preserve data types
Write DateTime and numeric values directly. Apply date and decimal formats for a readable display.
Add entry guidance
Declare validation lists for category and status, then wrap the populated area in an Excel table.
Calculate the total
Use SUM over the amount cells, evaluate the workbook, and render the register. The four sample expenses total 385.15 EUR.
The C# source
This is the complete example file used to generate the download. The walkthrough runner creates the output directory and produces the additional previews.
using System;
using System.IO;
using OfficeIMO.Drawing;
using OfficeIMO.Excel;
namespace OfficeIMO.Examples.Showcase.Workflows;
/// <summary>Builds an expense register with real date cells, currency formats, and list validation.</summary>
internal static class ExpenseRegister {
internal static void Create(string folder) {
using ExcelDocument document = ExcelDocument.Create(Path.Combine(folder, "example.xlsx"));
ExcelSheet sheet = document.AddWorksheet("Expenses");
sheet.MergeRange("A1:E1");
sheet.Cell(1, 1, "September expense register");
sheet.CellFontSize(1, 1, 20);
sheet.CellBold(1, 1, true);
sheet.CellFontColor(1, 1, "17365D");
string[] headers = { "Date", "Description", "Category", "Amount (EUR)", "Status" };
for (int column = 0; column < headers.Length; column++) {
sheet.Cell(4, column + 1, headers[column]);
sheet.SetColumnWidth(column + 1, column == 1 ? 32 : 21);
}
var expenses = new[] {
(Day: 2, Description: "Client workshop travel", Category: "Travel", Amount: 184.50),
(Day: 4, Description: "Training materials", Category: "Training", Amount: 62.00),
(Day: 7, Description: "Project meeting", Category: "Meals", Amount: 48.75),
(Day: 9, Description: "Replacement headset", Category: "Equipment", Amount: 89.90)
};
for (int index = 0; index < expenses.Length; index++) {
int row = index + 5;
var expense = expenses[index];
sheet.Cell(row, 1, new DateTime(2026, 9, expense.Day), numberFormat: "dd mmm yyyy");
sheet.Cell(row, 2, expense.Description);
sheet.Cell(row, 3, expense.Category);
sheet.Cell(row, 4, expense.Amount, numberFormat: "#,##0.00");
sheet.Cell(row, 5, index < 2 ? "Approved" : "Submitted");
}
sheet.AddTable("A4:E8", true, "Expenses", ExcelTableStyle.TableStyleMedium2);
sheet.ValidationList("C5:C8", new[] { "Travel", "Training", "Meals", "Equipment" });
sheet.ValidationList("E5:E8", new[] { "Submitted", "Approved", "Returned" });
sheet.Cell(10, 3, "Total");
sheet.CellFormula(10, 4, "SUM(D5:D8)");
sheet.FormatCell(10, 4, "#,##0.00");
sheet.CellBold(10, 4, true);
sheet.Freeze(topRows: 4);
document.Calculate();
sheet.Range("A1:E12").ExportImage(OfficeImageExportFormat.Png)
.Save(Path.Combine(folder, "preview.png"), OfficeImageExportFileConflictPolicy.Replace);
document.Save();
}
}
Open the C# source fileRun it from the source checkout
Clone the OfficeIMO repository and run this command from its root with the .NET 10 SDK. The first run restores the example project's dependencies.
dotnet run --project OfficeIMO.Examples -f net10.0 -- --showcase-workflows --showcase-example excel-expense-registerThe files are written to OfficeIMO.Examples/bin/Debug/net10.0/Documents/Workflows/excel-expense-register/. To use the example in your application, start with the Excel guide and its package setup.
Downloads and scope
What the preview shows
The linked C# example generates this file. The runner reopens and validates the XLSX. The image is a native rendering of the specified worksheet range.
What to keep in mind
Dropdown validation guides entry in a spreadsheet application. It is not a security boundary or an expense approval service.