SkillAgentSearch skills...

Excelsior

Excelsior is a Excel spreadsheet generation library with a distinctive data-driven approach.

Install / Use

/learn @SimonCropp/Excelsior
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<img src="/src/icon.png" height="30px"> Excelsior

Build status NuGet Status NuGet Status NuGet Status NuGet Status

Excelsior is a Excel spreadsheet generation library with a distinctive data-driven approach.

See Milestones for release notes.

Supported libraries

The architecture is designed to support multiple spreadsheet creation libraries.

Currently supported libraries include:

Usage

Model

Given an input class:

<!-- snippet: Employee.cs -->

<a id='snippet-Employee.cs'></a>

using Excelsior;

public class Employee
{
    [Column(Heading = "Employee ID", Order = 1)]
    public required int Id { get; init; }

    [Column(Heading = "Full Name", Order = 2)]
    public required string Name { get; init; }

    [Column(Heading = "Email Address", Order = 3)]
    public required string Email { get; init; }

    [Column(Heading = "Hire Date", Order = 4)]
    public Date? HireDate { get; init; }

    [Column(Heading = "Annual Salary", Order = 5)]
    public int Salary { get; init; }

    public bool IsActive { get; init; }

    public EmployeeStatus Status { get; init; }
}

<sup><a href='/src/Model/Employee.cs#L1-L23' title='Snippet source file'>snippet source</a> | <a href='#snippet-Employee.cs' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

[ColumnAttribute] is optional. If omitted:

Builder

BookBuilder is the root entry point.

Once instantiated, the data for multiple sheets can be added.

<!-- snippet: Usage -->

<a id='snippet-Usage'></a>

var builder = new BookBuilder();

List<Employee> data =
[
    new()
    {
        Id = 1,
        Name = "John Doe",
        Email = "john@company.com",
        HireDate = new(2020, 1, 15),
        Salary = 75000,
        IsActive = true,
        Status = EmployeeStatus.FullTime
    },
    new()
    {
        Id = 2,
        Name = "Jane Smith",
        Email = "jane@company.com",
        HireDate = new(2019, 3, 22),
        Salary = 120000,
        IsActive = true,
        Status = EmployeeStatus.FullTime
    },
];
builder.AddSheet(data);

using var book = await builder.Build();

<sup><a href='/src/ExcelsiorAspose.Tests/UsageTests.cs#L7-L38' title='Snippet source file'>snippet source</a> | <a href='#snippet-Usage' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

The above sample builds an instance of the Workbook for the target library:

  • Aspose.Cells.Workbook for Aspose
  • ClosedXML.Excel.IXLWorkbook for ClosedXml.
  • ExcelsiorSyncfusion.IDisposableBook for Syncfusion. Which implements both Syncfusion.XlsIO.IWorkbook, and System.IDisposable
  • ExcelsiorOpenXml.OpenXmlBook for OpenXml.

Result:

<img src="/src/ExcelsiorClosedXml.Tests/UsageTests.Test_Sheet1.png">

Worksheet Name

Worksheet defaults to SheetN, when N is a counter. So the first sheet is Sheet1, the second is Sheet2, etc.

The name can be controlled by passing an explicit value.

<!-- snippet: WorksheetName -->

<a id='snippet-WorksheetName'></a>

var builder = new BookBuilder();
builder.AddSheet(employees, "Employee Report");

<sup><a href='/src/ExcelsiorAspose.Tests/WorksheetName.cs#L9-L14' title='Snippet source file'>snippet source</a> | <a href='#snippet-WorksheetName' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

DataAnnotations Attributes

DisplayAttribute and DisplayNameAttribute from System.ComponentModel.DataAnnotations are supported.

DisplayAttribute and DisplayNameAttribute are support for scenarios where it is not convenient to reference Excelsior from that assembly.<!-- singleLineInclude: DisplayAttributeScenario. path: /docs/DisplayAttributeScenario.include.md -->

<!-- snippet: DataAnnotationsModel -->

<a id='snippet-DataAnnotationsModel'></a>

public class Employee
{
    [Display(Name = "Employee ID", Order = 1)]
    public required int Id { get; init; }

    [Display(Name = "Full Name", Order = 2)]
    public required string Name { get; init; }

    [Display(Name = "Email Address", Order = 3)]
    public required string Email { get; init; }

    [Display(Name = "Hire Date", Order = 4)]
    public Date? HireDate { get; init; }

    [Display(Name = "Annual Salary", Order = 5)]
    public int Salary { get; init; }

