FormulaEngineer — A Highly Accurate Excel Formula Engine with support for 315+ Excel functions — explore the complete list new · v1.0.1

FormulaEngineer Examples

Create Excel workbooks with formulas, then read and evaluate those formulas in .NET.

Introduction

FormulaEngineer is a .NET library for creating Excel workbooks, reading their contents, and evaluating formula cells without Excel or COM automation. These examples show the create, read, and evaluate patterns most .NET applications need.

Every read/evaluate sample on this page follows the same shape: open the workbook with ExcelReader, open a worksheet by name, then call EvaluateCell on the formula location.

Quick start

Install the NuGet package, then open an existing .xlsx file and evaluate a formula cell. The example below assumes the worksheet is named Data and that a formula lives in cell A4.

Get FormulaEngineer on NuGet

Read and evaluate
Program.cs
using FormulaEngineer.Api;

using var reader    = new ExcelReader("sum.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");
var result = evaluator.EvaluateCell(sheet, row: 4, col: 1);

Console.WriteLine(result);

SUM formula workbook

Basic formulas

Create a workbook with three numbers and a SUM formula, then reopen the workbook and evaluate the formula cell.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("sum.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow(10);
sheet.WriteRow(20);
sheet.WriteRow(30);
sheet.WriteRow(ExcelFormula.From("SUM(A1:A3)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("sum.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");
var result = evaluator.EvaluateCell(sheet, row: 4, col: 1);

Console.WriteLine(result);

AVERAGE formula workbook

Basic formulas

Write a column of scores into a worksheet and use AVERAGE to compute the mean, then reopen and evaluate the cell.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("average.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Student", "Score");
sheet.WriteRow("Alice",   80);
sheet.WriteRow("Bob",     65);
sheet.WriteRow("Carol",   90);
sheet.WriteRow("Dave",    70);
sheet.WriteRow("Eve",     85);
sheet.WriteRow("Average", ExcelFormula.From("AVERAGE(B2:B6)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("average.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");
var result = evaluator.EvaluateCell(sheet, row: 7, col: 2);

Console.WriteLine(result);

MIN and MAX workbook

Basic formulas

Write a column of values and use MIN and MAX to find the smallest and largest values in the range.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("min-max.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Day",     "Sales");
sheet.WriteRow("Mon",     120);
sheet.WriteRow("Tue",      95);
sheet.WriteRow("Wed",     180);
sheet.WriteRow("Thu",     140);
sheet.WriteRow("Fri",     210);
sheet.WriteRow("Lowest",  ExcelFormula.From("MIN(B2:B6)"));
sheet.WriteRow("Highest", ExcelFormula.From("MAX(B2:B6)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("min-max.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");

var lowest  = evaluator.EvaluateCell(sheet, row: 7, col: 2);
var highest = evaluator.EvaluateCell(sheet, row: 8, col: 2);

Console.WriteLine($"Lowest:  {lowest}");
Console.WriteLine($"Highest: {highest}");

IF status workbook

Basic formulas

Use IF to mark a score as Pass or Fail depending on whether it meets a threshold.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("if-status.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Student", "Score", "Status");
sheet.WriteRow("Alice",   80, ExcelFormula.From("IF(B2>=60,\"Pass\",\"Fail\")"));
sheet.WriteRow("Bob",     45, ExcelFormula.From("IF(B3>=60,\"Pass\",\"Fail\")"));
sheet.WriteRow("Carol",   90, ExcelFormula.From("IF(B4>=60,\"Pass\",\"Fail\")"));
sheet.WriteRow("Dave",    55, ExcelFormula.From("IF(B5>=60,\"Pass\",\"Fail\")"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("if-status.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");

for (int row = 2; row <= 5; row++)
{
    var name   = evaluator.EvaluateCell(sheet, row: row, col: 1);
    var status = evaluator.EvaluateCell(sheet, row: row, col: 3);
    Console.WriteLine($"{name}: {status}");
}

Invoice formulas workbook

Basic formulas

Create an invoice worksheet with line totals, subtotal, tax, and final total formulas, then evaluate the final total.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("invoice.xlsx");
using var sheet = writer.CreateWorksheet("Invoice");

sheet.WriteRow("Item",     "Qty", "Unit Price", "Line Total");
sheet.WriteRow("Widget",    4,    25.00, ExcelFormula.From("B2*C2"));
sheet.WriteRow("Gadget",    2,    80.00, ExcelFormula.From("B3*C3"));
sheet.WriteRow("Cable",    10,     3.50, ExcelFormula.From("B4*C4"));
sheet.WriteRow("Subtotal", "", "", ExcelFormula.From("SUM(D2:D4)"));
sheet.WriteRow("Tax (8%)", "", "", ExcelFormula.From("D5*0.08"));
sheet.WriteRow("Total",    "", "", ExcelFormula.From("D5+D6"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("invoice.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Invoice");
var total = evaluator.EvaluateCell(sheet, row: 7, col: 4);

Console.WriteLine(total);

Read formula text from a workbook

Read workbook

Create a workbook with a formula cell, reopen it, read the original formula text, and evaluate the formula result.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("formula-text.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow(10);
sheet.WriteRow(20);
sheet.WriteRow(30);
sheet.WriteRow(ExcelFormula.From("SUM(A1:A3)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;
using System.Linq;

using var reader = new ExcelReader("formula-text.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

string formulaText;
object? result;

using (var sheet = reader.OpenWorksheet("Data"))
{
    var lastRow = sheet.ReadRows().Last();
    formulaText = ((ExcelFormula)lastRow[0]!).FormulaText;
}

using (var sheet = reader.OpenWorksheet("Data"))
{
    result = evaluator.EvaluateCell(sheet, row: 4, col: 1);
}

Console.WriteLine($"Formula: {formulaText}");
Console.WriteLine($"Result:  {result}");

Evaluate a formula cell by row and column

Read workbook

Create a workbook with a formula, then reopen the worksheet and evaluate the formula cell by row and column.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("evaluate-cell.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Item",  "Amount");
sheet.WriteRow("A",     100);
sheet.WriteRow("B",     250);
sheet.WriteRow("C",     150);
sheet.WriteRow("Total", ExcelFormula.From("SUM(B2:B4)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("evaluate-cell.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");
var result = evaluator.EvaluateCell(sheet, row: 5, col: 2);

Console.WriteLine(result);

Cached value versus recalculated value

Read workbook

Write a workbook with formula cells, then demonstrate how FormulaEngineer recalculates the formula rather than reading a potentially stale cached value from the file.

Write workbook
Write.cs
// TODO (api-check): this example demonstrates that FormulaEngineer
// recalculates from the formula text rather than trusting a possibly
// stale cached value baked into the .xlsx by an earlier Excel session.
// The cleanest demo is: write the workbook ourselves with fresh inputs,
// then on read.cs change one of the inputs in code before evaluating —
// proving the formula reflects the change, not the saved cached number.
using FormulaEngineer.Api;

using var writer = new ExcelWriter("cached-vs-evaluated.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Price",  "Qty", "Total");
sheet.WriteRow(10.00,     2,    ExcelFormula.From("A2*B2"));
sheet.WriteRow(15.00,     3,    ExcelFormula.From("A3*B3"));
sheet.WriteRow(20.00,     1,    ExcelFormula.From("A4*B4"));
sheet.WriteRow("Grand",   "",   ExcelFormula.From("SUM(C2:C4)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("cached-vs-evaluated.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");

// FormulaEngineer evaluates the formula text directly. Even if the
// .xlsx file contained a stale cached value left over from an earlier
// save, EvaluateCell recomputes the result from the formula itself.
var grandTotal = evaluator.EvaluateCell(sheet, row: 5, col: 3);

Console.WriteLine($"Recalculated grand total: {grandTotal}");

SUMIF workbook

Conditional aggregation

Use SUMIF to total values that match a single criterion in another column.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("sumif.xlsx");
using var sheet = writer.CreateWorksheet("Sales");

sheet.WriteRow("Region", "Amount");
sheet.WriteRow("East",   100);
sheet.WriteRow("West",   200);
sheet.WriteRow("East",   150);
sheet.WriteRow("North",   80);
sheet.WriteRow("East",   220);
sheet.WriteRow("West",   175);
sheet.WriteRow("North",  130);
sheet.WriteRow("East total", ExcelFormula.From("SUMIF(A2:A8,\"East\",B2:B8)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("sumif.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Sales");
var eastTotal = evaluator.EvaluateCell(sheet, row: 9, col: 2);

Console.WriteLine($"East total: {eastTotal}");

SUMIFS workbook

Conditional aggregation

Use SUMIFS to total values that match multiple criteria across different columns.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("sumifs.xlsx");
using var sheet = writer.CreateWorksheet("Sales");

sheet.WriteRow("Region", "Product", "Amount");
sheet.WriteRow("East",   "Widget",  100);
sheet.WriteRow("East",   "Gadget",  200);
sheet.WriteRow("West",   "Widget",  150);
sheet.WriteRow("East",   "Widget",  220);
sheet.WriteRow("North",  "Widget",   80);
sheet.WriteRow("East",   "Gadget",  175);
sheet.WriteRow("East",   "Widget",  130);
sheet.WriteRow("West",   "Gadget",   90);
sheet.WriteRow("North",  "Gadget",  140);
sheet.WriteRow("East Widget total",
    ExcelFormula.From("SUMIFS(C2:C10,A2:A10,\"East\",B2:B10,\"Widget\")"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("sumifs.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Sales");
var eastWidget = evaluator.EvaluateCell(sheet, row: 11, col: 2);

Console.WriteLine($"East Widget total: {eastWidget}");

COUNTIF workbook

Conditional aggregation

Use COUNTIF to count how many cells in a range match a single criterion.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("countif.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Student", "Score");
sheet.WriteRow("Alice",   80);
sheet.WriteRow("Bob",     45);
sheet.WriteRow("Carol",   90);
sheet.WriteRow("Dave",    55);
sheet.WriteRow("Eve",     72);
sheet.WriteRow("Frank",   60);
sheet.WriteRow("Grace",   33);
sheet.WriteRow("Henry",   88);
sheet.WriteRow("Ivy",     65);
sheet.WriteRow("Passing", ExcelFormula.From("COUNTIF(B2:B10,\">=60\")"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("countif.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");
var passing = evaluator.EvaluateCell(sheet, row: 11, col: 2);

Console.WriteLine($"Passing count: {passing}");

COUNTIFS workbook

Conditional aggregation

Use COUNTIFS to count cells that match multiple criteria across different columns.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("countifs.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Region", "Score");
sheet.WriteRow("East",    80);
sheet.WriteRow("West",    45);
sheet.WriteRow("East",    90);
sheet.WriteRow("North",   55);
sheet.WriteRow("East",    72);
sheet.WriteRow("West",    60);
sheet.WriteRow("East",    33);
sheet.WriteRow("North",   88);
sheet.WriteRow("East",    65);
sheet.WriteRow("East passing",
    ExcelFormula.From("COUNTIFS(A2:A10,\"East\",B2:B10,\">=60\")"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("countifs.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");
var eastPassing = evaluator.EvaluateCell(sheet, row: 11, col: 2);

Console.WriteLine($"East passing count: {eastPassing}");

VLOOKUP product price workbook

Lookups

Use VLOOKUP to find the price for a given product code in a reference table.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("vlookup.xlsx");
using var sheet = writer.CreateWorksheet("Products");

// Reference table in A2:C6 (Code, Name, Price), plus a lookup query in E2.
sheet.WriteRow("Code", "Name",   "Price", "", "Query", "Price");
sheet.WriteRow("A",    "Apple",   1.20,   "", "C",     ExcelFormula.From("VLOOKUP(E2,A2:C6,3,FALSE)"));
sheet.WriteRow("B",    "Banana",  0.50);
sheet.WriteRow("C",    "Cherry",  3.40);
sheet.WriteRow("D",    "Date",    2.80);
sheet.WriteRow("E",    "Eggplant",1.90);
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("vlookup.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Products");
var price = evaluator.EvaluateCell(sheet, row: 2, col: 6);

Console.WriteLine($"Price for code 'C': {price}");

XLOOKUP product price workbook

Lookups

Use XLOOKUP — the modern replacement for VLOOKUP — to find a product price by code.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("xlookup.xlsx");
using var sheet = writer.CreateWorksheet("Products");

// Same reference data as VLOOKUP, but the lookup uses XLOOKUP, which
// takes a separate lookup array and return array — no column index needed.
sheet.WriteRow("Code", "Name",   "Price", "", "Query", "Price");
sheet.WriteRow("A",    "Apple",   1.20,   "", "C",     ExcelFormula.From("XLOOKUP(E2,A2:A6,C2:C6)"));
sheet.WriteRow("B",    "Banana",  0.50);
sheet.WriteRow("C",    "Cherry",  3.40);
sheet.WriteRow("D",    "Date",    2.80);
sheet.WriteRow("E",    "Eggplant",1.90);
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("xlookup.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Products");
var price = evaluator.EvaluateCell(sheet, row: 2, col: 6);

Console.WriteLine($"Price for code 'C': {price}");

INDEX / MATCH workbook

Lookups

Use INDEX with MATCH to look up a value — the classic two-step pattern that works in any column direction.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("index-match.xlsx");
using var sheet = writer.CreateWorksheet("Products");

// MATCH finds the row position of the query, INDEX returns the value
// from the price column at that position.
sheet.WriteRow("Code", "Name",    "Price", "", "Query", "Price");
sheet.WriteRow("A",    "Apple",    1.20,   "", "C",     ExcelFormula.From("INDEX(C2:C6,MATCH(E2,A2:A6,0))"));
sheet.WriteRow("B",    "Banana",   0.50);
sheet.WriteRow("C",    "Cherry",   3.40);
sheet.WriteRow("D",    "Date",     2.80);
sheet.WriteRow("E",    "Eggplant", 1.90);
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("index-match.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Products");
var price = evaluator.EvaluateCell(sheet, row: 2, col: 6);

Console.WriteLine($"Price for code 'C': {price}");

Case-sensitive lookup workbook

Lookups

Combine EXACT, INDEX, and MATCH to perform a case-sensitive lookup that normal VLOOKUP / XLOOKUP cannot do.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("case-sensitive-lookup.xlsx");
using var sheet = writer.CreateWorksheet("Codes");

// Note: code "a" (lowercase) and "A" (uppercase) are different entries.
// VLOOKUP / XLOOKUP would match the first one regardless of case;
// EXACT inside an array MATCH gives a true case-sensitive lookup.
sheet.WriteRow("Code", "Name",     "Price", "", "Query", "Price");
sheet.WriteRow("a",    "apple-lc",  1.00,   "", "A",     ExcelFormula.From("INDEX(C2:C8,MATCH(TRUE,EXACT(E2,A2:A8),0))"));
sheet.WriteRow("A",    "Apple-UC",  9.99);
sheet.WriteRow("b",    "banana-lc", 0.50);
sheet.WriteRow("B",    "Banana-UC", 8.50);
sheet.WriteRow("c",    "cherry-lc", 3.00);
sheet.WriteRow("C",    "Cherry-UC", 7.40);
sheet.WriteRow("d",    "date-lc",   2.80);
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("case-sensitive-lookup.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Codes");
var price = evaluator.EvaluateCell(sheet, row: 2, col: 6);

Console.WriteLine($"Price for code 'A' (uppercase): {price}");

Text formulas workbook

Text

Use LEFT, RIGHT, MID, LEN, and CONCATENATE to extract and combine portions of text values.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("text-formulas.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Source",            "Result");
sheet.WriteRow("FormulaEngineer",   ExcelFormula.From("LEFT(A2,7)"));
sheet.WriteRow("FormulaEngineer",   ExcelFormula.From("RIGHT(A3,8)"));
sheet.WriteRow("FormulaEngineer",   ExcelFormula.From("MID(A4,8,3)"));
sheet.WriteRow("FormulaEngineer",   ExcelFormula.From("LEN(A5)"));
sheet.WriteRow("Formula",           ExcelFormula.From("CONCATENATE(A6,\"Engineer\")"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("text-formulas.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");

var left  = evaluator.EvaluateCell(sheet, row: 2, col: 2);
var right = evaluator.EvaluateCell(sheet, row: 3, col: 2);
var mid   = evaluator.EvaluateCell(sheet, row: 4, col: 2);
var len   = evaluator.EvaluateCell(sheet, row: 5, col: 2);
var cat   = evaluator.EvaluateCell(sheet, row: 6, col: 2);

Console.WriteLine($"LEFT:        {left}");
Console.WriteLine($"RIGHT:       {right}");
Console.WriteLine($"MID:         {mid}");
Console.WriteLine($"LEN:         {len}");
Console.WriteLine($"CONCATENATE: {cat}");

IFERROR error-handling workbook

Errors

Create a workbook where SEARCH returns an Excel error, then use IFERROR to return a friendly fallback value.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("iferror.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("FormulaEngineer");
sheet.WriteRow(ExcelFormula.From("SEARCH(\"z\",A1)"));
sheet.WriteRow(ExcelFormula.From("IFERROR(SEARCH(\"z\",A1),\"Not Found\")"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;

using var reader = new ExcelReader("iferror.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");

var rawError = evaluator.EvaluateCell(sheet, row: 2, col: 1);
var handled  = evaluator.EvaluateCell(sheet, row: 3, col: 1);

Console.WriteLine($"Raw error: {rawError}");
Console.WriteLine($"Handled:   {handled}");

Date formulas workbook

Dates

Use DATE to build a date value and YEAR / MONTH / DAY to extract its parts.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("date-formulas.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Label", "Value");
sheet.WriteRow("Date",  ExcelFormula.From("DATE(2026,5,21)"));
sheet.WriteRow("Year",  ExcelFormula.From("YEAR(B2)"));
sheet.WriteRow("Month", ExcelFormula.From("MONTH(B2)"));
sheet.WriteRow("Day",   ExcelFormula.From("DAY(B2)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;
using System.Globalization;

using var reader = new ExcelReader("date-formulas.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");

var date = evaluator.EvaluateCell(sheet, row: 2, col: 2);
var year = evaluator.EvaluateCell(sheet, row: 3, col: 2);
var month = evaluator.EvaluateCell(sheet, row: 4, col: 2);
var day = evaluator.EvaluateCell(sheet, row: 5, col: 2);

var formattedDate = FormatExcelDate(date);

Console.WriteLine($"Date:  {formattedDate}");
Console.WriteLine($"Year:  {year}");
Console.WriteLine($"Month: {month}");
Console.WriteLine($"Day:   {day}");

static string FormatExcelDate(object? value)
{
	if (value is DateTime dt)
		return dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is double d)
		return DateTime.FromOADate(d).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is int i)
		return DateTime.FromOADate(i).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is long l)
		return DateTime.FromOADate(l).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is decimal m)
		return DateTime.FromOADate((double)m).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	return Convert.ToString(value, CultureInfo.InvariantCulture) ?? "";
}

WORKDAY workbook

Dates

Use WORKDAY to compute a future business date by adding a number of working days to a start date.

Write workbook
Write.cs
using FormulaEngineer.Api;

using var writer = new ExcelWriter("workday.xlsx");
using var sheet = writer.CreateWorksheet("Data");

sheet.WriteRow("Start", ExcelFormula.From("DATE(2026,5,21)"));
sheet.WriteRow("Plus 5wd", ExcelFormula.From("WORKDAY(B1,5)"));
Read and evaluate
Read.cs
using FormulaEngineer.Api;
using System.Globalization;

using var reader = new ExcelReader("workday.xlsx");
using var evaluator = new ExcelFormulaEvaluator();

using var sheet = reader.OpenWorksheet("Data");

var future = evaluator.EvaluateCell(sheet, row: 2, col: 2);
var formattedFuture = FormatExcelDate(future);

Console.WriteLine($"5 working days after 2026-05-21: {formattedFuture}");

static string FormatExcelDate(object? value)
{
	if (value is DateTime dt)
		return dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is double d)
		return DateTime.FromOADate(d).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is int i)
		return DateTime.FromOADate(i).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is long l)
		return DateTime.FromOADate(l).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	if (value is decimal m)
		return DateTime.FromOADate((double)m).ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

	return Convert.ToString(value, CultureInfo.InvariantCulture) ?? "";
}

Need help testing your workbook?

If your workbook contains formulas your application depends on, contact us with the formula patterns you need to support.