Initial commit of the ClosedXML library

Establishes the foundational structure, core Excel functionality, and tooling.

- Implements base components for cells, ranges, columns, and rows.
- Integrates a custom calculation engine with a wide range of Excel functions.
- Adds comprehensive support for styling, conditional formatting, data validation, comments, pictures, and charts.
- Configures build setup, project metadata (NuGet), and developer guidelines.
- Includes editor and Git attributes for consistent code style and line endings.
This commit is contained in:
Thom Lamb
2026-06-23 11:02:53 -05:00
parent 28bc05cf54
commit 2cd6df6481
1092 changed files with 97270 additions and 408 deletions
@@ -0,0 +1,139 @@
using System;
using System.IO;
using ClosedXML.Excel;
namespace ClosedXML_Examples
{
public class CustomAutoFilter : IXLExample
{
public void Create(string filePath)
{
var wb = new XLWorkbook();
IXLWorksheet ws;
#region Single Column Numbers
String singleColumnNumbers = "Single Column Numbers";
ws = wb.Worksheets.Add(singleColumnNumbers);
// Add a bunch of numbers to filter
ws.Cell("A1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).EqualTo(3).Or.GreaterThan(4);
// Sort the filtered list
ws.AutoFilter.Sort(1);
#endregion
#region Single Column Strings
String singleColumnStrings = "Single Column Strings";
ws = wb.Worksheets.Add(singleColumnStrings);
// Add a bunch of strings to filter
ws.Cell("A1").SetValue("Strings")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).Between("B", "D");
// Sort the filtered list
ws.AutoFilter.Sort(1);
#endregion
#region Single Column Mixed
String singleColumnMixed = "Single Column Mixed";
ws = wb.Worksheets.Add(singleColumnMixed);
// Add a bunch of items to filter
ws.Cell("A1").SetValue("Mixed")
.CellBelow().SetValue("B")
.CellBelow().SetValue(3)
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).EqualTo(3).Or.EqualTo("C");
// Sort the filtered list
ws.AutoFilter.Sort(1);
#endregion
#region Multi Column
String multiColumn = "Multi Column";
ws = wb.Worksheets.Add(multiColumn);
ws.Cell("A1").SetValue("First")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
ws.Cell("B1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
ws.Cell("C1").SetValue("Strings")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
// Add filters
ws.RangeUsed().SetAutoFilter().Column(2).EqualTo(3).Or.GreaterThan(4);
ws.RangeUsed().SetAutoFilter().Column(3).Between("B", "D");
// Sort the filtered list
ws.AutoFilter.Sort(3);
#endregion
using (var ms = new MemoryStream())
{
wb.SaveAs(ms);
var workbook = new XLWorkbook(ms);
#region Single Column Numbers
workbook.Worksheet(singleColumnNumbers).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion
#region Single Column Strings
workbook.Worksheet(singleColumnStrings).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion
#region Single Column Mixed
workbook.Worksheet(singleColumnMixed).AutoFilter.Column(1).EqualOrGreaterThan("D");
workbook.Worksheet(singleColumnMixed).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion
#region Multi Column
workbook.Worksheet(multiColumn).AutoFilter.Column(3).EqualTo("E");
workbook.Worksheet(multiColumn).AutoFilter.Sort(3, XLSortOrder.Descending);
#endregion
workbook.SaveAs(filePath);
ms.Close();
}
}
}
}
@@ -0,0 +1,43 @@
using ClosedXML.Excel;
using System;
namespace ClosedXML_Examples
{
public class DateTimeGroupAutoFilter : IXLExample
{
public void Create(string filePath)
{
using (var wb = new XLWorkbook())
{
IXLWorksheet ws;
#region Single Column Dates
String singleColumnDates = "Single Column Dates";
ws = wb.Worksheets.Add(singleColumnDates);
// Add a bunch of numbers to filter
ws.Cell("A1").SetValue("Dates")
.CellBelow().SetValue(new DateTime(2018, 1, 1).AddDays(2))
.CellBelow().SetValue(new DateTime(2018, 1, 1).AddDays(3))
.CellBelow().SetValue(new DateTime(2018, 1, 1).AddDays(3))
.CellBelow().SetValue(new DateTime(2018, 1, 1).AddDays(5))
.CellBelow().SetValue(new DateTime(2018, 1, 1).AddDays(1))
.CellBelow().SetValue(new DateTime(2018, 1, 1).AddDays(4));
ws.Column(1).Style.NumberFormat.Format = "d MMMM yyyy";
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).AddDateGroupFilter(new DateTime(2018, 1, 1).AddDays(3), XLDateTimeGrouping.Day);
// Sort the filtered list
ws.AutoFilter.Sort(1);
#endregion Single Column Dates
ws.Columns().AdjustToContents();
wb.SaveAs(filePath);
}
}
}
}
@@ -0,0 +1,88 @@
using System;
using System.IO;
using ClosedXML.Excel;
namespace ClosedXML_Examples
{
public class DynamicAutoFilter : IXLExample
{
public void Create(string filePath)
{
var wb = new XLWorkbook();
IXLWorksheet ws;
#region Single Column Numbers
String singleColumnNumbers = "Single Column Numbers";
ws = wb.Worksheets.Add(singleColumnNumbers);
// Add a bunch of numbers to filter
ws.Cell("A1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).AboveAverage();
// Sort the filtered list
//ws.AutoFilter.Sort(1);
#endregion
#region Multi Column
String multiColumn = "Multi Column";
ws = wb.Worksheets.Add(multiColumn);
ws.Cell("A1").SetValue("First")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
ws.Cell("B1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
ws.Cell("C1").SetValue("Strings")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
// Add filters
ws.RangeUsed().SetAutoFilter().Column(2).BelowAverage();
// Sort the filtered list
//ws.AutoFilter.Sort(3);
#endregion
using (var ms = new MemoryStream())
{
wb.SaveAs(ms);
var workbook = new XLWorkbook(ms);
#region Single Column Numbers
//workbook.Worksheet(singleColumnNumbers).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion
#region Multi Column
//workbook.Worksheet(multiColumn).AutoFilter.Sort(3, XLSortOrder.Descending);
#endregion
workbook.SaveAs(filePath);
ms.Close();
}
}
}
}
@@ -0,0 +1,205 @@
using ClosedXML.Excel;
using System;
using System.IO;
namespace ClosedXML_Examples
{
public class RegularAutoFilter : IXLExample
{
public void Create(string filePath)
{
var wb = new XLWorkbook();
IXLWorksheet ws;
#region Single Column Numbers
String singleColumnNumbers = "Single Column Numbers";
ws = wb.Worksheets.Add(singleColumnNumbers);
// Add a bunch of numbers to filter
ws.Cell("A1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4)
.CellBelow().SetValue(5);
ws.Cell("B1").SetValue("Names")
.CellBelow().SetValue("John")
.CellBelow().SetValue("Jack")
.CellBelow().SetValue("Neil")
.CellBelow().SetValue("Alex")
.CellBelow().SetValue("Jason")
.CellBelow().SetValue("Patrick")
.CellBelow().SetValue("Jacques");
// Add filters
var autoFilter = ws.RangeUsed().SetAutoFilter();
autoFilter.Column(1).AddFilter(3)
.AddFilter(1);
autoFilter.Column(2).BeginsWith("J");
// Sort the filtered list
ws.AutoFilter.Sort(1);
#endregion Single Column Numbers
#region Single Column Strings
String singleColumnStrings = "Single Column Strings";
ws = wb.Worksheets.Add(singleColumnStrings);
// Add a bunch of strings to filter
ws.Cell("A1").SetValue("Strings")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).AddFilter("C")
.AddFilter("A");
// Sort the filtered list
ws.AutoFilter.Sort(1);
#endregion Single Column Strings
#region Single Column Mixed
String singleColumnMixed = "Single Column Mixed";
ws = wb.Worksheets.Add(singleColumnMixed);
// Add a bunch of items to filter
ws.Cell("A1").SetValue("Mixed")
.CellBelow().SetValue("B")
.CellBelow().SetValue(3)
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).AddFilter("C")
.AddFilter(1);
// Sort the filtered list
ws.AutoFilter.Sort(1);
#endregion Single Column Mixed
#region Multi Column
String multiColumn = "Multi Column";
ws = wb.Worksheets.Add(multiColumn);
ws.Cell("A1").SetValue("First")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
ws.Cell("B1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
ws.Cell("C1").SetValue("Strings")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
// Add filters
ws.RangeUsed().SetAutoFilter().Column(2).AddFilter(3)
.AddFilter(1);
// Sort the filtered list
ws.AutoFilter.Sort(3);
#endregion Multi Column
#region Table
String tableSheetName = "Table";
ws = wb.Worksheets.Add(tableSheetName);
// Add a bunch of numbers to filter
ws.Cell("A1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
// Add filters
var table = ws.RangeUsed().CreateTable();
table.ShowTotalsRow = true;
table.Field(0).TotalsRowFunction = XLTotalsRowFunction.Sum;
table.AutoFilter.Column(1).AddFilter(3).AddFilter(4);
table.AutoFilter.Sort(1);
#endregion Table
using (var ms = new MemoryStream())
{
wb.SaveAs(ms);
var workbook = new XLWorkbook(ms);
#region Single Column Numbers
workbook.Worksheet(singleColumnNumbers).AutoFilter.Column(1).AddFilter(5);
workbook.Worksheet(singleColumnNumbers).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion Single Column Numbers
#region Single Column Strings
workbook.Worksheet(singleColumnStrings).AutoFilter.Column(1).AddFilter("E");
workbook.Worksheet(singleColumnStrings).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion Single Column Strings
#region Single Column Mixed
workbook.Worksheet(singleColumnMixed).AutoFilter.Column(1).AddFilter("E");
workbook.Worksheet(singleColumnMixed).AutoFilter.Column(1).AddFilter(3);
workbook.Worksheet(singleColumnMixed).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion Single Column Mixed
#region Multi Column
workbook.Worksheet(multiColumn).AutoFilter.Column(3).AddFilter("C");
workbook.Worksheet(multiColumn).AutoFilter.Sort(3, XLSortOrder.Descending);
#endregion Multi Column
#region Table
workbook.Worksheet(tableSheetName).Table(0).AutoFilter.Column(1).AddFilter(5);
workbook.Worksheet(tableSheetName).Table(0).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion Table
workbook.SaveAs(filePath);
ms.Close();
}
}
}
}
@@ -0,0 +1,88 @@
using System;
using System.IO;
using ClosedXML.Excel;
namespace ClosedXML_Examples
{
public class TopBottomAutoFilter : IXLExample
{
public void Create(string filePath)
{
var wb = new XLWorkbook();
IXLWorksheet ws;
#region Single Column Numbers
String singleColumnNumbers = "Single Column Numbers";
ws = wb.Worksheets.Add(singleColumnNumbers);
// Add a bunch of numbers to filter
ws.Cell("A1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
// Add filters
ws.RangeUsed().SetAutoFilter().Column(1).Top(2);
// Sort the filtered list
//ws.AutoFilter.Sort(1);
#endregion
#region Multi Column
String multiColumn = "Multi Column";
ws = wb.Worksheets.Add(multiColumn);
ws.Cell("A1").SetValue("First")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
ws.Cell("B1").SetValue("Numbers")
.CellBelow().SetValue(2)
.CellBelow().SetValue(3)
.CellBelow().SetValue(3)
.CellBelow().SetValue(5)
.CellBelow().SetValue(1)
.CellBelow().SetValue(4);
ws.Cell("C1").SetValue("Strings")
.CellBelow().SetValue("B")
.CellBelow().SetValue("C")
.CellBelow().SetValue("C")
.CellBelow().SetValue("E")
.CellBelow().SetValue("A")
.CellBelow().SetValue("D");
// Add filters
ws.RangeUsed().SetAutoFilter().Column(2).Bottom(50, XLTopBottomType.Percent);
// Sort the filtered list
//ws.AutoFilter.Sort(3);
#endregion
using (var ms = new MemoryStream())
{
wb.SaveAs(ms);
var workbook = new XLWorkbook(ms);
#region Single Column Numbers
//workbook.Worksheet(singleColumnNumbers).AutoFilter.Sort(1, XLSortOrder.Descending);
#endregion
#region Multi Column
//workbook.Worksheet(multiColumn).AutoFilter.Sort(3, XLSortOrder.Descending);
#endregion
workbook.SaveAs(filePath);
ms.Close();
}
}
}
}