EPPlus.Core.Extensions
3.2.0
dotnet add package EPPlus.Core.Extensions --version 3.2.0
NuGet\Install-Package EPPlus.Core.Extensions -Version 3.2.0
<PackageReference Include="EPPlus.Core.Extensions" Version="3.2.0" />
<PackageVersion Include="EPPlus.Core.Extensions" Version="3.2.0" />
<PackageReference Include="EPPlus.Core.Extensions" />
paket add EPPlus.Core.Extensions --version 3.2.0
#r "nuget: EPPlus.Core.Extensions, 3.2.0"
#:package EPPlus.Core.Extensions@3.2.0
#addin nuget:?package=EPPlus.Core.Extensions&version=3.2.0
#tool nuget:?package=EPPlus.Core.Extensions&version=3.2.0
EPPlus.Core.Extensions 
Installation 
PM> Install-Package EPPlus.Core.Extensions
Dependencies
.NET 10.0 — EPPlus >= 8.6.1
License Setup
EPPlus 8 requires a license declaration before use. For non-commercial/personal projects:
ExcelPackage.License.SetNonCommercialPersonal("YourName");
For commercial use, see EPPlus licensing.
Features
- Converts
IEnumerable<T>into an Excel worksheet or package - Reads data from Excel packages and converts them into a
List<T> - Supports result-based imports that collect mapping, casting, and validation errors
- Provides safe
TryGetWorksheetandTryGetTablelookup helpers - Supports reading headers from any row via
WithHeaderRowIndex - Maps nested class properties as flat columns via
[ExcelNestedColumn] - Supports data annotations for validation (
[Required],[MaxLength],[Range], etc.) - Fluent API for building multi-worksheet workbooks
- Generates Excel templates from classes marked with
[ExcelWorksheet]
Examples
Mapping a class to Excel columns
Use [ExcelTableColumn] to map properties to Excel columns by name or index:
public class PersonDto
{
[ExcelTableColumn("First name")]
[Required(ErrorMessage = "First name cannot be empty.")]
[MaxLength(50, ErrorMessage = "First name cannot be more than {1} characters.")]
public string FirstName { get; set; }
[ExcelTableColumn(columnName = "Last name", isOptional = true)]
public string LastName { get; set; }
[ExcelTableColumn(3)]
[Range(1900, 2050, ErrorMessage = "Please enter a value bigger than {1}")]
public int YearBorn { get; set; }
public decimal NotMapped { get; set; }
[ExcelTableColumn(isOptional = true)]
public decimal OptionalColumn1 { get; set; }
[ExcelTableColumn(columnIndex = 999, isOptional = true)]
public decimal OptionalColumn2 { get; set; }
}
Reading Excel data into a list
// From the first worksheet:
List<PersonDto> firstWorksheetPersons = excelPackage.ToList<PersonDto>(c => c.SkipCastingErrors());
// From a named worksheet:
List<PersonDto> namedWorksheetPersons = excelPackage.GetWorksheet("Persons").ToList<PersonDto>();
// Or read a named worksheet directly from the package:
List<PersonDto> directNamedWorksheetPersons = excelPackage.ToListFromWorksheet<PersonDto>("Persons");
Reading without exceptions
Use Read<T> when a workbook is user input and all usable rows and errors should be returned together:
ExcelReadResult<PersonDto> result = excelPackage.Read<PersonDto>("Persons");
foreach (PersonDto person in result.Items)
{
// Rows with invalid cells are retained and may be partially populated.
}
foreach (ExcelReadError error in result.Errors)
{
Console.WriteLine($"{error.Kind}: {error.Context.CellAddress} - {error.Message}");
}
ToList<T> and AsEnumerable<T> keep their existing throw/skip behavior. Read<T> captures missing-column mappings, casting failures, and data annotation validation errors.
Safe workbook lookups
if (excelPackage.TryGetWorksheet("Persons", out ExcelWorksheet worksheet))
{
List<PersonDto> persons = worksheet.ToList<PersonDto>();
}
if (excelPackage.TryGetTable("PeopleTable", out ExcelTable table))
{
ExcelReadResult<PersonDto> result = table.Read<PersonDto>();
}
Reading when the header row is not on row 1
Use WithHeaderRowIndex when your sheet has title rows above the actual column headers:
// Header is on row 3 — rows 1 and 2 are skipped
List<PersonDto> persons = worksheet.ToList<PersonDto>(c => c.WithHeaderRowIndex(3));
Mapping nested class properties as flat columns
Use [ExcelNestedColumn] on a complex-type property to have its sub-properties mapped as flat columns:
public class Order
{
[ExcelTableColumn]
public string OrderId { get; set; }
[ExcelNestedColumn]
public Address ShippingAddress { get; set; }
}
public class Address
{
[ExcelTableColumn]
public string Street { get; set; }
[ExcelTableColumn]
public string City { get; set; }
}
// A worksheet with columns OrderId | Street | City maps correctly:
List<Order> orders = worksheet.ToList<Order>();
// orders[0].ShippingAddress.Street => "123 Main St"
Writing a list to an Excel package
// Convert to ExcelPackage
ExcelPackage excelPackage = persons.ToExcelPackage();
// Convert to byte array
byte[] xlsx = persons.ToXlsx();
// Specify the worksheet name
byte[] namedXlsx = persons.ToXlsx("Persons", addHeaderRow: true);
// Start the fluent builder with the default worksheet name (typeof(T).Name)
WorksheetWrapper<PersonDto> worksheet = persons.ToWorksheet();
// Fluent multi-worksheet builder
List<PersonDto> pre50 = persons.Where(x => x.YearBorn < 1950).ToList();
List<PersonDto> post50 = persons.Where(x => x.YearBorn >= 1950).ToList();
ExcelPackage excelPackage = pre50.ToWorksheet("< 1950")
.WithConfiguration(c => c.WithColumnConfiguration(x => x.AutoFit()))
.WithColumn(x => x.FirstName, "First Name")
.WithColumn(x => x.LastName, "Last Name")
.WithColumn(x => x.YearBorn, "Year of Birth")
.WithTitle("< 1950")
.NextWorksheet(post50, "> 1950")
.WithColumn(x => x.LastName, "Last Name")
.WithColumn(x => x.YearBorn, "Year of Birth")
.WithTitle("> 1950")
.ToExcelPackage();
Generating an Excel template from a class
Mark a class with [ExcelWorksheet] to generate a structured template:
[ExcelWorksheet("Stocks")]
public class StocksDto
{
[ExcelTableColumn("SKU")]
public string Barcode { get; set; }
[ExcelTableColumn]
public int Quantity { get; set; }
}
// Generate as ExcelPackage
ExcelPackage excelPackage = Assembly.GetExecutingAssembly().GenerateExcelPackage(nameof(StocksDto));
// Generate as ExcelWorksheet inside an existing package
using var excelPackage = new ExcelPackage();
ExcelWorksheet worksheet = excelPackage.GenerateWorksheet(Assembly.GetExecutingAssembly(), nameof(StocksDto));
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- EPPlus (>= 8.6.1)
NuGet packages (11)
Showing the top 5 NuGet packages that depend on EPPlus.Core.Extensions:
| Package | Downloads |
|---|---|
|
Tradeber.AbpCore.ServiceFabric
tradeber 基础设施库 |
|
|
IvyBaby.Infrastructure
暂无 |
|
|
Alizhou.Office
根据模板导入导出word,execl |
|
|
FileReaders
Package Description |
|
|
Farben.Office
Package Description |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on EPPlus.Core.Extensions:
| Repository | Stars |
|---|---|
|
WeihanLi/WeihanLi.Npoi
NPOI Extensions, excel/csv importer/exporter for IEnumerable<T>/DataTable, fluentapi(great flexibility)/attribute configuration
|
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 3.2.0 | 83 | 7/16/2026 | |
| 3.1.0 | 1,167 | 4/18/2026 | |
| 3.0.4 | 138 | 4/18/2026 | |
| 3.0.3 | 147 | 4/18/2026 | |
| 3.0.2 | 127 | 4/18/2026 | |
| 3.0.1 | 120 | 4/18/2026 | |
| 3.0.0 | 149 | 4/18/2026 | |
| 2.4.0 | 1,060,604 | 1/5/2020 | |
| 2.3.2 | 95,946 | 4/8/2019 | |
| 2.3.1 | 25,258 | 3/19/2019 | |
| 2.3.0 | 8,102 | 3/7/2019 | |
| 2.2.4 | 43,396 | 8/9/2018 | |
| 2.2.3 | 5,122 | 6/27/2018 | |
| 2.2.2 | 2,315 | 6/26/2018 | |
| 2.2.1 | 6,108 | 6/5/2018 | |
| 2.2.0 | 2,479 | 6/2/2018 | |
| 2.1.0 | 6,842 | 5/26/2018 | |
| 2.0.0 | 4,982 | 5/16/2018 | |
| 2.0.0-preview1 | 1,978 | 5/15/2018 | |
| 1.2.8 | 3,349 | 4/13/2018 |