diff --git a/MiniExcel.slnx b/MiniExcel.slnx
index 989be6cc..73698bc3 100644
--- a/MiniExcel.slnx
+++ b/MiniExcel.slnx
@@ -25,6 +25,7 @@
+
diff --git a/src/.editorconfig b/src/.editorconfig
index a226b8bb..68647853 100644
--- a/src/.editorconfig
+++ b/src/.editorconfig
@@ -6,6 +6,7 @@ dotnet_diagnostic.CA1835.severity = error
# CA1849: Call async methods when in an async method
dotnet_diagnostic.CA1849.severity = error
+# CA2000: Dispose objects before losing scope
dotnet_diagnostic.CA2000.severity = error
# CA2007: Do not directly await a Task
diff --git a/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapter.cs b/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapter.cs
index 7c0784ef..85408fc1 100644
--- a/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapter.cs
+++ b/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapter.cs
@@ -4,12 +4,12 @@ public interface IMiniExcelWriteAdapter
{
bool TryGetKnownCount(out int count);
List? GetColumns();
- IEnumerable> GetRows(List props, CancellationToken cancellationToken = default);
+ IEnumerable GetRows(List mappings, CancellationToken cancellationToken = default);
}
-public readonly struct CellWriteInfo(object? value, int cellIndex, MiniExcelColumnMapping prop)
+public readonly struct CellWriteInfo(object? value, int cellIndex, MiniExcelColumnMapping? mapping)
{
public object? Value { get; } = value;
public int CellIndex { get; } = cellIndex;
- public MiniExcelColumnMapping Prop { get; } = prop;
-}
\ No newline at end of file
+ public MiniExcelColumnMapping? Mapping { get; } = mapping;
+}
diff --git a/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapterAsync.cs b/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapterAsync.cs
index 2e88ec26..fb754da8 100644
--- a/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapterAsync.cs
+++ b/src/MiniExcel.Core/Abstractions/IMiniExcelWriteAdapterAsync.cs
@@ -3,5 +3,5 @@
public interface IMiniExcelWriteAdapterAsync
{
Task?> GetColumnsAsync();
- IAsyncEnumerable GetRowsAsync(List props, CancellationToken cancellationToken);
+ IAsyncEnumerable GetRowsAsync(List mappings, CancellationToken cancellationToken);
}
\ No newline at end of file
diff --git a/src/MiniExcel.Core/Helpers/NetSatandardExtensions.cs b/src/MiniExcel.Core/Helpers/NetSatandardExtensions.cs
new file mode 100644
index 00000000..50d412a9
--- /dev/null
+++ b/src/MiniExcel.Core/Helpers/NetSatandardExtensions.cs
@@ -0,0 +1,11 @@
+namespace MiniExcelLib.Core.Helpers;
+
+public static class NetStandardExtensions
+{
+#if NETSTANDARD2_0
+ public static TValue? GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key, TValue? defaultValue = default)
+ {
+ return dictionary.TryGetValue(key, out var value) ? value : defaultValue;
+ }
+#endif
+}
diff --git a/src/MiniExcel.Core/Reflection/ColumnMappingsProvider.cs b/src/MiniExcel.Core/Reflection/ColumnMappingsProvider.cs
index 1e0d72b5..5a9f1e72 100644
--- a/src/MiniExcel.Core/Reflection/ColumnMappingsProvider.cs
+++ b/src/MiniExcel.Core/Reflection/ColumnMappingsProvider.cs
@@ -48,14 +48,14 @@ internal static List GetMappingsForImport(Type type, str
private static List GetMappingsForExport(this Type type, MiniExcelBaseConfiguration configuration)
{
- var props = GetColumnMappings(type, ExportMembersFlags, configuration)
+ var mappings = GetColumnMappings(type, ExportMembersFlags, configuration)
.Where(prop => prop?.MemberAccessor.CanRead is true)
.ToList();
- if (props.Count == 0)
+ if (mappings.Count == 0)
throw new InvalidMappingException($"{type.Name} must contain at least one mappable property or field.", type);
- return SortMappings(props);
+ return SortMappings(mappings);
}
private static List SortMappings(List mappings)
@@ -81,29 +81,29 @@ internal static List GetMappingsForImport(Type type, str
if (explicitIndexMappings.Count != 0)
maxColumnIndex = Math.Max(explicitIndexMappings.Max(w => w?.ExcelColumnIndex ?? 0), maxColumnIndex);
- var withoutCustomIndexProps = mappings
+ var mappingsWithoutCustomIndex = mappings
.Where(w => w?.ExcelColumnIndex is null or -1)
.ToList();
var index = 0;
- var newProps = new List();
+ var newMappings = new List();
for (int i = 0; i <= maxColumnIndex; i++)
{
if (explicitIndexMappings.SingleOrDefault(s => s?.ExcelColumnIndex == i) is { } p1)
{
- newProps.Add(p1);
+ newMappings.Add(p1);
}
else
{
- var p2 = withoutCustomIndexProps.ElementAtOrDefault(index);
+ var map = mappingsWithoutCustomIndex.ElementAtOrDefault(index);
- p2?.ExcelColumnIndex = i;
- newProps.Add(p2);
+ map?.ExcelColumnIndex = i;
+ newMappings.Add(map);
index++;
}
}
- return newProps;
+ return newMappings;
}
private static IEnumerable GetColumnMappings(Type type, BindingFlags bindingFlags, MiniExcelBaseConfiguration configuration)
@@ -156,7 +156,7 @@ internal static List GetMappingsForImport(Type type, str
private static List GetDictionaryColumnInfo(IDictionary? dicString, IDictionary? dic, MiniExcelBaseConfiguration configuration)
{
- var props = new List();
+ var mappings = new List();
var keys = dicString?.Keys.ToList()
?? dic?.Keys
@@ -164,15 +164,15 @@ internal static List GetMappingsForImport(Type type, str
foreach (var key in keys)
{
- SetDictionaryColumnInfo(props, key, configuration);
+ SetDictionaryColumnInfo(mappings, key, configuration);
}
- return SortMappings(props);
+ return SortMappings(mappings);
}
- private static void SetDictionaryColumnInfo(List props, object key, MiniExcelBaseConfiguration configuration)
+ private static void SetDictionaryColumnInfo(List mappings, object key, MiniExcelBaseConfiguration configuration)
{
- var mapping = new MiniExcelColumnMapping
+ var map = new MiniExcelColumnMapping
{
Key = key,
ExcelColumnName = key?.ToString()
@@ -185,40 +185,40 @@ private static void SetDictionaryColumnInfo(List props,
var dynamicColumn = configuration.DynamicColumns.SingleOrDefault(x => x.Key == key?.ToString());
if (dynamicColumn is not null)
{
- mapping.Nullable = true;
+ map.Nullable = true;
if (dynamicColumn is { Format: { } fmt, FormatId: var fmtId })
{
- mapping.ExcelFormat = fmt;
- mapping.ExcelFormatId = fmtId;
+ map.ExcelFormat = fmt;
+ map.ExcelFormatId = fmtId;
}
if (dynamicColumn.Aliases is { } aliases)
- mapping.ExcelColumnAliases = aliases;
+ map.ExcelColumnAliases = aliases;
if (dynamicColumn.IndexName is { } idxName)
- mapping.ExcelIndexName = idxName;
+ map.ExcelIndexName = idxName;
if (dynamicColumn.Name is { } colName)
- mapping.ExcelColumnName = colName;
+ map.ExcelColumnName = colName;
- mapping.ExcelColumnIndex = dynamicColumn.Index;
- mapping.ExcelColumnWidth = dynamicColumn.Width;
- mapping.ExcelHiddenColumn = dynamicColumn.Hidden;
- mapping.ExcelColumnType = dynamicColumn.Type;
- mapping.CustomFormatter = dynamicColumn.CustomFormatter;
+ map.ExcelColumnIndex = dynamicColumn.Index;
+ map.ExcelColumnWidth = dynamicColumn.Width;
+ map.ExcelHiddenColumn = dynamicColumn.Hidden;
+ map.ExcelColumnType = dynamicColumn.Type;
+ map.CustomFormatter = dynamicColumn.CustomFormatter;
isIgnore = dynamicColumn.Ignore;
}
}
if (!isIgnore)
- props.Add(mapping);
+ mappings.Add(map);
}
- internal static bool TryGetColumnMappings(Type? type, MiniExcelBaseConfiguration configuration, out List props)
+ internal static bool TryGetColumnMappings(Type? type, MiniExcelBaseConfiguration configuration, out List mappings)
{
- props = [];
+ mappings = [];
// Unknown type
if (type is null)
@@ -230,7 +230,7 @@ internal static bool TryGetColumnMappings(Type? type, MiniExcelBaseConfiguration
if (ValueIsNeededToDetermineProperties(type))
return false;
- props = type.GetMappingsForExport(configuration);
+ mappings = type.GetMappingsForExport(configuration);
return true;
}
diff --git a/src/MiniExcel.Core/WriteAdapters/AsyncEnumerableWriteAdapter.cs b/src/MiniExcel.Core/WriteAdapters/AsyncEnumerableWriteAdapter.cs
index d9665b09..32ed1509 100644
--- a/src/MiniExcel.Core/WriteAdapters/AsyncEnumerableWriteAdapter.cs
+++ b/src/MiniExcel.Core/WriteAdapters/AsyncEnumerableWriteAdapter.cs
@@ -27,7 +27,7 @@ internal sealed class AsyncEnumerableWriteAdapter(IAsyncEnumerable values,
return ColumnMappingsProvider.GetColumnMappingFromValue(_enumerator.Current, _configuration);
}
- public async IAsyncEnumerable GetRowsAsync(List props, [EnumeratorCancellation] CancellationToken cancellationToken)
+ public async IAsyncEnumerable GetRowsAsync(List mappings, [EnumeratorCancellation] CancellationToken cancellationToken)
{
if (_empty)
yield break;
@@ -44,30 +44,27 @@ public async IAsyncEnumerable GetRowsAsync(List props)
+ private static CellWriteInfo[] GetRowValues(T currentValue, List mappings)
{
var column = 0;
- var result = new List();
+ var result = new List(mappings.Count);
- foreach (var prop in props)
+ foreach (var map in mappings)
{
column++;
-
- if (prop is null)
- continue;
-
- var info = currentValue switch
+ var cellValue = currentValue switch
{
- IDictionary genericDictionary => new CellWriteInfo(genericDictionary[prop.Key.ToString()], column, prop),
- IDictionary dictionary => new CellWriteInfo(dictionary[prop.Key], column, prop),
- _ => new CellWriteInfo(prop.MemberAccessor.GetValue(currentValue), column, prop)
+ _ when map is null => null,
+ IDictionary genericDictionary => genericDictionary[map.Key.ToString()],
+ IDictionary dictionary => dictionary[map.Key],
+ _ => map.MemberAccessor.GetValue(currentValue)
};
- result.Add(info);
+ result.Add(new CellWriteInfo(cellValue, column, map));
}
return result.ToArray();
@@ -84,4 +81,4 @@ public async ValueTask DisposeAsync()
_disposed = true;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/MiniExcel.Core/WriteAdapters/DataReaderWriteAdapter.cs b/src/MiniExcel.Core/WriteAdapters/DataReaderWriteAdapter.cs
index a4bb8815..952e246c 100644
--- a/src/MiniExcel.Core/WriteAdapters/DataReaderWriteAdapter.cs
+++ b/src/MiniExcel.Core/WriteAdapters/DataReaderWriteAdapter.cs
@@ -13,44 +13,48 @@ public bool TryGetKnownCount(out int count)
public List GetColumns()
{
- var props = new List();
+ var mappings = new List();
for (var i = 0; i < _reader.FieldCount; i++)
{
var columnName = _reader.GetName(i);
if (!_configuration.DynamicColumnFirst ||
_configuration.DynamicColumns.Any(d => string.Equals(d.Key, columnName, StringComparison.OrdinalIgnoreCase)))
{
- var prop = ColumnMappingsProvider.GetColumnMappingFromDynamicConfiguration(columnName, _configuration);
- props.Add(prop);
+ var map = ColumnMappingsProvider.GetColumnMappingFromDynamicConfiguration(columnName, _configuration);
+ mappings.Add(map);
}
}
- return props;
+ return mappings;
}
- public IEnumerable> GetRows(List props, CancellationToken cancellationToken = default)
+ public IEnumerable GetRows(List mappings, CancellationToken cancellationToken = default)
{
while (_reader.Read())
{
cancellationToken.ThrowIfCancellationRequested();
- yield return GetRowValues(props);
+ yield return GetRowValues(mappings);
}
}
- private IEnumerable GetRowValues(List props)
+ private CellWriteInfo[] GetRowValues(List mappings)
{
var column = 1;
+ var result = new List(mappings.Count);
+
for (int i = 0; i < _reader.FieldCount; i++)
{
- var prop = props[i];
- if (prop is { ExcelIgnoreColumn: false })
+ var map = mappings[i];
+ if (map is not { ExcelIgnoreColumn: true })
{
var columnIndex = _configuration.DynamicColumnFirst
- ? _reader.GetOrdinal(prop.Key.ToString())
+ ? _reader.GetOrdinal(map.Key.ToString())
: i;
-
- yield return new CellWriteInfo(_reader.GetValue(columnIndex), column, prop);
+
+ result.Add(new CellWriteInfo(_reader.GetValue(columnIndex), column, map));
column++;
}
}
+
+ return result.ToArray();
}
-}
\ No newline at end of file
+}
diff --git a/src/MiniExcel.Core/WriteAdapters/DataTableWriteAdapter.cs b/src/MiniExcel.Core/WriteAdapters/DataTableWriteAdapter.cs
index 273d36bd..be82aa9a 100644
--- a/src/MiniExcel.Core/WriteAdapters/DataTableWriteAdapter.cs
+++ b/src/MiniExcel.Core/WriteAdapters/DataTableWriteAdapter.cs
@@ -13,30 +13,32 @@ public bool TryGetKnownCount(out int count)
public List GetColumns()
{
- var props = new List();
+ var mappings = new List();
for (var i = 0; i < _dataTable.Columns.Count; i++)
{
var columnName = _dataTable.Columns[i].Caption ?? _dataTable.Columns[i].ColumnName;
- var prop = ColumnMappingsProvider.GetColumnMappingFromDynamicConfiguration(columnName, _configuration);
- props.Add(prop);
+ var map = ColumnMappingsProvider.GetColumnMappingFromDynamicConfiguration(columnName, _configuration);
+ mappings.Add(map);
}
- return props;
+ return mappings;
}
- public IEnumerable> GetRows(List props, CancellationToken cancellationToken = default)
+ public IEnumerable GetRows(List mappings, CancellationToken cancellationToken = default)
{
for (int row = 0; row < _dataTable.Rows.Count; row++)
{
cancellationToken.ThrowIfCancellationRequested();
- yield return GetRowValues(row, props);
+ yield return GetRowValues(row, mappings);
}
}
- private IEnumerable GetRowValues(int row, List props)
+ private CellWriteInfo[] GetRowValues(int row, List mappings)
{
+ var result = new List(mappings.Count);
for (int i = 0, column = 1; i < _dataTable.Columns.Count; i++, column++)
{
- yield return new CellWriteInfo(_dataTable.Rows[row][i], column, props[i]);
+ result.Add(new CellWriteInfo(_dataTable.Rows[row][i], column, mappings[i]));
}
+ return result.ToArray();
}
-}
\ No newline at end of file
+}
diff --git a/src/MiniExcel.Core/WriteAdapters/EnumerableWriteAdapter.cs b/src/MiniExcel.Core/WriteAdapters/EnumerableWriteAdapter.cs
index 19c12270..d2a9633b 100644
--- a/src/MiniExcel.Core/WriteAdapters/EnumerableWriteAdapter.cs
+++ b/src/MiniExcel.Core/WriteAdapters/EnumerableWriteAdapter.cs
@@ -23,8 +23,8 @@ public bool TryGetKnownCount(out int count)
public List? GetColumns()
{
- if (ColumnMappingsProvider.TryGetColumnMappings(_genericType, _configuration, out var props))
- return props;
+ if (ColumnMappingsProvider.TryGetColumnMappings(_genericType, _configuration, out var mappings))
+ return mappings;
_enumerator = _values.GetEnumerator();
if (_enumerator.MoveNext())
@@ -42,7 +42,7 @@ public bool TryGetKnownCount(out int count)
}
}
- public IEnumerable> GetRows(List props, CancellationToken cancellationToken = default)
+ public IEnumerable GetRows(List mappings, CancellationToken cancellationToken = default)
{
if (_empty)
yield break;
@@ -59,7 +59,7 @@ public IEnumerable> GetRows(List> GetRows(List GetRowValues(object currentValue, List props)
+
+ private static CellWriteInfo[] GetRowValues(object currentValue, List mappings)
{
- var column = 1;
- foreach (var prop in props)
+ var column = 0;
+ var result = new List(mappings.Count);
+
+ foreach (var map in mappings)
{
- object? cellValue;
- if (prop is null)
- {
- cellValue = null;
- }
- else if (currentValue is IDictionary genericDictionary)
- {
- cellValue = genericDictionary[prop.Key.ToString()];
- }
- else if (currentValue is IDictionary dictionary)
- {
- cellValue = dictionary[prop.Key];
- }
- else
- {
- cellValue = prop.MemberAccessor.GetValue(currentValue);
- }
-
- yield return new CellWriteInfo(cellValue, column, prop);
column++;
+ var cellValue = currentValue switch
+ {
+ _ when map is null => null,
+ IDictionary genericDictionary => genericDictionary[map.Key.ToString()],
+ IDictionary dictionary => dictionary[map.Key],
+ _ => map.MemberAccessor.GetValue(currentValue)
+ };
+ result.Add(new CellWriteInfo(cellValue, column, map));
}
+
+ return result.ToArray();
}
-}
\ No newline at end of file
+}
diff --git a/src/MiniExcel.Csv/CsvWriter.cs b/src/MiniExcel.Csv/CsvWriter.cs
index 37c11ddf..cc24173e 100644
--- a/src/MiniExcel.Csv/CsvWriter.cs
+++ b/src/MiniExcel.Csv/CsvWriter.cs
@@ -24,7 +24,7 @@ internal CsvWriter(Stream stream, object? value, bool printHeader, IMiniExcelCon
private void AppendColumn(StringBuilder rowBuilder, CellWriteInfo column)
{
- rowBuilder.Append(CsvSanitizer.SanitizeCsvField(ToCsvString(column.Value, column.Prop), _configuration));
+ rowBuilder.Append(CsvSanitizer.SanitizeCsvField(ToCsvString(column.Value, column.Mapping), _configuration));
rowBuilder.Append(_configuration.Seperator);
}
@@ -51,14 +51,14 @@ private async Task WriteValuesAsync(StreamWriter writer, object values, str
try
{
#if SYNC_ONLY
- var props = writeAdapter?.GetColumns();
+ var mappings = writeAdapter?.GetColumns();
#else
- var props = writeAdapter is not null
+ var mappings = writeAdapter is not null
? writeAdapter.GetColumns()
: await asyncWriteAdapter!.GetColumnsAsync().ConfigureAwait(false);
#endif
- if (props is null)
+ if (mappings is null)
{
await _writer.WriteAsync(_configuration.NewLine
#if NET5_0_OR_GREATER
@@ -75,7 +75,7 @@ await _writer.FlushAsync(
if (_printHeader)
{
- await _writer.WriteAsync(GetHeader(props)
+ await _writer.WriteAsync(GetHeader(mappings)
#if NET5_0_OR_GREATER
.AsMemory(), cancellationToken
#endif
@@ -92,7 +92,7 @@ await _writer.WriteAsync(newLine
if (writeAdapter is not null)
{
- foreach (var row in writeAdapter.GetRows(props, cancellationToken))
+ foreach (var row in writeAdapter.GetRows(mappings, cancellationToken))
{
rowBuilder.Clear();
foreach (var column in row)
@@ -120,7 +120,7 @@ await _writer.WriteAsync(newLine
else
{
#if !SYNC_ONLY
- await foreach (var row in asyncWriteAdapter!.GetRowsAsync(props, cancellationToken).ConfigureAwait(false))
+ await foreach (var row in asyncWriteAdapter!.GetRowsAsync(mappings, cancellationToken).ConfigureAwait(false))
{
cancellationToken.ThrowIfCancellationRequested();
rowBuilder.Clear();
@@ -221,9 +221,9 @@ public string ToCsvString(object? value, MiniExcelColumnMapping? p)
return Convert.ToString(value, _configuration.Culture) ?? "";
}
- private string GetHeader(List props) => string.Join(
+ private string GetHeader(List mappings) => string.Join(
_configuration.Seperator.ToString(),
- props.Select(s => CsvSanitizer.SanitizeCsvField(s?.ExcelColumnName, _configuration)));
+ mappings.Select(s => CsvSanitizer.SanitizeCsvField(s?.ExcelColumnName, _configuration)));
private void Dispose(bool disposing)
{
diff --git a/src/MiniExcel.OpenXml/FluentMapping/MappingCellStreamAdapter.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingCellStreamAdapter.cs
index 5859d926..0596742e 100644
--- a/src/MiniExcel.OpenXml/FluentMapping/MappingCellStreamAdapter.cs
+++ b/src/MiniExcel.OpenXml/FluentMapping/MappingCellStreamAdapter.cs
@@ -18,11 +18,10 @@ public bool TryGetKnownCount(out int count)
public List GetColumns()
{
- var props = new List();
-
+ var mappings = new List();
for (int i = 0; i < _columnLetters.Length; i++)
{
- props.Add(new MiniExcelColumnMapping
+ mappings.Add(new MiniExcelColumnMapping
{
Key = _columnLetters[i],
ExcelColumnName = _columnLetters[i],
@@ -30,10 +29,10 @@ public List GetColumns()
});
}
- return props;
+ return mappings;
}
- public IEnumerable> GetRows(List props, CancellationToken cancellationToken = default)
+ public IEnumerable GetRows(List mappings, CancellationToken cancellationToken = default)
{
var currentRow = new Dictionary();
var currentRowIndex = 0;
@@ -48,7 +47,7 @@ public IEnumerable> GetRows(List 0 && currentRow.Count > 0)
{
- yield return ConvertRowToCellWriteInfos(currentRow, props);
+ yield return ConvertRowToCellWriteInfos(currentRow, mappings);
}
// Start new row
@@ -63,23 +62,22 @@ public IEnumerable> GetRows(List 0)
{
- yield return ConvertRowToCellWriteInfos(currentRow, props);
+ yield return ConvertRowToCellWriteInfos(currentRow, mappings);
}
}
- private static IEnumerable ConvertRowToCellWriteInfos(Dictionary row, List props)
+ private static CellWriteInfo[] ConvertRowToCellWriteInfos(Dictionary row, List mappings)
{
- var columnIndex = 1;
- foreach (var prop in props)
+ var columnIndex = 0;
+ var result = new List(mappings.Count);
+
+ foreach (var map in mappings)
{
- object? cellValue = null;
- if (row.TryGetValue(prop.Key.ToString(), out var value))
- {
- cellValue = value;
- }
-
- yield return new CellWriteInfo(cellValue, columnIndex, prop);
columnIndex++;
+ var cellValue = row.GetValueOrDefault(map.Key.ToString());
+ result.Add(new CellWriteInfo(cellValue, columnIndex, map));
}
+
+ return result.ToArray();
}
-}
\ No newline at end of file
+}
diff --git a/src/MiniExcel.OpenXml/FluentMapping/MappingRegistry.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingRegistry.cs
index 54d8d629..cf9121fb 100644
--- a/src/MiniExcel.OpenXml/FluentMapping/MappingRegistry.cs
+++ b/src/MiniExcel.OpenXml/FluentMapping/MappingRegistry.cs
@@ -1,4 +1,3 @@
-using System.Reflection;
using MiniExcelLib.OpenXml.FluentMapping.Configuration;
namespace MiniExcelLib.OpenXml.FluentMapping;
@@ -62,9 +61,7 @@ public bool HasMapping()
{
lock (_lock)
{
- return _compiledMappings.TryGetValue(type, out var mapping)
- ? mapping
- : null;
+ return _compiledMappings.GetValueOrDefault(type);
}
}
diff --git a/src/MiniExcel.OpenXml/OpenXmlWriter.cs b/src/MiniExcel.OpenXml/OpenXmlWriter.cs
index e104fa5b..9d9e47ad 100644
--- a/src/MiniExcel.OpenXml/OpenXmlWriter.cs
+++ b/src/MiniExcel.OpenXml/OpenXmlWriter.cs
@@ -247,21 +247,21 @@ private async Task WriteValuesAsync(MiniExcelStreamWriter writer, object va
var isKnownCount = writeAdapter is not null && writeAdapter.TryGetKnownCount(out count);
#if SYNC_ONLY
- var props = writeAdapter?.GetColumns();
+ var mappings = writeAdapter?.GetColumns();
#else
- var props = writeAdapter is not null
+ var mappings = writeAdapter is not null
? writeAdapter.GetColumns()
: await (asyncWriteAdapter?.GetColumnsAsync() ?? Task.FromResult?>(null)).ConfigureAwait(false);
#endif
- if (props is null)
+ if (mappings is null)
{
await WriteEmptySheetAsync(writer).ConfigureAwait(false);
return 0;
}
int maxRowIndex;
- var maxColumnIndex = props.Count(x => x is { ExcelIgnoreColumn: false });
+ var maxColumnIndex = mappings.Count(x => x is { ExcelIgnoreColumn: false });
long dimensionPlaceholderPostition = 0;
await writer.WriteAsync(WorksheetXml.StartWorksheetWithRelationship, cancellationToken).ConfigureAwait(false);
@@ -270,7 +270,7 @@ private async Task WriteValuesAsync(MiniExcelStreamWriter writer, object va
if (isKnownCount)
{
maxRowIndex = _printHeader ? count + 1 : count;
- await writer.WriteAsync(WorksheetXml.Dimension(GetDimensionRef(maxRowIndex, props.Count)), cancellationToken).ConfigureAwait(false);
+ await writer.WriteAsync(WorksheetXml.Dimension(GetDimensionRef(maxRowIndex, mappings.Count)), cancellationToken).ConfigureAwait(false);
}
else if (_configuration.FastMode)
{
@@ -286,11 +286,11 @@ private async Task WriteValuesAsync(MiniExcelStreamWriter writer, object va
if (_configuration.EnableAutoWidth)
{
columnWidthsPlaceholderPosition = await WriteColumnWidthPlaceholdersAsync(writer, maxColumnIndex, cancellationToken).ConfigureAwait(false);
- widths = ExcelColumnWidthCollection.GetFromMappings(props!, _configuration.MinWidth, _configuration.MaxWidth);
+ widths = ExcelColumnWidthCollection.GetFromMappings(mappings!, _configuration.MinWidth, _configuration.MaxWidth);
}
else
{
- var colWidths = ExcelColumnWidthCollection.GetFromMappings(props!);
+ var colWidths = ExcelColumnWidthCollection.GetFromMappings(mappings!);
await WriteColumnsWidthsAsync(writer, colWidths.Columns, cancellationToken).ConfigureAwait(false);
}
@@ -299,13 +299,13 @@ private async Task WriteValuesAsync(MiniExcelStreamWriter writer, object va
var currentRowIndex = 0;
if (_printHeader)
{
- await PrintHeaderAsync(writer, props!, cancellationToken).ConfigureAwait(false);
+ await PrintHeaderAsync(writer, mappings!, cancellationToken).ConfigureAwait(false);
currentRowIndex++;
}
if (writeAdapter is not null)
{
- foreach (var row in writeAdapter.GetRows(props, cancellationToken))
+ foreach (var row in writeAdapter.GetRows(mappings, cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
await writer.WriteAsync(WorksheetXml.StartRow(++currentRowIndex), cancellationToken).ConfigureAwait(false);
@@ -313,7 +313,7 @@ private async Task WriteValuesAsync(MiniExcelStreamWriter writer, object va
foreach (var cellValue in row)
{
cancellationToken.ThrowIfCancellationRequested();
- await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value, cellValue.Prop, widths, cancellationToken).ConfigureAwait(false);
+ await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value, cellValue.Mapping, widths, cancellationToken).ConfigureAwait(false);
progress?.Report(1);
}
await writer.WriteAsync(WorksheetXml.EndRow, cancellationToken).ConfigureAwait(false);
@@ -322,14 +322,14 @@ private async Task WriteValuesAsync(MiniExcelStreamWriter writer, object va
else
{
#if !SYNC_ONLY
- await foreach (var row in asyncWriteAdapter!.GetRowsAsync(props, cancellationToken).ConfigureAwait(false))
+ await foreach (var row in asyncWriteAdapter!.GetRowsAsync(mappings, cancellationToken).ConfigureAwait(false))
{
cancellationToken.ThrowIfCancellationRequested();
await writer.WriteAsync(WorksheetXml.StartRow(++currentRowIndex), cancellationToken).ConfigureAwait(false);
foreach (var cellValue in row)
{
- await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value, cellValue.Prop, widths, cancellationToken).ConfigureAwait(false);
+ await WriteCellAsync(writer, currentRowIndex, cellValue.CellIndex, cellValue.Value, cellValue.Mapping, widths, cancellationToken).ConfigureAwait(false);
progress?.Report(1);
}
await writer.WriteAsync(WorksheetXml.EndRow, cancellationToken).ConfigureAwait(false);
@@ -423,22 +423,22 @@ private static async Task WriteColumnsWidthsAsync(MiniExcelStreamWriter writer,
}
[CreateSyncVersion]
- private async Task PrintHeaderAsync(MiniExcelStreamWriter writer, List props, CancellationToken cancellationToken = default)
+ private async Task PrintHeaderAsync(MiniExcelStreamWriter writer, List mappings, CancellationToken cancellationToken = default)
{
const int yIndex = 1;
await writer.WriteAsync(WorksheetXml.StartRow(yIndex), cancellationToken).ConfigureAwait(false);
var xIndex = 1;
- foreach (var p in props)
+ foreach (var map in mappings)
{
//reason : https://github.com/mini-software/MiniExcel/issues/142
- if (p is not null)
+ if (map is not null)
{
- if (p.ExcelIgnoreColumn)
+ if (map.ExcelIgnoreColumn)
continue;
var r = CellReferenceConverter.GetCellFromCoordinates(xIndex, yIndex);
- await WriteCellAsync(writer, r, columnName: p.ExcelColumnName).ConfigureAwait(false);
+ await WriteCellAsync(writer, r, columnName: map.ExcelColumnName).ConfigureAwait(false);
}
xIndex++;
}
@@ -447,19 +447,19 @@ private async Task PrintHeaderAsync(MiniExcelStreamWriter writer, List SpecialCellType.Header,
var generateCellValuesContext = new GenerateCellValuesContext()
{
- currentHeader = currentHeader,
- headerDiff = headerDiff,
- iEnumerableIndex = iEnumerableIndex,
- isFirst = isFirst,
- newRowIndex = newRowIndex,
- prevHeader = prevHeader,
- rowIndexDiff = rowIndexDiff,
+ CurrentHeader = currentHeader,
+ HeaderDiff = headerDiff,
+ EnumerableIndex = iEnumerableIndex,
+ IsFirst = isFirst,
+ NewRowIndex = newRowIndex,
+ PrevHeader = prevHeader,
+ RowIndexDiff = rowIndexDiff,
};
generateCellValuesContext = await GenerateCellValuesAsync(generateCellValuesContext, endPrefix, writer, rowXml, mergeRowCount, isHeaderRow, rowInfo, row, groupingRowDiff, innerXml, outerXmlOpen, row, cancellationToken).ConfigureAwait(false);
- rowIndexDiff = generateCellValuesContext.rowIndexDiff;
- headerDiff = generateCellValuesContext.headerDiff;
- prevHeader = generateCellValuesContext.prevHeader;
- newRowIndex = generateCellValuesContext.newRowIndex;
- isFirst = generateCellValuesContext.isFirst;
- iEnumerableIndex = generateCellValuesContext.iEnumerableIndex;
- currentHeader = generateCellValuesContext.currentHeader;
+ rowIndexDiff = generateCellValuesContext.RowIndexDiff;
+ headerDiff = generateCellValuesContext.HeaderDiff;
+ prevHeader = generateCellValuesContext.PrevHeader;
+ newRowIndex = generateCellValuesContext.NewRowIndex;
+ isFirst = generateCellValuesContext.IsFirst;
+ iEnumerableIndex = generateCellValuesContext.EnumerableIndex;
+ currentHeader = generateCellValuesContext.CurrentHeader;
enumrowend = newRowIndex - 1;
@@ -525,13 +525,13 @@ private async Task GenerateCellValuesAsync(
XmlElement rowElement,
CancellationToken cancellationToken = default)
{
- var rowIndexDiff = generateCellValuesContext.rowIndexDiff;
- var headerDiff = generateCellValuesContext.headerDiff;
- var prevHeader = generateCellValuesContext.prevHeader;
- var newRowIndex = generateCellValuesContext.newRowIndex;
- var isFirst = generateCellValuesContext.isFirst;
- var iEnumerableIndex = generateCellValuesContext.iEnumerableIndex;
- var currentHeader = generateCellValuesContext.currentHeader;
+ var rowIndexDiff = generateCellValuesContext.RowIndexDiff;
+ var headerDiff = generateCellValuesContext.HeaderDiff;
+ var prevHeader = generateCellValuesContext.PrevHeader;
+ var newRowIndex = generateCellValuesContext.NewRowIndex;
+ var isFirst = generateCellValuesContext.IsFirst;
+ var iEnumerableIndex = generateCellValuesContext.EnumerableIndex;
+ var currentHeader = generateCellValuesContext.CurrentHeader;
// https://github.com/mini-software/MiniExcel/issues/771 Saving by template introduces unintended value replication in each row #771
var notFirstRowElement = rowElement.Clone();
@@ -601,11 +601,11 @@ private async Task GenerateCellValuesAsync(
}
else
{
- var prop = rowInfo.PropsMap[newLines[0]];
- value = prop.PropertyInfoOrFieldInfo switch
+ var map = rowInfo.MembersMap[newLines[0]];
+ value = map.PropertyInfoOrFieldInfo switch
{
- PropertyInfoOrFieldInfo.PropertyInfo => prop.PropertyInfo.GetValue(item),
- PropertyInfoOrFieldInfo.FieldInfo => prop.FieldInfo.GetValue(item),
+ PropertyInfoOrFieldInfo.PropertyInfo => map.PropertyInfo.GetValue(item),
+ PropertyInfoOrFieldInfo.FieldInfo => map.FieldInfo.GetValue(item),
_ => string.Empty
};
}
@@ -638,26 +638,23 @@ private async Task GenerateCellValuesAsync(
else
{
var replacements = new Dictionary();
-#if NETCOREAPP3_0_OR_GREATER
string MatchDelegate(Match x) => replacements.GetValueOrDefault(x.Groups[1].Value, "");
-#else
- string MatchDelegate(Match x) => replacements.TryGetValue(x.Groups[1].Value, out var repl) ? repl : "";
-#endif
- foreach (var prop in rowInfo.PropsMap)
+
+ foreach (var map in rowInfo.MembersMap)
{
- var propInfo = prop.Value.PropertyInfo;
- var name = isDictOrTable ? prop.Key : propInfo.Name;
+ var propInfo = map.Value.PropertyInfo;
+ var name = isDictOrTable ? map.Key : propInfo.Name;
var key = $"{rowInfo.IEnumerablePropName}.{name}";
object? cellValue;
if (rowInfo.IsDictionary)
{
- if (!dict!.TryGetValue(prop.Key, out cellValue))
+ if (!dict!.TryGetValue(map.Key, out cellValue))
continue;
}
else if (rowInfo.IsDataTable)
{
- cellValue = dataRow![prop.Key];
+ cellValue = dataRow![map.Key];
}
else
{
@@ -668,7 +665,7 @@ private async Task GenerateCellValuesAsync(
continue;
var type = isDictOrTable
- ? prop.Value.UnderlyingTypePropType
+ ? map.Value.UnderlyingMemberType
: Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType;
string? cellValueStr;
@@ -813,13 +810,13 @@ await writer.WriteAsync(CleanXml(newRow.OuterXml, endPrefix)
return new GenerateCellValuesContext
{
- currentHeader = currentHeader,
- headerDiff = headerDiff,
- iEnumerableIndex = iEnumerableIndex,
- isFirst = isFirst,
- newRowIndex = newRowIndex,
- prevHeader = prevHeader,
- rowIndexDiff = rowIndexDiff,
+ CurrentHeader = currentHeader,
+ HeaderDiff = headerDiff,
+ EnumerableIndex = iEnumerableIndex,
+ IsFirst = isFirst,
+ NewRowIndex = newRowIndex,
+ PrevHeader = prevHeader,
+ RowIndexDiff = rowIndexDiff,
};
}
@@ -1168,17 +1165,17 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
foreach (var formatText in matches)
{
xRowInfo.FormatText = formatText;
- var propNames = formatText.Split('.');
- if (propNames[0].StartsWith("$")) //e.g:"$rowindex" it doesn't need to check cell value type
+ var mapNames = formatText.Split('.');
+ if (mapNames[0].StartsWith("$")) //e.g:"$rowindex" it doesn't need to check cell value type
continue;
// TODO: default if not contain property key, clean the template string
- if (!inputMaps.TryGetValue(propNames[0], out var cellValue))
+ if (!inputMaps.TryGetValue(mapNames[0], out var cellValue))
{
if (!_configuration.IgnoreTemplateParameterMissing)
- throw new KeyNotFoundException($"The parameter '{propNames[0]}' was not found.");
+ throw new KeyNotFoundException($"The parameter '{mapNames[0]}' was not found.");
- v.InnerText = v.InnerText.Replace($"{{{{{propNames[0]}}}}}", "");
+ v.InnerText = v.InnerText.Replace($"{{{{{mapNames[0]}}}}}", "");
break;
}
@@ -1203,17 +1200,17 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
xRowInfo.CellIEnumerableValuesCount++;
if (xRowInfo.IEnumerableGenericType is null && element is not null)
{
- xRowInfo.IEnumerablePropName = propNames[0];
+ xRowInfo.IEnumerablePropName = mapNames[0];
xRowInfo.IEnumerableGenericType = element.GetType();
if (element is IDictionary dic)
{
xRowInfo.IsDictionary = true;
- xRowInfo.PropsMap = dic.ToDictionary(
+ xRowInfo.MembersMap = dic.ToDictionary(
kv => kv.Key,
kv => kv.Value is not null
- ? new MemberInfo { UnderlyingTypePropType = Nullable.GetUnderlyingType(kv.Value.GetType()) ?? kv.Value.GetType() }
- : new MemberInfo { UnderlyingTypePropType = typeof(object) });
+ ? new MemberInfo { UnderlyingMemberType = Nullable.GetUnderlyingType(kv.Value.GetType()) ?? kv.Value.GetType() }
+ : new MemberInfo { UnderlyingMemberType = typeof(object) });
}
else
{
@@ -1224,7 +1221,7 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
{
PropertyInfo = p,
PropertyInfoOrFieldInfo = PropertyInfoOrFieldInfo.PropertyInfo,
- UnderlyingTypePropType = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType
+ UnderlyingMemberType = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType
});
var fields = xRowInfo.IEnumerableGenericType.GetFields();
@@ -1232,17 +1229,17 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
{
if (!values.ContainsKey(f.Name))
{
- var propInfo = new MemberInfo
+ var fieldInfo = new MemberInfo
{
FieldInfo = f,
PropertyInfoOrFieldInfo = PropertyInfoOrFieldInfo.FieldInfo,
- UnderlyingTypePropType = Nullable.GetUnderlyingType(f.FieldType) ?? f.FieldType
+ UnderlyingMemberType = Nullable.GetUnderlyingType(f.FieldType) ?? f.FieldType
};
- values.Add(f.Name, propInfo);
+ values.Add(f.Name, fieldInfo);
}
}
- xRowInfo.PropsMap = values;
+ xRowInfo.MembersMap = values;
}
}
@@ -1257,21 +1254,21 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
//only check first one match IEnumerable, so only render one collection at same row
// Empty collection parameter will get exception https://gitee.com/dotnetchina/MiniExcel/issues/I4WM67
- if (xRowInfo.PropsMap is null)
+ if (xRowInfo.MembersMap is null)
{
- v.InnerText = v.InnerText.Replace($"{{{{{propNames[0]}}}}}", propNames[1]);
+ v.InnerText = v.InnerText.Replace($"{{{{{mapNames[0]}}}}}", mapNames[1]);
break;
}
- if (!xRowInfo.PropsMap.TryGetValue(propNames[1], out var prop))
+ if (!xRowInfo.MembersMap.TryGetValue(mapNames[1], out var map))
{
- v.InnerText = v.InnerText.Replace($"{{{{{propNames[0]}.{propNames[1]}}}}}", "");
+ v.InnerText = v.InnerText.Replace($"{{{{{mapNames[0]}.{mapNames[1]}}}}}", "");
continue;
//why unreachable exception?
- throw new InvalidDataException($"{propNames[0]} doesn't have {propNames[1]} property");
+ throw new InvalidDataException($"{mapNames[0]} doesn't have {mapNames[1]} property");
}
// auto check type https://github.com/mini-software/MiniExcel/issues/177
- var type = prop.UnderlyingTypePropType; //avoid nullable
+ var type = map.UnderlyingMemberType; //avoid nullable
if (isMultiMatch)
{
@@ -1296,7 +1293,7 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
{
if (xRowInfo.CellIEnumerableValues is null)
{
- xRowInfo.IEnumerablePropName = propNames[0];
+ xRowInfo.IEnumerablePropName = mapNames[0];
xRowInfo.IEnumerableGenericType = typeof(DataRow);
xRowInfo.IsDataTable = true;
@@ -1314,16 +1311,16 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
}
//TODO:need to optimize
//maxRowIndexDiff = dt.Rows.Count <= 1 ? 0 : dt.Rows.Count-1;
- xRowInfo.PropsMap = dt.Columns.Cast().ToDictionary(col =>
+ xRowInfo.MembersMap = dt.Columns.Cast().ToDictionary(col =>
col.ColumnName,
- col => new MemberInfo { UnderlyingTypePropType = Nullable.GetUnderlyingType(col.DataType) }
+ col => new MemberInfo { UnderlyingMemberType = Nullable.GetUnderlyingType(col.DataType) }
);
}
- var column = dt.Columns[propNames[1]];
+ var column = dt.Columns[mapNames[1]];
var type = Nullable.GetUnderlyingType(column.DataType) ?? column.DataType; //avoid nullable
- if (!xRowInfo.PropsMap.ContainsKey(propNames[1]))
- throw new InvalidDataException($"{propNames[0]} doesn't have {propNames[1]} property");
+ if (!xRowInfo.MembersMap.ContainsKey(mapNames[1]))
+ throw new InvalidDataException($"{mapNames[0]} doesn't have {mapNames[1]} property");
if (isMultiMatch)
{
@@ -1372,7 +1369,7 @@ private void UpdateDimensionAndGetRowsInfo(IDictionary inputMap
// Re-acquire v after SetCellType may have changed DOM structure
v = c.SelectSingleNode("x:v", Ns) ?? c.SelectSingleNode("x:is/x:t", Ns);
- v.InnerText = v.InnerText.Replace($"{{{{{propNames[0]}}}}}", cellValueStr); //TODO: auto check type and set value
+ v.InnerText = v.InnerText.Replace($"{{{{{mapNames[0]}}}}}", cellValueStr); //TODO: auto check type and set value
}
}
//if (xRowInfo.CellIEnumerableValues is not null) //2. From left to right, only the first set is used as the basis for the list
diff --git a/src/MiniExcel.OpenXml/Templates/OpenXmlTemplateUtils.cs b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplateUtils.cs
index 473fb171..608269af 100644
--- a/src/MiniExcel.OpenXml/Templates/OpenXmlTemplateUtils.cs
+++ b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplateUtils.cs
@@ -1,6 +1,4 @@
-using System.Xml.Linq;
-
-namespace MiniExcelLib.OpenXml.Templates;
+namespace MiniExcelLib.OpenXml.Templates;
internal class XRowInfo
{
@@ -8,7 +6,7 @@ internal class XRowInfo
public string IEnumerablePropName { get; set; }
public XmlElement Row { get; set; }
public Type IEnumerableGenericType { get; set; }
- public IDictionary PropsMap { get; set; }
+ public IDictionary MembersMap { get; set; }
public bool IsDictionary { get; set; }
public bool IsDataTable { get; set; }
public int CellIEnumerableValuesCount { get; set; }
@@ -17,15 +15,13 @@ internal class XRowInfo
public XMergeCell? IEnumerableMercell { get; set; }
public List? RowMercells { get; set; }
public List? ConditionalFormats { get; set; }
-
-
}
internal class MemberInfo
{
public PropertyInfo PropertyInfo { get; set; }
public FieldInfo FieldInfo { get; set; }
- public Type UnderlyingTypePropType { get; set; }
+ public Type UnderlyingMemberType { get; set; }
public PropertyInfoOrFieldInfo PropertyInfoOrFieldInfo { get; set; } = PropertyInfoOrFieldInfo.None;
}
@@ -48,6 +44,7 @@ public XMergeCell(XMergeCell mergeCell)
Y2 = mergeCell.Y2;
MergeCell = mergeCell.MergeCell;
}
+
public XMergeCell(XmlElement mergeCell)
{
var refAttr = mergeCell.Attributes["ref"].Value;
@@ -64,6 +61,7 @@ public XMergeCell(XmlElement mergeCell)
Width = Math.Abs(X1 - X2) + 1;
Height = Math.Abs(Y1 - Y2) + 1;
}
+
public XMergeCell(string x1, int y1, string x2, int y2)
{
X1 = CellReferenceConverter.GetNumericalIndex(x1);
@@ -124,11 +122,11 @@ internal enum SpecialCellType { None, Group, Endgroup, Merge, Header }
internal class GenerateCellValuesContext
{
- public int rowIndexDiff { get; set; }
- public int headerDiff { get; set; }
- public string prevHeader { get; set; }
- public string currentHeader { get; set; }
- public int newRowIndex { get; set; }
- public bool isFirst { get; set; }
- public int iEnumerableIndex { get; set; }
+ public int RowIndexDiff { get; set; }
+ public int HeaderDiff { get; set; }
+ public string PrevHeader { get; set; }
+ public string CurrentHeader { get; set; }
+ public int NewRowIndex { get; set; }
+ public bool IsFirst { get; set; }
+ public int EnumerableIndex { get; set; }
}
diff --git a/src/MiniExcel.OpenXml/Zip/OpenXmlZip.cs b/src/MiniExcel.OpenXml/Zip/OpenXmlZip.cs
index 414fd835..0d3c845b 100644
--- a/src/MiniExcel.OpenXml/Zip/OpenXmlZip.cs
+++ b/src/MiniExcel.OpenXml/Zip/OpenXmlZip.cs
@@ -43,10 +43,7 @@ public OpenXmlZip(Stream fileStream, ZipArchiveMode mode = ZipArchiveMode.Read,
}
}
- public ZipArchiveEntry? GetEntry(string path)
- {
- return Entries.TryGetValue(path, out var entry) ? entry : null;
- }
+ public ZipArchiveEntry? GetEntry(string path) => Entries.GetValueOrDefault(path);
public XmlReader? GetXmlReader(string path)
{
@@ -82,4 +79,4 @@ protected virtual void Dispose(bool disposing)
_disposed = true;
}
}
-}
\ No newline at end of file
+}