netaera.OpenXml.Excel.SheetMapper 2.0.0

dotnet add package netaera.OpenXml.Excel.SheetMapper --version 2.0.0
                    
NuGet\Install-Package netaera.OpenXml.Excel.SheetMapper -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="netaera.OpenXml.Excel.SheetMapper" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="netaera.OpenXml.Excel.SheetMapper" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="netaera.OpenXml.Excel.SheetMapper" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add netaera.OpenXml.Excel.SheetMapper --version 2.0.0
                    
#r "nuget: netaera.OpenXml.Excel.SheetMapper, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package netaera.OpenXml.Excel.SheetMapper@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=netaera.OpenXml.Excel.SheetMapper&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=netaera.OpenXml.Excel.SheetMapper&version=2.0.0
                    
Install as a Cake Tool

netaera.OpenXml.Excel.SheetMapper

Upgrade Notice: This package includes breaking changes in version 2.0.
See UPGRADE.md (included in the NuGet package under contentFiles) for details.

netaera.OpenXml.Excel.SheetMapper is a powerful extension for the netaera.OpenXml.Excel library, enabling automatic mapping of Excel data into objects.
Similar to how an ORM transforms database records into structured entities, SheetMapper converts raw spreadsheet rows directly into typed DTOs—eliminating the need for manual data parsing.

🚀 Why SheetMapper?

  • No manual parsing – Retrieve structured objects instead of raw table rows.
  • Flexible mapping – Supports both attribute-based and code-based configurations.
  • Handles complex data types – Manages lists, related objects, and type conversion.
  • Ideal for business applications – Perfect for CRM imports, reporting, AI data sources, etc.

🔹 Installation

Install SheetMapper via NuGet:

dotnet add package netaera.OpenXml.Excel.SheetMapper

🛠 Usage & Examples

1. Mapping Using Attributes

The simplest way to define your mapping is by using annotations:

public interface ICustomer
{
    [SheetMappingData(columnName: "B")]
    string ExternNumber { get; set; }

    [SheetMappingData(columnName: "C")]
    string Number { get; set; }

    [SheetMappingData(columnName: "D")]
    string Name { get; set; }

    [SheetMappingData(columnName: "H")]
    string FirstName { get; set; }

    [SheetMappingData(columnName: "G")]
    string Street { get; set; }

    [SheetMappingData(columnName: "M")]
    string City { get; set; }

    [SheetMappingData(columnName: "J")]
    string DefaultEmailAddress { get; set; }

    List<IPhone> Phones { get; set; }
}

2. Code-Based Mapping Configuration

For more control, you can configure your mappings programmatically using MappingInfoBuilder<T>.
This approach allows you to define how values are read from and written to Excel cells using lambda expressions.

internal class CustomerMappingInfo : MappingInfoBuilder<ICustomer>, IMappingInfoBuilder
{
    public override IMappingInfoBuilder Build(IMappingInfoManager mappingInfoManager)
    {
        mappingInfoManager
            .Build<ICustomer>(rc => rc.FirstRowIsHeaderRow = true)
            .Build<ICustomer>(mapper => mapper
                .Add<ICustomer>("B", cus => cus.Number)
                .Add<ICustomer>("D", cus => cus.Name)
                .Add<ICustomer>("H", cus => cus.FirstName)
                .Add<ICustomer>("I",
                    expressionUsedWhenReading: (cus, value) => cus.Phones.ParseExcelValue(value?.ToString()),
                    expressionUsedWhenWriting: cus => cus.Phones.JoinPhones())
                .Add<ICustomer>("Y", cus => cus.TradeRegistrationOn, dataType: DataType.DateTime)
            );
        return this;
    }
}
What do expressionUsedWhenReading and expressionUsedWhenWriting do?
  • expressionUsedWhenReading defines how a raw Excel value is transformed and assigned to the target object.
    In the example above, it parses a string (e.g. "0123,0456") into a list of phone objects using ParseExcelValue.

  • expressionUsedWhenWriting defines how the object’s value is serialized back into Excel.
    Here, JoinPhones() converts the list of phone numbers into a single string for export.

