Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README-V2.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,30 @@ using var stream = File.OpenRead(path);
var rows = importer.Query<UserAccount>(stream);
```

Only public properties get mapped by default, but public fields can also be mapped if decorated with `MiniExcelColumnAttribute` or any of the other MiniExcel attributes:
```csharp
public class UserAccount
{
[MiniExcelColumn]
public Guid ID;

public string Name { get; set; }

[MiniExcelFormat("dd/MM/yyyy")]
public DateTime BoD;

public int Age { get; set; }

[MiniExcelColumnIndex(2)]
public bool VIP;

public decimal Points { get; set; }
}

var importer = MiniExcel.Importers.GetOpenXmlImporter();
var rows = importer.Query<UserAccount>(path);
```

#### 2. Execute a query and map it to a list of dynamic objects

By default no header will be used and the dynamic keys will be `.A`, `.B`, `.C`, etc..:
Expand Down
8 changes: 4 additions & 4 deletions src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
public interface IMiniExcelWriteAdapter
{
bool TryGetKnownCount(out int count);
List<MiniExcelColumnInfo>? GetColumns();
IEnumerable<IEnumerable<CellWriteInfo>> GetRows(List<MiniExcelColumnInfo> props, CancellationToken cancellationToken = default);
List<MiniExcelColumnMapping>? GetColumns();
IEnumerable<IEnumerable<CellWriteInfo>> GetRows(List<MiniExcelColumnMapping> props, CancellationToken cancellationToken = default);
}

public readonly struct CellWriteInfo(object? value, int cellIndex, MiniExcelColumnInfo prop)
public readonly struct CellWriteInfo(object? value, int cellIndex, MiniExcelColumnMapping prop)
{
public object? Value { get; } = value;
public int CellIndex { get; } = cellIndex;
public MiniExcelColumnInfo Prop { get; } = prop;
public MiniExcelColumnMapping Prop { get; } = prop;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

public interface IMiniExcelWriteAdapterAsync
{
Task<List<MiniExcelColumnInfo>?> GetColumnsAsync();
IAsyncEnumerable<CellWriteInfo[]> GetRowsAsync(List<MiniExcelColumnInfo> props, CancellationToken cancellationToken);
Task<List<MiniExcelColumnMapping>?> GetColumnsAsync();
IAsyncEnumerable<CellWriteInfo[]> GetRowsAsync(List<MiniExcelColumnMapping> props, CancellationToken cancellationToken);
}
4 changes: 4 additions & 0 deletions src/MiniExcel.Core/Attributes/MiniExcelAttributeBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace MiniExcelLib.Core.Attributes;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public abstract class MiniExcelAttributeBase : Attribute;
21 changes: 10 additions & 11 deletions src/MiniExcel.Core/Attributes/MiniExcelColumnAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
namespace MiniExcelLib.Core.Attributes;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MiniExcelColumnAttribute : Attribute
public class MiniExcelColumnAttribute : MiniExcelAttributeBase
{
private int _index = -1;
private string? _xName;

public string? Name { get; set; }
public string[]? Aliases { get; set; } = [];
public string? Format { get; set; }
public bool Ignore { get; set; }
public string[]? Aliases { get; set; } = [];
public string? Format { get; set; }
public bool Ignore { get; set; }

internal int FormatId { get; private set; } = -1;
public double Width { get; set; } = 8.42857143;
public ColumnType Type { get; set; } = ColumnType.Value;
Expand All @@ -35,19 +34,19 @@ private void Init(int index, string? columnName = null)
_index = index;
_xName ??= columnName ?? CellReferenceConverter.GetAlphabeticalIndex(index);
}

public void SetFormatId(int formatId) => FormatId = formatId;
}

public enum ColumnType { Value, Formula }
public void SetFormatId(int formatId) => FormatId = formatId;
}

public class DynamicExcelColumn : MiniExcelColumnAttribute
{
public string Key { get; set; }
public Func<object, object>? CustomFormatter { get; set; }
public Func<object?, object?>? CustomFormatter { get; set; }

public DynamicExcelColumn(string key)
{
Key = key;
}
}

public enum ColumnType { Value, Formula }
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace MiniExcelLib.Core.Attributes;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MiniExcelColumnIndexAttribute : Attribute
public class MiniExcelColumnIndexAttribute : MiniExcelAttributeBase
{
public int ExcelColumnIndex { get; set; }
internal string? ExcelXName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace MiniExcelLib.Core.Attributes;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MiniExcelColumnNameAttribute(string columnName, string[]? aliases = null) : Attribute
public class MiniExcelColumnNameAttribute(string columnName, string[]? aliases = null) : MiniExcelAttributeBase
{
public string ExcelColumnName { get; set; } = columnName;
public string[] Aliases { get; set; } = aliases ?? [];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace MiniExcelLib.Core.Attributes;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MiniExcelColumnWidthAttribute(double columnWidth) : Attribute
public class MiniExcelColumnWidthAttribute(double columnWidth) : MiniExcelAttributeBase
{
public double ExcelColumnWidth { get; set; } = columnWidth;
}
3 changes: 1 addition & 2 deletions src/MiniExcel.Core/Attributes/MiniExcelFormatAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace MiniExcelLib.Core.Attributes;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MiniExcelFormatAttribute(string format) : Attribute
public class MiniExcelFormatAttribute(string format) : MiniExcelAttributeBase
{
public string Format { get; set; } = format;
}
3 changes: 1 addition & 2 deletions src/MiniExcel.Core/Attributes/MiniExcelIgnoreAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace MiniExcelLib.Core.Attributes;

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MiniExcelIgnoreAttribute(bool ignore = true) : Attribute
public class MiniExcelIgnoreAttribute(bool ignore = true) : MiniExcelAttributeBase
{
public bool Ignore { get; set; } = ignore;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace MiniExcelLib.Core.Exceptions;

public class MiniExcelColumnNotFoundException(
public class ColumnNotFoundException(
string? columnIndex,
string? columnName,
string[] columnAliases,
Expand Down
8 changes: 8 additions & 0 deletions src/MiniExcel.Core/Exceptions/InvalidMappingException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace MiniExcelLib.Core.Exceptions;

public class InvalidMappingException(string message, Type? type, MemberInfo? member = null)
: InvalidOperationException(message)
{
public Type? InvalidType { get; } = type;
public MemberInfo? InvalidProperty { get; } = member;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace MiniExcelLib.Core.Exceptions;

public class MiniExcelNotSerializableException(string message, MemberInfo member)
public class MemberNotSerializableException(string message, MemberInfo member)
: InvalidOperationException(message)
{
public MemberInfo Member { get; } = member;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
namespace MiniExcelLib.Core.Exceptions;

public class MiniExcelInvalidCastException(string columnName, int row, object value, Type invalidCastType, string message)
public class ValueNotAssignableException(string columnName, int row, object value, Type columnType, string message)
: InvalidCastException(message)
{
public string ColumnName { get; set; } = columnName;
public int Row { get; set; } = row;
public object Value { get; set; } = value;
public Type InvalidCastType { get; set; } = invalidCastType;
public Type ColumnType { get; set; } = columnType;
}
9 changes: 9 additions & 0 deletions src/MiniExcel.Core/Helpers/AsyncEnumerableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,13 @@ public static async Task<List<T>> CreateListAsync<T>(this IAsyncEnumerable<T> en

// needed by the SyncGenerator
public static List<T> CreateList<T>(this IEnumerable<T> enumerable) => [..enumerable];

public static async IAsyncEnumerable<IDictionary<string, object?>> CastToDictionary(this IAsyncEnumerable<dynamic> enumerable, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
await foreach (var item in enumerable.WithCancellation(cancellationToken).ConfigureAwait(false))
{
if (item is IDictionary<string, object?> dict)
yield return dict;
}
}
}
39 changes: 39 additions & 0 deletions src/MiniExcel.Core/Helpers/ExpandoHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Dynamic;

namespace MiniExcelLib.Core.Helpers;

public static class ExpandoHelper
{
public static IDictionary<string, object?> CreateEmptyByIndices(int maxColumnIndex, int startCellIndex)
{
IDictionary<string, object?> cell = new ExpandoObject();
for (int i = startCellIndex; i <= maxColumnIndex; i++)
{
var key = CellReferenceConverter.GetAlphabeticalIndex(i);
#if NETCOREAPP2_0_OR_GREATER
cell.TryAdd(key, null);
#else
if (!cell.ContainsKey(key))
cell.Add(key, null);
#endif
}

return cell;
}

public static IDictionary<string, object?> CreateEmptyByHeaders(Dictionary<int, string> headers)
{
IDictionary<string, object?> cell = new ExpandoObject();
foreach (var hr in headers)
{
#if NETCOREAPP2_0_OR_GREATER
cell.TryAdd(hr.Value, null);
#else
if (!cell.ContainsKey(hr.Value))
cell.Add(hr.Value, null);
#endif
}

return cell;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace MiniExcelLib.Core.Helpers;

internal static class ListHelper
internal static class ListExtensions
{
internal static bool StartsWith<T>(this IList<T> span, IList<T> value) where T : IEquatable<T>
{
Expand All @@ -12,4 +12,4 @@ internal static bool StartsWith<T>(this IList<T> span, IList<T> value) where T :

return span.Take(value.Count).SequenceEqual(value);
}
}
}
Loading
Loading