![]() |
VOOZH | about |
dotnet add package ExcelMapper --version 6.0.641
NuGet\Install-Package ExcelMapper -Version 6.0.641
<PackageReference Include="ExcelMapper" Version="6.0.641" />
<PackageVersion Include="ExcelMapper" Version="6.0.641" />Directory.Packages.props
<PackageReference Include="ExcelMapper" />Project file
paket add ExcelMapper --version 6.0.641
#r "nuget: ExcelMapper, 6.0.641"
#:package ExcelMapper@6.0.641
#addin nuget:?package=ExcelMapper&version=6.0.641Install as a Cake Addin
#tool nuget:?package=ExcelMapper&version=6.0.641Install as a Cake Tool
👁 NuGet version
👁 Build status
👁 codecov.io
👁 netstandard2.0
👁 net462
👁 Discord
A library to map POCO objects to Excel files.
var products = new ExcelMapper("products.xlsx").Fetch<Product>();
This expects the Excel file to contain a header row with the column names. Objects are read from the first worksheet. If the column names equal the property names (ignoring case) no other configuration is necessary. The format of the Excel file (xlsx or xls) is autodetected.
public class Product
{
public string Name { get; set; }
[Column("Number")]
public int NumberInStock { get; set; }
public decimal Price { get; set; }
}
This maps the column named Number to the NumberInStock property.
Column indexes start at 1.
public class Product
{
[Column(1)]
public string Name { get; set; }
[Column(Letter="C")]
public int NumberInStock { get; set; }
[Column(4)]
public decimal Price { get; set; }
}
var products = new ExcelMapper("products.xlsx") { HeaderRow = false }.Fetch<Product>();
Note that column indexes don't need to be consecutive. When mapping to column indexes, every property needs to be explicitly mapped through the ColumnAttribute attribute or the AddMapping() method. You can combine column indexes with column names to specify an explicit column order while still using a header row.
var excel = new ExcelMapper("products.xls");
excel.AddMapping<Product>("Number", p => p.NumberInStock);
excel.AddMapping<Product>(1, p => p.NumberInStock);
excel.AddMapping(typeof(Product), "Number", "NumberInStock");
excel.AddMapping(typeof(Product), ExcelMapper.LetterToIndex("A"), "NumberInStock");
You can map a single column to multiple properties but you need to be aware of what should happen when mapping back from objects to Excel. To specify the single property you want to map back to Excel, add MappingDirections.ExcelToObject in the Column attribute of all other properties that map to the same column. Alternatively, you can use the FromExcelOnly() method when mapping through method calls.
public class Product
{
public decimal Price { get; set; }
[Column("Price", MappingDirections.ExcelToObject)]
public string PriceString { get; set; }
}
// or
excel.AddMapping<Product>("Price", p => p.PriceString).FromExcelOnly();
Column attributes are inherited by default, resulting in multiple mappings for a single overridden property if you add a Column attribute to the property in base
and derived classes. To prevent this, set the Inherit property to false on the Column attribute in the base class.
You don't have to specify a mapping to static types, you can also fetch a collection of dynamic objects.
var products = new ExcelMapper("products.xlsx").Fetch(); // -> IEnumerable<dynamic>
products.First().Price += 1.0;
The returned dynamic objects are instances of ExpandoObject with an extra property called __indexes__ that is a dictionary specifying the mapping from property names to
column indexes. If you set the HeaderRow property to false on the ExcelMapper object, the property names of the returned dynamic objects will match the Excel "letter" column names, i.e. "A" for column 1 etc.
var products = new List<Product>
{
new Product { Name = "Nudossi", NumberInStock = 60, Price = 1.99m },
new Product { Name = "Halloren", NumberInStock = 33, Price = 2.99m },
new Product { Name = "Filinchen", NumberInStock = 100, Price = 0.99m },
};
new ExcelMapper().Save("products.xlsx", products, "Products");
This saves to the worksheet named "Products". If you save objects after having previously read from an Excel file using the same instance of ExcelMapper the style of the workbook is preserved allowing use cases where an Excel template is filled with computed data.
var products = new ExcelMapper("products.xlsx").Fetch<Product>().ToList();
products[1].Price += 1.0m;
excel.Save("products.out.xlsx");
public class Product
{
public string Name { get; set; }
[Ignore]
public int Number { get; set; }
public decimal Price { get; set; }
}
// or
var excel = new ExcelMapper("products.xlsx");
excel.Ignore<Product>(p => p.Price);
public class Product
{
[DataFormat(0xf)]
public DateTime Date { get; set; }
[DataFormat("0%")]
public decimal Number { get; set; }
}
You can use both builtin formats and custom formats. The default format for DateTime cells is 0x16 ("m/d/yy h:mm") and can be changed through the properties DefaultDateFormat and DateFormat.
Explicitly set data formats override existing formats in an Excel file. Otherwise existing column and cell styles will be left untouched.
Formula columns are mapped according to the type of the property they are mapped to: for string properties, the formula itself (e.g. "A1+B1") is mapped, for other property types the formula result is mapped. If you need the formula result in a string property, use the FormulaResult attribute.
public class Product
{
[FormulaResult]
public string Result { get; set; }
}
// or
excel.AddMapping<Product>("Result" p => p.Result).AsFormulaResult();
If you want to save formulas you need to use the FormulaAttribute attribute or call AsFormula() if mapping manually.
It's not needed if you only want to map from Excel to objects (deserialize).
public class Product
{
[Formula]
public string Formula { get; set; }
}
// or
excel.AddMapping<Product>("Formula" p => p.Formula).AsFormula();
☝️ The string values of formula properties must not start with the = sign. So instead of =A1+B1 set the property's value to A1+B1.
If you have specific requirements for mapping between cells and objects, you can use custom conversion methods. Here, cells that contain the string "NULL" are mapped to null:
public class Product
{
public DateTime? Date { get; set; }
}
excel.AddMapping<Product>("Date", p => p.Date)
.SetCellUsing((c, o) =>
{
if (o == null) c.SetCellValue("NULL"); else c.SetCellValue((DateTime)o);
})
.SetPropertyUsing(v =>
{
if ((v as string) == "NULL") return null;
return Convert.ChangeType(v, typeof(DateTime), CultureInfo.InvariantCulture);
});
You can specify the row number of the header row using the property HeaderRowNumber (default is 0). The range of rows that are considered rows that may contain data can be specified using the properties MinRowNumber (default is 0) and MaxRowNumber (default is int.MaxValue). The header row doesn't have to fall within this range, e.g. you can have the header row in row 5 and the data in rows 10-20.
You can easily serialize to and from JSON formatted cells by specifying the Json attribute or AsJson() method.
public class ProductJson
{
[Json]
public Product Product { get; set; }
}
// or
var excel = new ExcelMapper("products.xls");
excel.AddMapping<ProductJson>("Product", p => p.Product).AsJson();
This also works with lists.
public class ProductJson
{
[Json]
public List<Product> Products { get; set; }
}
If the header cell values are not uniform, perhaps because they contain varying amounts of whitespace, you can specify a normalization function that will be applied to header cell values before mapping to property names. This can be done globally or for specific classes only.
excel.NormalizeUsing(n => Regex.Replace(n, "\s", ""));
This removes all whitespace so that columns with the string " First Name " map to a property named FirstName.
Records are supported. If the type has no default constructor (as is the case for positional records) the constructor with the highest number of arguments is used to initialize objects. This constructor must have a parameter for each of the mapped properties with the same name as the corresponding property (ignoring case). The remanining parameters will receive the default value of their type.
Nested objects are supported and should work out of the box for most use cases. For example, if you have a sheet with columns Name, Street, City, Zip, Birthday, you can map to the following class hierarchy without any configuration:
public class Person
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string Zip { get; set; }
}
var customers = new ExcelMapper("customers.xlsx").Fetch<Person>();
This works with records, too:
public record Person(string Name, DateTime Birthday, Address Address);
public record Address(string Street, string City, string Zip);
You can specify a custom object factory for any type which will be used to create object instances for mapped properties of that type. This can be useful to handle cases where object creation is otherwise not possible (such as for properties that have interface types) or where you want to execute specific initialization logic.
public class Person
{
public string Name { get; set; }
public IAddress Address { get; set; }
}
excel.CreateInstance<IAddress>(() => new Address());
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 is compatible. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on ExcelMapper:
| Package | Downloads |
|---|---|
|
rna.Core.Infrastructure
A complete set of libraries for rna Authorization and CRUD operations |
|
|
AbacusLib.Common
Package Description |
|
|
TrinityText.Utilities
Trinity Text utilities layer |
|
|
Halifax.Excel
Halifax Service Foundation Excel/CSV library |
|
|
FMSoftlab.DataMigration
Package Description |
Showing the top 2 popular GitHub repositories that depend on ExcelMapper:
| Repository | Stars |
|---|---|
|
grandnode/grandnode2
E-commerce platform built with ASP.NET Core using MongoDB for NoSQL storage
|
|
|
nsnail/NetAdmin
通用后台权限管理系统、快速开发框架(基于C#13/.NET9、Vue3/Vite、ElementPlus等现代技术构建,具有十分整洁、优雅的编码规范)Universal backend permission management system, rapid development framework (based on modern technologies such as C#13/.NET9, Vue3/Vite, ElementPlus, etc., with very neat and elegant coding standards)
|
| Version | Downloads | Last Updated |
|---|---|---|
| 6.0.641 | 22,182 | 4/27/2026 |
| 6.0.615 | 104,794 | 12/22/2025 |
| 6.0.614 | 8,439 | 12/16/2025 |
| 6.0.613 | 15,274 | 11/25/2025 |
| 6.0.612 | 130,952 | 8/27/2025 |
| 6.0.611 | 42,433 | 7/8/2025 |
| 6.0.609 | 290,579 | 4/23/2025 |
| 5.2.604 | 27,039 | 4/10/2025 |
| 5.2.602 | 24,687 | 3/29/2025 |
| 5.2.598 | 113,459 | 1/23/2025 |
| 5.2.594 | 123,179 | 12/19/2024 |
| 5.2.593 | 62,261 | 11/20/2024 |
| 5.2.592 | 527,566 | 7/16/2024 |
| 5.2.591 | 11,781 | 7/10/2024 |
| 5.2.590 | 40,050 | 6/12/2024 |
| 5.2.588 | 99,365 | 5/24/2024 |
| 5.2.581 | 75,085 | 4/12/2024 |
| 5.2.580 | 82,831 | 3/25/2024 |
| 5.2.568 | 43,607 | 2/12/2024 |
| 5.2.564 | 54,616 | 12/13/2023 |