< Summary

Information
Class: ArturRios.Data.Export.Excel.Exporters.ExcelExporter<T>
Assembly: ArturRios.Data.Export.Excel
File(s): /home/runner/work/dotnet-data/dotnet-data/src/ArturRios.Data.Export.Excel/Exporters/ExcelExporter.cs
Line coverage
86%
Covered lines: 25
Uncovered lines: 4
Coverable lines: 29
Total lines: 77
Line coverage: 86.2%
Branch coverage
92%
Covered branches: 39
Total branches: 42
Branch coverage: 92.8%
Method coverage
100%
Covered methods: 3
Fully covered methods: 2
Total methods: 3
Method coverage: 100%
Full method coverage: 66.6%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
WriteCoreAsync(...)100%1414100%
SetCell(...)89.28%1262850%

File(s)

/home/runner/work/dotnet-data/dotnet-data/src/ArturRios.Data.Export.Excel/Exporters/ExcelExporter.cs

#LineLine coverage
 1using ArturRios.Data.Export.Abstractions;
 2using ArturRios.Data.Export.Excel.Configuration;
 3using ArturRios.Data.Export.Exporters;
 4using ClosedXML.Excel;
 5using Microsoft.Extensions.Logging;
 6
 7namespace ArturRios.Data.Export.Excel.Exporters;
 8
 9/// <summary>Writes records to a single-worksheet .xlsx workbook using ClosedXML and the shared column map.</summary>
 10/// <typeparam name="T">The record type.</typeparam>
 11/// <param name="options">Excel options.</param>
 12/// <param name="logger">Optional logger; see <see cref="ExporterBase{T}" />.</param>
 13public class ExcelExporter<T>(ExcelExportOptions options, ILogger<ExcelExporter<T>>? logger = null)
 814    : ExporterBase<T>(logger) where T : class
 15{
 16    /// <inheritdoc />
 17    protected override Task WriteCoreAsync(IEnumerable<T> data, Stream destination, CancellationToken ct)
 18    {
 619        var columns = ColumnMap.For<T>();
 620        using var workbook = new XLWorkbook();
 621        var worksheet = workbook.Worksheets.Add(options.SheetName);
 622        var row = 1;
 23
 624        if (options.IncludeHeader)
 25        {
 4826            for (var i = 0; i < columns.Count; i++)
 27            {
 1828                var cell = worksheet.Cell(row, i + 1);
 1829                cell.Value = columns[i].Header;
 3630                if (options.BoldHeader) cell.Style.Font.Bold = true;
 31            }
 32
 633            row++;
 34        }
 35
 2036        foreach (var item in data)
 37        {
 438            ct.ThrowIfCancellationRequested();
 3239            for (var i = 0; i < columns.Count; i++)
 40            {
 1241                SetCell(worksheet.Cell(row, i + 1), columns[i].Getter(item));
 42            }
 43
 444            row++;
 45        }
 46
 647        if (options.AutoFitColumns && columns.Count > 0)
 48        {
 649            worksheet.Columns().AdjustToContents();
 50        }
 51
 652        workbook.SaveAs(destination);
 653        return Task.CompletedTask;
 654    }
 55
 56    private static void SetCell(IXLCell cell, object? value)
 57    {
 58        switch (value)
 59        {
 60            case null:
 61                break;
 62            case bool b:
 063                cell.Value = b;
 064                break;
 65            case DateTime dt:
 066                cell.Value = dt;
 067                break;
 68            // xlsx stores all numbers as IEEE-754 double; long/ulong > 2^53 and high-precision decimals lose precision.
 69            case sbyte or byte or short or ushort or int or uint or long or ulong or float or double or decimal:
 870                cell.Value = Convert.ToDouble(value, System.Globalization.CultureInfo.InvariantCulture);
 871                break;
 72            default:
 473                cell.Value = ValueRenderer.Render(value);
 74                break;
 75        }
 476    }
 77}