FluentSpreadsheets.ClosedXML 0.0.2-alpha

This is a prerelease version of FluentSpreadsheets.ClosedXML.
There is a newer version of this package available.
See the version list below for details.
dotnet add package FluentSpreadsheets.ClosedXML --version 0.0.2-alpha                
NuGet\Install-Package FluentSpreadsheets.ClosedXML -Version 0.0.2-alpha                
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="FluentSpreadsheets.ClosedXML" Version="0.0.2-alpha" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FluentSpreadsheets.ClosedXML --version 0.0.2-alpha                
#r "nuget: FluentSpreadsheets.ClosedXML, 0.0.2-alpha"                
#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.
// Install FluentSpreadsheets.ClosedXML as a Cake Addin
#addin nuget:?package=FluentSpreadsheets.ClosedXML&version=0.0.2-alpha&prerelease

// Install FluentSpreadsheets.ClosedXML as a Cake Tool
#tool nuget:?package=FluentSpreadsheets.ClosedXML&version=0.0.2-alpha&prerelease                

FluentSpreadsheets

FluentSpreadsheets

badge

FluentSpreadsheets.ClosedXML

badge

FluentSpreadsheets.GoogleSheets

badge

Overview

FluentSpreadsheets library consists of two APIs:

  • Component API
    An API that provides a set of components, that can be used for building static UI with sheet cells as building blocks, as well as base logic for drawing defined component composition on the sheet.
  • Sheets API
    An API that provides a set of abstractions to define sheet segments that will dynamically build components, providing a way to build dynamic UI based on given data, as well as a way to combine an output from sheet segments into a single component representing a built table.

Examples

Component API

The base unit of component API is IComponent interface, it provides a basic interface to interact with all components.

public interface IComponent
{
    Size Size { get; }

    void Accept(IComponentVisitor visitor);
}

There are many derived interfaces from IComponent used to reflect on component type in IComponentVisitor.

All component implementations are internal, so to create an instance of a component you need to use a static class ComponentFactory.

Hint

You can import static members of ComponentFactory for clener code.

using static FluentSpreadsheets.ComponentFactory;

Usage

  • Use .Label to create a label component. You can pass a string to it, or use a generic overload which will call ToString on the passed object (IFormattable overload supported).

    Label("Hello, World!");
    Label(2.2, CultureInfo.InvariantCulture);
    
  • Use .VStack & .HStack to stack components vertically or horizontally.

    VStack
    (
        HStack
        (
            Label("Hello"),
            Label(",")
        ),
        Label("World!")
    )
    

    The result will be something like this:
    Stacks

    Stacks will automatically scale their children so they all will have an equal width/height and fill a rectangle.

  • Use extension methods to style components.

    VStack
    (
        HStack
        (
            Label("Hello")
                .WithContentAlignment(HorizontalAlignment.Trailing)
                .WithTrailingBorder(BorderType.Thin, Color.Black),
            Label(",")
        ),
        Label("Styles!")
            .WithContentAlignment(HorizontalAlignment.Center, VerticalAlignment.Top)
            .WithTopBorder(BorderType.Thin, Color.Black)
            .WithRowHeight(20)
    ).WithBottomBorder(BorderType.Thin, Color.Black).WithTrailingBorder(BorderType.Thin, Color.Black);
    

    The result will be something like this:
    Styles

Output

Code above will only produce component composition stored as objects in memory. To render it on the sheet, you need to use IComponentVisitor.

Now supported:
  • Excel output via "ClosedXML" library. (You will need to reference a FluentSpreadsheets.ClosedXML NuGet package)
    var workbook = new XLWorkbook();
    var worksheet = workbook.AddWorksheet("Sample");
    var xlVisitor = new ClosedXmlVisitor(worksheet, new Index(1, 1));
    
    var helloComponent =
        VStack
        (
            HStack
            (
                Label("Hello")
                    .WithContentAlignment(HorizontalAlignment.Trailing)
                    .WithTrailingBorder(BorderType.Thin, Color.Black),
                Label(",")
            ),
            Label("Styles!")
                .WithContentAlignment(HorizontalAlignment.Center, VerticalAlignment.Top)
                .WithTopBorder(BorderType.Thin, Color.Black)
                .WithRowHeight(20)
        ).WithBottomBorder(BorderType.Thin, Color.Black).WithTrailingBorder(BorderType.Thin, Color.Black);
    
    var renderer = new ClosedXmlComponentRenderer();
    var renderCommand = new ClosedXmlRenderCommand(worksheet, helloComponent);
    
    await renderer.RenderAsync(renderCommand);
    
    workbook.SaveAs("sample.xlsx");
    
  • Google Sheets output via "Google Sheets API v4" library. (You will need to reference a FluentSpreadsheets.GoogleSheets NuGet package)
    var credential = GoogleCredential.FromFile("credentials.json");
    
    var initializer = new BaseClientService.Initializer
    {
      HttpClientInitializer = credential
    };
    
    var service = new SheetsService(initializer);
    var renderer = new GoogleSheetComponentRenderer(service);  
    
    var helloComponent =
        VStack
        (
            HStack
            (
                Label("Hello")
                    .WithContentAlignment(HorizontalAlignment.Trailing)
                    .WithTrailingBorder(BorderType.Thin, Color.Black),
                Label(",")
            ),
            Label("Styles!")
                .WithContentAlignment(HorizontalAlignment.Center, VerticalAlignment.Top)
                .WithTopBorder(BorderType.Thin, Color.Black)
                .WithRowHeight(20)
        ).WithBottomBorder(BorderType.Thin, Color.Black).WithTrailingBorder(BorderType.Thin, Color.Black);
    
    const string spreadsheetId = "SampleSpreadsheetId";
    const string title = "SampleTitle";
    
    var renderCommandFactory = new RenderCommandFactory(service);
    var renderCommand = await renderCommandFactory.CreateAsync(spreadsheetId, title, helloComponent);
    
    await renderer.RenderAsync(renderCommand);
    

