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.
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.
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)"));
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.
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)"));
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.
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)"));
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.
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\")"));
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.
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"));
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.
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)"));
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.
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)"));
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.
// 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)"));
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.
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)"));
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.
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\")"));
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.
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\")"));
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.
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\")"));
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.
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);
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.
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);
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.
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);
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.
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);
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.
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\")"));
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.
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\")"));
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.
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)"));
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.
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)"));
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.