    [DisplayName("IsActive")]
    public bool IsActive { get; init; }

    public EmployeeStatus Status { get; init; }
}

public enum EmployeeStatus
{
    [Display(Name = "Full Time")]
    FullTime,

    [Display(Name = "Part Time")]
    PartTime,

    [Display(Name = "Contract")]
    Contract,

    [Display(Name = "Terminated")]
    Terminated
}

<sup><a href='/src/ExcelsiorAspose.Tests/DataAnnotationsTests.cs#L43-L83' title='Snippet source file'>snippet source</a> | <a href='#snippet-DataAnnotationsModel' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Result

<img src="/src/ExcelsiorClosedXml.Tests/DataAnnotationsTests.Simple_Sheet1.png">

Saving to a stream

To save to a stream use ToStream().

<!-- snippet: ToStream -->

<a id='snippet-ToStream'></a>

var builder = new BookBuilder();
builder.AddSheet(data);

var stream = new MemoryStream();
await builder.ToStream(stream);

<sup><a href='/src/ExcelsiorAspose.Tests/Saving.cs#L10-L18' title='Snippet source file'>snippet source</a> | <a href='#snippet-ToStream' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Custom Headings

The heading text for a column can be overridden:

Fluent

<!-- snippet: CustomHeadings -->

<a id='snippet-CustomHeadings'></a>

var builder = new BookBuilder();
builder.AddSheet(employees)
    .Column(
        _ => _.Name,
        _ => _.Heading = "Employee Name");

<sup><a href='/src/ExcelsiorAspose.Tests/Headings.cs#L9-L17' title='Snippet source file'>snippet source</a> | <a href='#snippet-CustomHeadings' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

ColumnAttribute

public class Employee
{
    [Column(Heading = "Employee Name")]
    public required string Name { get; init; }

DisplayNameAttribute

public class Employee
{
    [DisplayName("Employee Name")]
    public required string Name { get; init; }

DisplayAttribute

public class Employee
{
    [Display(Name = "Employee Name")]
    public required string Name { get; init; }

Result:

<img src="/src/ExcelsiorClosedXml.Tests/Headings.Fluent_Sheet1.png">

Order of precedence

  1. Fluent
  2. ColumnAttribute
  3. DisplayAttribute
  4. DisplayNameAttribute

Column Ordering

The column order can be overridden:

<!-- snippet: ColumnOrdering -->

<a id='snippet-ColumnOrdering'></a>

var builder = new BookBuilder();
builder.AddSheet(employees)
    .Column(_ => _.Email, _ => _.Order = 1)
    .Column(_ => _.Name, _ => _.Order = 2)
    .Column(_ => _.Salary, _ => _.Order = 3);

<sup><a href='/src/ExcelsiorAspose.Tests/ColumnOrdering.cs#L9-L17' title='Snippet source file'>snippet source</a> | <a href='#snippet-ColumnOrdering' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Result:

<img src="/src/ExcelsiorClosedXml.Tests/ColumnOrdering.Fluent_Sheet1.png">

Heading Style

<!-- snippet: HeadingStyle -->

<a id='snippet-HeadingStyle'></a>

var builder = new BookBuilder(
    headingStyle: style =>
    {
        style.Font.Bold = true;
        style.Font.FontColor = XLColor.White;
        style.Fill.BackgroundColor = XLColor.DarkBlue;
    });
builder.AddSheet(data);

<sup><a href='/src/ExcelsiorClosedXml.Tests/StyleTests.cs#L10-L21' title='Snippet source file'>snippet source</a> | <a href='#snippet-HeadingStyle' title='Start of snippet'>anchor</a></sup>

<!-- endSnippet -->

Result:

<img src="/src/ExcelsiorClosedXml.Tests/StyleTests.HeadingStyle_Sheet1.png">

Global Style

<!-- snippet: GlobalStyle -->

<a id='snippet-GlobalStyle'></a>

var builder = new BookBuilder(
    globalStyle: style =>
    {
        style.Font.Bold = true;
        style.Font.FontColor = XLColor.White;
        style.Fill.BackgroundColor = XLColor.DarkBlue;
    });
builder.AddSheet(data);

<sup><a href='/src/ExcelsiorClosedXml.Tests/StyleTests.cs#L33-L44' title='Snippet source file'>snippet source</a> | <a href='#snippet-GlobalStyle' title='Start of snippet'>a

Related Skills

View on GitHub
GitHub Stars69
CategoryDevelopment
Updated6h ago
Forks2

Languages

C#

Security Score

95/100

Audited on Mar 30, 2026

No findings