Sheets API

The base unit of sheets API is ISheetSegment interface, it provides an interface to get components for different sheet section parts (header, rows, footer).

public interface ISheetSegment<THeaderData, TRowData, TFooterData>
{
    IEnumerable<IComponent> BuildHeaders(THeaderData data);

    IEnumerable<IComponent> BuildRows(HeaderRowData<THeaderData, TRowData> data, int rowIndex);
    
    IEnumerable<IComponent> BuildFooters(HeaderFooterData<THeaderData, TFooterData> data);
}

There are two main kinds of sheet segments:

  • Plain SheetSegmentBase
    A segment that consists of a single data column.
  • A PrototypeSheetSegmentBase
    A segment that can represent a collection of data columns.\

SheetSegmentBase

  • Requires you to implement 2 methods
    • IComponent BuildHeader(THeaderData data)
    • IComponent BuildRow(HeaderRowData<THeaderData, TRowData> data, int rowIndex)
  • With an option to overload
    • IComponent BuildFooter(HeaderFooterData<THeaderData, TFooterData> data)

PrototypeSheetSegmentBase

Prototype sheet segments are useful when you table may have a dynamic amount of columns depending on the data that has been provided.

To be a part of a sheet segment collection, prototype must implement ISheetSegment<THeaderData, TRowData, TFooterData> interface, just like any other static sheet segment. But prototype segment must have a collection of header data to create multiple segments, so you must implement IEnumerable<TPrototypeHeaderData> SelectHeaderData(THeaderData data) method to extract collection of header data that prototypes will use from general header data.

PrototypeSheetSegmentBase`6 also requires you to implement:

  • TPrototypeRowData SelectRowData(HeaderRowData<TPrototypeHeaderData, TRowData> data)
  • TPrototypeFooterData SelectFooterData(HeaderFooterData<TPrototypeHeaderData, TFooterData> data)

But there are overloads PrototypeSheetSegmentBase`4 and PrototypeSheetSegmentBase`5 that only require SelectHeaderData and SelectHeaderData + SelectRowData methods respectively.

SheetBuilder

The type SheetBuilder that conforms to ISheetBuilder interface is used to build a sheet from collection of sheet segments and corresponding sheet data.

public interface ISheetBuilder
{
    IComponent Build<THeaderData, TRowData, TFooterData>(
        IReadOnlyCollection<ISheetSegment<THeaderData, TRowData, TFooterData>> segments,
        SheetData<THeaderData, TRowData, TFooterData> data);
}

It's .Build method returns a component which is a rectangle that represents table built from given data.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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
1.6.7 259 11/12/2023
1.6.6 157 11/1/2023
1.6.5 137 10/12/2023
1.6.4 147 9/27/2023
1.6.3 140 9/27/2023
1.5.1 123 9/21/2023
1.4.4 319 3/22/2023
1.4.3 252 3/22/2023
1.4.2 232 3/22/2023
1.4.1 230 3/22/2023
1.4.0 232 3/21/2023
1.3.1 270 2/20/2023
1.3.0 379 11/24/2022
1.2.4 408 9/21/2022
1.2.3 417 9/21/2022
1.2.2 497 9/18/2022
1.2.1 478 9/14/2022
1.2.0 444 9/12/2022
1.1.0 432 9/11/2022
1.0.1 434 9/4/2022
1.0.0 409 8/30/2022
0.0.3-alpha 201 8/6/2022
0.0.2-alpha 191 8/5/2022
0.0.1-alpha 194 7/31/2022