This mechanism allows you to handle complex types, collections, and custom transformations with minimal effort.

3. Mapping with Instantiation of Complex Types

If you want to map a scalar value from Excel into a dependent list or collection, use the classType parameter to instantiate the target object:

.Add<ICustomer>("I",
    expressionUsedWhenReading: (cus, value) => cus.Phones.Add((IPhone)value),
    classType: typeof(Phone))

This is ideal when each cell represents a single element of a collection (e.g., one phone number per row). The class type ensures that the object is created and the value is passed through the delegate.

4. Reading Mapped Data

Once mappings are registered, reading Excel data is straightforward:

var reader = DocumentBuilder.Build(config => config.FileName = "customers.xlsx").BuildReader();
var customers = reader.Read<ICustomer>();

5. Registering Mappings

Mappings must be registered before reading:

IMappingInfoManager sheetMappingInfoManager = MappingInfoManager.Instance
    .Register(new CustomerMappingInfo())
    .Register(new EmailMappingInfo());

6. Handling Dates and Types

Date values stored as OADate are automatically converted when using the appropriate DataType:

.Add<ICustomer>("Y", cus => cus.TradeRegistrationOn, dataType: DataType.DateTime)

No custom converter is needed.

📝 FAQ

How is SheetMapper different from netaera.OpenXml.Excel?

While netaera.OpenXml.Excel reads spreadsheet data as raw rows, SheetMapper transforms them into structured objects, easing downstream processing.

Can SheetMapper handle complex data models?

Yes. It supports mapping multiple columns, related entities, and delegate-based transformations.

Is SheetMapper useful for AI and machine learning applications?

Absolutely. By providing clean, well-typed data, SheetMapper serves as an excellent data source for analytical and AI-driven systems.


⚖ License

This package is free to use, but the source code may not be copied, decompiled, modified, or republished.
See LICENSE for details.

© 2025 Paul Berthold Goebel – creativesource. All rights reserved.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 485 7/23/2025
1.1.2-Beta 218 6/13/2025
1.1.1-Beta 115 5/28/2025
1.1.0-Beta 114 5/26/2025

Version 2.0.0:
- Major restructuring of mapping logic: introduced `ReadDelegate` and `WriteDelegate` for flexible property assignment and transformation
- Removed legacy properties (`ConstructorDelegate`, `ConstructorParameterType`, `ConverterClassType`) — replaced by more streamlined and unified delegates
- Simplified and clearer mapping configuration via lambda expressions for both read and write directions
- Obsoleted direct `ColumnName` usage; all mapping now relies on `ColumnInfo.Name` for consistency with core `OpenXml.Excel` library
- Improved extensibility with support for method-based transformations during read and write
- Updated to depend on `netaera.OpenXml.Excel` v1.2.0 — includes full support for standardized and custom Excel formatting
- Breaking changes: existing configurations using deprecated properties must migrate to new delegate-based approach

- Note: This release introduces breaking API changes; please review migration notes before upgrading.

Version 1.1.4
– Now also available for the .NET 9 target platform.

Version 1.1.2-Beta:
- Update to netaera.OpenXml.Excel package 1.1.2
- Writing data from DTOs is now possible

Version 1.1.1-Beta:
- Update to netaera.OpenXml.Excel package 1.1.1
- Setting RowCount now produces the correct result

Version 1.1.0-Beta
- Attribute-based Mapping Support: Added full support for attribute-based mapping. Properties can now be decorated with [SheetMappingData] to automatically map Excel columns to DTO properties. This declarative approach simplifies configuration and reduces boilerplate code.
- Renaming & API Enhancements: All mapping-related interfaces and classes have been renamed for clarity and making the API more generic and easier to understand.
- Improved Type Conversions and Method Mapping: Mappings using converters (e.g., OADateConverter) and method-invoked mappings (for example, handling phone numbers) have been refined. Although currently only a single phone number is processed, the groundwork has been laid for future enhancements to support multiple phone numbers with customizable delimiters (e.g. comma, semicolon).
- General Enhancements: Updated configuration APIs provide more flexibility and better error handling. Minor bug fixes and performance optimizations have also been implemented.