diff --git a/MiniExcel.slnx b/MiniExcel.slnx index a446af9f..989be6cc 100644 --- a/MiniExcel.slnx +++ b/MiniExcel.slnx @@ -27,13 +27,14 @@ + + - \ No newline at end of file diff --git a/README-V2.md b/README-V2.md index 426639e7..4ff8c7eb 100644 --- a/README-V2.md +++ b/README-V2.md @@ -1589,18 +1589,20 @@ public enum UserTypeEnum ![image](https://user-images.githubusercontent.com/12729184/133116630-27cc7161-099a-48b8-9784-cd1e443af3d1.png) -#### 2. Convert Csv to Xlsx or vice-versa +#### 2. Convert Csv to Xlsx and vice-versa + +You can use the `MiniExcelConverter` utility class to convert a file from Csv to Xlsx and vice-versa: ```csharp -MiniExcel.Exporters.GetCsvExporter().ConvertXlsxToCsv(xlsxPath, csvPath); -MiniExcel.Exporters.GetCsvExporter().ConvertCsvToXlsx(csvPath, xlsxPath); +MiniExcelConverter.ConvertXlsxToCsv(xlsxPath, csvPath); +MiniExcelConverter.ConvertCsvToXlsx(csvPath, xlsxPath); // or using (var excelStream = new FileStream(path: filePath, FileMode.Open, FileAccess.Read)) using (var csvStream = new MemoryStream()) { - MiniExcel.ConvertXlsxToCsv(excelStream, csvStream); + MiniExcelConverter.ConvertXlsxToCsv(excelStream, csvStream); } ``` diff --git a/V2-Upgrade-Notes.md b/V2-Upgrade-Notes.md index 4274fd9c..6b0f9ed7 100644 --- a/V2-Upgrade-Notes.md +++ b/V2-Upgrade-Notes.md @@ -6,8 +6,8 @@ `MiniExcel.Importers`, `MiniExcel.Exporters` and `MiniExcel.Templaters` will give you access to, respectively, the `MiniExcelImporterProvider`, `MiniExcelExporterProvider` and `MiniExcelTemplaterProvider`. - This way Excel and Csv query methods are split between the `OpenXmlImporter` and the `CsvImporter`, accessible from the `MiniExcelImporterProvider`. - The same structure was adopted for export methods through `OpenXmlExporter` and `CsvExporter`, while template methods are instead currently only found in `OpenXmlTemplater`. -- ~~Csv methods are only available if the MiniExcel.Csv package is installed, which is pulled down automatically when the full MiniExcel package is downloaded.~~ -We're still pondering whether this is the best way to move forward with the library, currently only the full MiniExcel package is available. +- Csv methods are only available if the MiniExcel.Csv package is installed, which is pulled down automatically when the full MiniExcel package is downloaded. +- You can only access the conversion methods `ConvertCsvToXlsx` and `ConvertXlsxToCsv` from the `MiniExcelConverter` utility class, which is part of the full MiniExcel package. - If the full MiniExcel package is downloaded, the previous namespace will coexist along the new one, containing the original static methods' signatures, which have become a facade for the aferomentioned providers. - `IConfiguration` is now `IMiniExcelConfiguration`, but most methods now require the proper implementation (`OpenXmlConfiguration` or `CsvConfiguration`) to be provided rather than the interface - MiniExcel now fully supports asynchronous streaming the queries, diff --git a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/CreateExcelBenchmark.cs b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/CreateExcelBenchmark.cs index 8c519a4c..733eddb0 100644 --- a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/CreateExcelBenchmark.cs +++ b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/CreateExcelBenchmark.cs @@ -6,7 +6,9 @@ using DocumentFormat.OpenXml.Spreadsheet; using MiniExcelLib.Benchmarks.Utils; using MiniExcelLib.Core; -using MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.OpenXml.Api; +using MiniExcelLib.OpenXml.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping.Api; using NPOI.XSSF.UserModel; using OfficeOpenXml; diff --git a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/QueryExcelBenchmark.cs b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/QueryExcelBenchmark.cs index 24d04fdc..531d6a64 100644 --- a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/QueryExcelBenchmark.cs +++ b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/QueryExcelBenchmark.cs @@ -5,7 +5,9 @@ using DocumentFormat.OpenXml.Spreadsheet; using ExcelDataReader; using MiniExcelLib.Core; -using MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.OpenXml.Api; +using MiniExcelLib.OpenXml.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping.Api; using NPOI.XSSF.UserModel; using OfficeOpenXml; diff --git a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/TemplateExcelBenchmark.cs b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/TemplateExcelBenchmark.cs index 89173841..410f325d 100644 --- a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/TemplateExcelBenchmark.cs +++ b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/TemplateExcelBenchmark.cs @@ -2,7 +2,9 @@ using ClosedXML.Report; using MiniExcelLib.Benchmarks.Utils; using MiniExcelLib.Core; -using MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.OpenXml.Api; +using MiniExcelLib.OpenXml.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping.Api; namespace MiniExcelLib.Benchmarks.BenchmarkSections; diff --git a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/XlsxAsyncBenchmark.cs b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/XlsxAsyncBenchmark.cs index ed327bfa..54300493 100644 --- a/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/XlsxAsyncBenchmark.cs +++ b/benchmarks/MiniExcel.Benchmarks/BenchmarkSections/XlsxAsyncBenchmark.cs @@ -1,6 +1,7 @@ using BenchmarkDotNet.Attributes; using MiniExcelLib.Benchmarks.Utils; using MiniExcelLib.Core; +using MiniExcelLib.OpenXml.Api; namespace MiniExcelLib.Benchmarks.BenchmarkSections; diff --git a/benchmarks/MiniExcel.Benchmarks/MiniExcel.Benchmarks.csproj b/benchmarks/MiniExcel.Benchmarks/MiniExcel.Benchmarks.csproj index bf73c342..fb04cf56 100644 --- a/benchmarks/MiniExcel.Benchmarks/MiniExcel.Benchmarks.csproj +++ b/benchmarks/MiniExcel.Benchmarks/MiniExcel.Benchmarks.csproj @@ -35,7 +35,7 @@ - + diff --git a/src/MiniExcel.Core/Abstractions/IMappingCellStream.cs b/src/MiniExcel.Core/Abstractions/IMappingCellStream.cs new file mode 100644 index 00000000..abae5aa8 --- /dev/null +++ b/src/MiniExcel.Core/Abstractions/IMappingCellStream.cs @@ -0,0 +1,6 @@ +namespace MiniExcelLib.Core.Abstractions; + +public interface IMappingCellStream +{ + IMiniExcelWriteAdapter CreateAdapter(); +} diff --git a/src/MiniExcel.Core/Attributes/MiniExcelColumnAttribute.cs b/src/MiniExcel.Core/Attributes/MiniExcelColumnAttribute.cs index 2d6098a7..c02f83ed 100644 --- a/src/MiniExcel.Core/Attributes/MiniExcelColumnAttribute.cs +++ b/src/MiniExcel.Core/Attributes/MiniExcelColumnAttribute.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.Attributes; +namespace MiniExcelLib.Core.Attributes; [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class MiniExcelColumnAttribute : Attribute @@ -6,13 +6,13 @@ public class MiniExcelColumnAttribute : Attribute private int _index = -1; private string? _xName; - internal int FormatId { get; set; } = -1; - public string? Name { get; set; } - public string[]? Aliases { 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; } = 9.28515625; - public string? Format { get; set; } - public bool Ignore { get; set; } public ColumnType Type { get; set; } = ColumnType.Value; public int Index @@ -24,7 +24,7 @@ public int Index public string? IndexName { get => _xName; - set => Init(ColumnHelper.GetColumnIndex(value), value); + set => Init(CellReferenceConverter.GetNumericalIndex(value), value); } private void Init(int index, string? columnName = null) @@ -33,8 +33,10 @@ private void Init(int index, string? columnName = null) throw new ArgumentOutOfRangeException(nameof(index), index, $"Column index {index} must be greater or equal to zero."); _index = index; - _xName ??= columnName ?? ColumnHelper.GetAlphabetColumnName(index); + _xName ??= columnName ?? CellReferenceConverter.GetAlphabeticalIndex(index); } + + public void SetFormatId(int formatId) => FormatId = formatId; } public enum ColumnType { Value, Formula } @@ -42,10 +44,10 @@ public enum ColumnType { Value, Formula } public class DynamicExcelColumn : MiniExcelColumnAttribute { public string Key { get; set; } - public Func CustomFormatter { get; set; } + public Func? CustomFormatter { get; set; } public DynamicExcelColumn(string key) { Key = key; } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/Attributes/MiniExcelColumnIndexAttribute.cs b/src/MiniExcel.Core/Attributes/MiniExcelColumnIndexAttribute.cs index b0033b63..7c0137ae 100644 --- a/src/MiniExcel.Core/Attributes/MiniExcelColumnIndexAttribute.cs +++ b/src/MiniExcel.Core/Attributes/MiniExcelColumnIndexAttribute.cs @@ -5,7 +5,7 @@ public class MiniExcelColumnIndexAttribute : Attribute { public int ExcelColumnIndex { get; set; } internal string? ExcelXName { get; set; } - public MiniExcelColumnIndexAttribute(string columnName) => Init(ColumnHelper.GetColumnIndex(columnName), columnName); + public MiniExcelColumnIndexAttribute(string columnName) => Init(CellReferenceConverter.GetNumericalIndex(columnName), columnName); public MiniExcelColumnIndexAttribute(int columnIndex) => Init(columnIndex); private void Init(int columnIndex, string? columnName = null) @@ -13,7 +13,7 @@ private void Init(int columnIndex, string? columnName = null) if (columnIndex < 0) throw new ArgumentOutOfRangeException(nameof(columnIndex), columnIndex, $"Column index {columnIndex} must be greater or equal to zero."); - ExcelXName ??= columnName ?? ColumnHelper.GetAlphabetColumnName(columnIndex); + ExcelXName ??= columnName ?? CellReferenceConverter.GetAlphabeticalIndex(columnIndex); ExcelColumnIndex = columnIndex; } } \ No newline at end of file diff --git a/src/MiniExcel.Core/GlobalUsings.cs b/src/MiniExcel.Core/GlobalUsings.cs index 05f12759..88106cf2 100644 --- a/src/MiniExcel.Core/GlobalUsings.cs +++ b/src/MiniExcel.Core/GlobalUsings.cs @@ -3,15 +3,10 @@ global using System.Collections; global using System.Data; global using System.Globalization; -global using System.IO.Compression; global using System.Reflection; global using System.Runtime.CompilerServices; global using System.Text; -global using System.Text.RegularExpressions; -global using System.Xml; global using MiniExcelLib.Core.Abstractions; global using MiniExcelLib.Core.Helpers; -global using MiniExcelLib.Core.OpenXml; -global using MiniExcelLib.Core.OpenXml.Utils; global using MiniExcelLib.Core.Reflection; global using Zomp.SyncMethodGenerator; \ No newline at end of file diff --git a/src/MiniExcel.Core/Helpers/AsyncEnumerableExtensions.cs b/src/MiniExcel.Core/Helpers/AsyncEnumerableExtensions.cs new file mode 100644 index 00000000..f91bede2 --- /dev/null +++ b/src/MiniExcel.Core/Helpers/AsyncEnumerableExtensions.cs @@ -0,0 +1,18 @@ +namespace MiniExcelLib.Core.Helpers; + +public static class AsyncEnumerableExtensions +{ + public static async Task> CreateListAsync(this IAsyncEnumerable enumerable, CancellationToken cancellationToken = default) + { + List list = []; + await foreach (var item in enumerable.WithCancellation(cancellationToken).ConfigureAwait(false)) + { + list.Add(item); + } + + return list; + } + + // needed by the SyncGenerator + public static List CreateList(this IEnumerable enumerable) => [..enumerable]; +} diff --git a/src/MiniExcel.Core/Helpers/AttributeExtension.cs b/src/MiniExcel.Core/Helpers/AttributeExtension.cs deleted file mode 100644 index a8236785..00000000 --- a/src/MiniExcel.Core/Helpers/AttributeExtension.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace MiniExcelLib.Core.Helpers; - -internal static class AttributeExtension -{ - internal static TValue? GetAttributeValue( - this Type targetType, - Func selector) where TAttribute : Attribute - { - var attributeType = targetType - .GetCustomAttributes(typeof(TAttribute), true) - .FirstOrDefault() as TAttribute; - - return GetValueOrDefault(selector, attributeType); - } - - private static TValue? GetValueOrDefault( - Func selector, - TAttribute? attr) where TAttribute : Attribute - { - return attr is not null ? selector(attr) : default; - } - - internal static TAttribute? GetAttribute( - this MemberInfo prop, - bool isInherit = true) where TAttribute : Attribute - { - return GetAttributeValue(prop, (TAttribute attr) => attr, isInherit); - } - - internal static TValue? GetAttributeValue( - this MemberInfo prop, - Func selector, - bool isInherit = true ) where TAttribute : Attribute - { - var attr = Attribute.GetCustomAttribute(prop, typeof(TAttribute), isInherit) as TAttribute; - return GetValueOrDefault(selector, attr); - } -} \ No newline at end of file diff --git a/src/MiniExcel.Core/Helpers/AttributeExtensions.cs b/src/MiniExcel.Core/Helpers/AttributeExtensions.cs new file mode 100644 index 00000000..fe502ad2 --- /dev/null +++ b/src/MiniExcel.Core/Helpers/AttributeExtensions.cs @@ -0,0 +1,26 @@ +namespace MiniExcelLib.Core.Helpers; + +public static class AttributeExtensions +{ + private static TValue? GetValueOrDefault( + Func selector, + TAttribute? attr) where TAttribute : Attribute + { + return attr is not null ? selector(attr) : default; + } + + public static TAttribute? GetAttribute(this MemberInfo prop, bool isInherit = true) + where TAttribute : Attribute + { + return prop.GetAttributeValue((TAttribute attr) => attr, isInherit); + } + + public static TValue? GetAttributeValue( + this MemberInfo prop, + Func selector, + bool isInherit = true ) where TAttribute : Attribute + { + var attr = Attribute.GetCustomAttribute(prop, typeof(TAttribute), isInherit) as TAttribute; + return GetValueOrDefault(selector, attr); + } +} diff --git a/src/MiniExcel.Core/Helpers/CellReferenceConverter.cs b/src/MiniExcel.Core/Helpers/CellReferenceConverter.cs new file mode 100644 index 00000000..9a7129f2 --- /dev/null +++ b/src/MiniExcel.Core/Helpers/CellReferenceConverter.cs @@ -0,0 +1,117 @@ +using System.Collections.Concurrent; + +namespace MiniExcelLib.Core.Helpers; + +public static class CellReferenceConverter +{ + private const int GeneralColumnIndex = 255; + private const int MaxColumnIndex = 16383; + + private static readonly ConcurrentDictionary IntMappingToAlphabet = new(); + private static readonly ConcurrentDictionary AlphabetMappingToInt = new(); + + static CellReferenceConverter() + { + EnsureMappingsUpTo(GeneralColumnIndex); + } + + public static string GetAlphabeticalIndex(int columnIndex) + { + EnsureMappingsUpTo(columnIndex); + return IntMappingToAlphabet.TryGetValue(columnIndex, out var value) ? value : throw new KeyNotFoundException(); + } + + public static int GetNumericalIndex(string? columnName) + { + columnName ??= string.Empty; + if (AlphabetMappingToInt.TryGetValue(columnName, out var columnIndex)) + EnsureMappingsUpTo(columnIndex); + + return columnIndex; + } + + private static void EnsureMappingsUpTo(int columnIndex) + { + if (columnIndex < IntMappingToAlphabet.Count) + return; + + if (columnIndex > MaxColumnIndex) + throw new InvalidDataException($"Column index {columnIndex} exceeds Excel's maximum valid index."); + + for (int i = IntMappingToAlphabet.Count; i <= columnIndex; i++) + { + var name = GetColumnFromIndex(i); + + IntMappingToAlphabet.TryAdd(i, name); + AlphabetMappingToInt.TryAdd(name, i); + } + } + + private static string GetColumnFromIndex(int value) + { + var result = string.Empty; + + do + { + result = (char)('A' + value % 26) + result; + value = value / 26 - 1; + } + while (value >= 0); + + return result; + } + + /// eg. A2=(1,2),C5=(3,5) + public static string GetCellFromCoordinates(int column, int row) + { + return $"{GetAlphabeticalIndex(column - 1)}{row}"; + } + + /**The code below was copied and modified from ExcelDataReader - @MIT License**/ + /// + /// Converts Excel cells into numerical coordinates. ex:A2=(1,2),C5=(3,5) + /// + /// The value. + /// The column, 1-based. + /// The row, 1-based. + public static bool TryParseCellReference(string? value, out int column, out int row) + { + const int offset = 'A' - 1; + + row = 0; + column = 0; + var position = 0; + + if (string.IsNullOrWhiteSpace(value)) + return false; + + while (position < value!.Length) + { + var c = char.ToUpperInvariant(value[position]); + if (c is >= 'A' and <= 'Z') + { + position++; + column = column * 26 + c - offset; + continue; + } + + if (char.IsLetter(c)) + { + row = 0; + column = 0; + position = 0; + break; + } + + if (char.IsDigit(c)) + break; + + return false; + } + + if (position == 0) + return false; + + return int.TryParse(value[position..], NumberStyles.None, CultureInfo.InvariantCulture, out row) && row > 0; + } +} diff --git a/src/MiniExcel.Core/Helpers/CollectionAccessor.cs b/src/MiniExcel.Core/Helpers/CollectionAccessor.cs index 20b198dd..667a9e6e 100644 --- a/src/MiniExcel.Core/Helpers/CollectionAccessor.cs +++ b/src/MiniExcel.Core/Helpers/CollectionAccessor.cs @@ -1,12 +1,12 @@ -using System.Linq.Expressions; - -namespace MiniExcelLib.Core.Helpers; +using System.Linq.Expressions; + +namespace MiniExcelLib.Core.Helpers; /// /// Optimized collection access utilities to reduce code duplication across mapping components. /// Provides consistent handling of IList vs IEnumerable patterns. /// -internal static class CollectionAccessor +public static class CollectionAccessor { /// /// Gets an item at the specified offset from a collection, with optimized handling for IList. @@ -58,27 +58,27 @@ public static object FinalizeCollection(IList list, Type targetType, Type itemTy /// /// The type to create instances of /// A factory function that creates new instances - public static Func CreateItemFactory(Type itemType) - { - // Value types can always be created via Activator.CreateInstance - if (itemType.IsValueType) - { - return () => Activator.CreateInstance(itemType); - } - - // For reference types, prefer a compiled parameterless constructor if available - var ctor = itemType.GetConstructor(Type.EmptyTypes); - if (ctor is null) - { - // No default constructor - unable to materialize items automatically - return () => null; - } - - var newExpression = Expression.New(ctor); - var lambda = Expression.Lambda>(Expression.Convert(newExpression, typeof(object))); - var factory = lambda.Compile(); - return factory; - } + public static Func CreateItemFactory(Type itemType) + { + // Value types can always be created via Activator.CreateInstance + if (itemType.IsValueType) + { + return () => Activator.CreateInstance(itemType); + } + + // For reference types, prefer a compiled parameterless constructor if available + var ctor = itemType.GetConstructor(Type.EmptyTypes); + if (ctor is null) + { + // No default constructor - unable to materialize items automatically + return () => null; + } + + var newExpression = Expression.New(ctor); + var lambda = Expression.Lambda>(Expression.Convert(newExpression, typeof(object))); + var factory = lambda.Compile(); + return factory; + } /// /// Determines the item type from a collection type. @@ -98,4 +98,4 @@ public static object FinalizeCollection(IList list, Type targetType, Type itemTy var genericArgs = collectionType.GetGenericArguments(); return genericArgs.Length > 0 ? genericArgs[0] : null; } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/Helpers/ColumnHelper.cs b/src/MiniExcel.Core/Helpers/ColumnHelper.cs deleted file mode 100644 index b5d9ccba..00000000 --- a/src/MiniExcel.Core/Helpers/ColumnHelper.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Collections.Concurrent; - -namespace MiniExcelLib.Core.Helpers; - -// For Row/Column Index -public static class ColumnHelper -{ - private const int GeneralColumnIndex = 255; - private const int MaxColumnIndex = 16383; - - private static readonly ConcurrentDictionary IntMappingAlphabet = new(); - private static readonly ConcurrentDictionary AlphabetMappingInt = new(); - - private static int _intMappingAlphabetCount; - - static ColumnHelper() - { - _intMappingAlphabetCount = IntMappingAlphabet.Count; - CheckAndSetMaxColumnIndex(GeneralColumnIndex); - } - - public static string GetAlphabetColumnName(int columnIndex) - { - CheckAndSetMaxColumnIndex(columnIndex); - return IntMappingAlphabet.TryGetValue(columnIndex, out var value) ? value : throw new KeyNotFoundException(); - } - - public static int GetColumnIndex(string? columnName) - { - columnName ??= ""; - if (AlphabetMappingInt.TryGetValue(columnName, out var columnIndex)) - CheckAndSetMaxColumnIndex(columnIndex); - - return columnIndex; - } - - private static void CheckAndSetMaxColumnIndex(int columnIndex) - { - if (columnIndex < _intMappingAlphabetCount) - return; - - if (columnIndex > MaxColumnIndex) - throw new InvalidDataException($"ColumnIndex {columnIndex} over excel vaild max index."); - - for (int i = IntMappingAlphabet.Count; i <= columnIndex; i++) - { - IntMappingAlphabet.AddOrUpdate(i, IntToLetters(i), (_, _) => IntToLetters(i)); - AlphabetMappingInt.AddOrUpdate(IntToLetters(i), i, (_, _) => i); - } - _intMappingAlphabetCount = IntMappingAlphabet.Count; - } - - private static string IntToLetters(int value) - { - value++; - var result = string.Empty; - while (--value >= 0) - { - result = (char)('A' + value % 26) + result; - value /= 26; - } - return result; - } -} \ No newline at end of file diff --git a/src/MiniExcel.Core/Helpers/SafeStreamWriter.cs b/src/MiniExcel.Core/Helpers/EnhancedStreamWriter.cs similarity index 91% rename from src/MiniExcel.Core/Helpers/SafeStreamWriter.cs rename to src/MiniExcel.Core/Helpers/EnhancedStreamWriter.cs index e147263c..d7748b87 100644 --- a/src/MiniExcel.Core/Helpers/SafeStreamWriter.cs +++ b/src/MiniExcel.Core/Helpers/EnhancedStreamWriter.cs @@ -1,6 +1,6 @@ namespace MiniExcelLib.Core.Helpers; -internal partial class SafeStreamWriter(Stream stream, Encoding encoding, int bufferSize) : IDisposable +public partial class EnhancedStreamWriter(Stream stream, Encoding encoding, int bufferSize) : IDisposable { private readonly StreamWriter _streamWriter = new(stream, encoding, bufferSize); private bool _disposed; @@ -62,4 +62,4 @@ public void Dispose() Dispose(disposing: true); GC.SuppressFinalize(this); } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/Helpers/ImageHelper.cs b/src/MiniExcel.Core/Helpers/ImageHelper.cs index 97013e66..1d89ac61 100644 --- a/src/MiniExcel.Core/Helpers/ImageHelper.cs +++ b/src/MiniExcel.Core/Helpers/ImageHelper.cs @@ -1,6 +1,6 @@ namespace MiniExcelLib.Core.Helpers; -internal static class ImageHelper +public static class ImageHelper { private static readonly byte[] Bmp = [(byte)'B', (byte)'M']; private static readonly byte[] Gif = [(byte)'G', (byte)'I', (byte)'F']; @@ -39,4 +39,4 @@ public static ImageFormat GetImageFormat(byte[] bytes) return ImageFormat.Unknown; } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/Helpers/TaskHelper.cs b/src/MiniExcel.Core/Helpers/TaskHelper.cs deleted file mode 100644 index 909e5691..00000000 --- a/src/MiniExcel.Core/Helpers/TaskHelper.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace MiniExcelLib.Core.Helpers; - -internal static class TaskHelper -{ - internal static async Task> CreateListAsync(this IAsyncEnumerable enumerable, CancellationToken cancellationToken = default) - { - List list = []; - await foreach (var item in enumerable.WithCancellation(cancellationToken).ConfigureAwait(false)) - { - list.Add(item); - } - - return list; - } - - internal static List CreateList(this IEnumerable enumerable) => [..enumerable]; -} \ No newline at end of file diff --git a/src/MiniExcel.Core/Helpers/TypeHelper.cs b/src/MiniExcel.Core/Helpers/TypeHelper.cs index 1ba86cbf..2e507a93 100644 --- a/src/MiniExcel.Core/Helpers/TypeHelper.cs +++ b/src/MiniExcel.Core/Helpers/TypeHelper.cs @@ -1,8 +1,8 @@ namespace MiniExcelLib.Core.Helpers; -internal static class TypeHelper +public static class TypeHelper { - public static IEnumerable> ConvertToEnumerableDictionary(IDataReader reader) + public static IEnumerable> ToEnumerableDictionaries(this IDataReader reader) { while (reader.Read()) { @@ -15,7 +15,7 @@ public static IEnumerable> ConvertToEnumerableDictio /// /// From : https://stackoverflow.com/questions/906499/getting-type-t-from-ienumerablet /// - public static IEnumerable GetGenericIEnumerables(object o) + internal static IEnumerable GetGenericIEnumerables(object o) { return o.GetType() .GetInterfaces() @@ -32,7 +32,7 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals return Type.GetTypeCode(type) is >= TypeCode.Int16 and <= TypeCode.Decimal; } - public static bool IsAsyncEnumerable(this Type type, out Type? genericArgument) + internal static bool IsAsyncEnumerable(this Type type, out Type? genericArgument) { var asyncEnumrableInterfaceType = type .GetInterfaces() @@ -41,4 +41,4 @@ public static bool IsAsyncEnumerable(this Type type, out Type? genericArgument) genericArgument = asyncEnumrableInterfaceType?.GetGenericArguments().FirstOrDefault(); return genericArgument is not null; } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/MiniExcel.Core.csproj b/src/MiniExcel.Core/MiniExcel.Core.csproj index 7db6767f..2e3318ff 100644 --- a/src/MiniExcel.Core/MiniExcel.Core.csproj +++ b/src/MiniExcel.Core/MiniExcel.Core.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/MiniExcel.Core/MiniExcelProviders.cs b/src/MiniExcel.Core/MiniExcelProviders.cs index ead314a9..5d0f775a 100644 --- a/src/MiniExcel.Core/MiniExcelProviders.cs +++ b/src/MiniExcel.Core/MiniExcelProviders.cs @@ -1,27 +1,16 @@ -using MiniExcelLib.Core.FluentMapping; -using MappingExporter = MiniExcelLib.Core.FluentMapping.MappingExporter; -using MappingImporter = MiniExcelLib.Core.FluentMapping.MappingImporter; -using MappingTemplater = MiniExcelLib.Core.FluentMapping.MappingTemplater; - namespace MiniExcelLib.Core; public sealed class MiniExcelImporterProvider { internal MiniExcelImporterProvider() { } - - public OpenXmlImporter GetOpenXmlImporter() => new(); } public sealed class MiniExcelExporterProvider { internal MiniExcelExporterProvider() { } - - public OpenXmlExporter GetOpenXmlExporter() => new(); } public sealed class MiniExcelTemplaterProvider { internal MiniExcelTemplaterProvider() { } - - public OpenXmlTemplater GetOpenXmlTemplater() => new(); } diff --git a/src/MiniExcel.Core/OpenXml/Utils/GeneralHelper.cs b/src/MiniExcel.Core/OpenXml/Utils/GeneralHelper.cs deleted file mode 100644 index 1f19995a..00000000 --- a/src/MiniExcel.Core/OpenXml/Utils/GeneralHelper.cs +++ /dev/null @@ -1,57 +0,0 @@ -namespace MiniExcelLib.Core.OpenXml.Utils; - -internal static class GeneralHelper -{ - public static int GetCellColumnIndex(string cell) - { - const string keys = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - const int mode = 26; - - var x = 0; - var cellLetter = GetCellColumnLetter(cell); - //AA=27,ZZ=702 - foreach (var t in cellLetter) - x = x * mode + keys.IndexOf(t); - - return x; - } - - public static int GetCellRowNumber(string cell) - { - if (string.IsNullOrEmpty(cell)) - throw new Exception("cell is null or empty"); - - var cellNumber = string.Empty; - foreach (var t in cell) - { - if (char.IsDigit(t)) - cellNumber += t; - } - return int.Parse(cellNumber); - } - - public static string GetCellColumnLetter(string cell) - { - string GetCellLetter = string.Empty; - foreach (var t in cell) - { - if (char.IsLetter(t)) - GetCellLetter += t; - } - return GetCellLetter; - } - - public static string ConvertColumnName(int x) - { - int dividend = x; - string columnName = string.Empty; - - while (dividend > 0) - { - var modulo = (dividend - 1) % 26; - columnName = Convert.ToChar(65 + modulo) + columnName; - dividend = (dividend - modulo) / 26; - } - return columnName; - } -} \ No newline at end of file diff --git a/src/MiniExcel.Core/OpenXml/Utils/ReferenceHelper.cs b/src/MiniExcel.Core/OpenXml/Utils/ReferenceHelper.cs deleted file mode 100644 index 157362ba..00000000 --- a/src/MiniExcel.Core/OpenXml/Utils/ReferenceHelper.cs +++ /dev/null @@ -1,124 +0,0 @@ -namespace MiniExcelLib.Core.OpenXml.Utils; - -internal static class ReferenceHelper -{ - public static string GetCellNumber(string cell) - { - return cell - .Where(char.IsDigit) - .Aggregate(string.Empty, (current, c) => current + c); - } - - public static string GetCellLetter(string cell) - { - return cell - .Where(char.IsLetter) - .Aggregate(string.Empty, (current, c) => current + c); - } - - /// X=CellLetter,Y=CellNumber,ex:A1=(1,1),B2=(2,2) - public static (int, int) ConvertCellToCoordinates(string? cell) - { - const string keys = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - const int mode = 26; - - //AA=27,ZZ=702 - var cellLetter = GetCellLetter(cell); - var x = cellLetter.Aggregate(0, (idx, chr) => idx * mode + keys.IndexOf(chr)); - - var cellNumber = GetCellNumber(cell); - return (x, int.Parse(cellNumber)); - } - - /// X=CellLetter,Y=CellNumber,ex:A1=(1,1),B2=(2,2) - public static string ConvertCoordinatesToCell(int x, int y) - { - int dividend = x; - string columnName = string.Empty; - - while (dividend > 0) - { - var modulo = (dividend - 1) % 26; - columnName = Convert.ToChar(65 + modulo) + columnName; - dividend = (dividend - modulo) / 26; - } - return $"{columnName}{y}"; - } - - /// - /// Try to parse cell reference (e.g., "A1") into column and row numbers. - /// - /// The cell reference (e.g., "A1", "B2", "AA10") - /// The column number (1-based) - /// The row number (1-based) - /// True if successfully parsed, false otherwise - public static bool TryParseCellReference(string cellRef, out int column, out int row) - { - column = 0; - row = 0; - - if (string.IsNullOrEmpty(cellRef)) - return false; - - try - { - var coords = ConvertCellToCoordinates(cellRef); - column = coords.Item1; - row = coords.Item2; - return column > 0 && row > 0; - } - catch - { - return false; - } - } - - /**The code below was copied and modified from ExcelDataReader - @MIT License**/ - /// - /// Logic for the Excel dimensions. Ex: A15 - /// - /// The value. - /// The column, 1-based. - /// The row, 1-based. - public static bool ParseReference(string value, out int column, out int row) - { - const int offset = 'A' - 1; - - row = 0; - column = 0; - var position = 0; - - if (string.IsNullOrWhiteSpace(value)) - return false; - - while (position < value.Length) - { - var c = char.ToUpperInvariant(value[position]); - if (c is >= 'A' and <= 'Z') - { - position++; - column *= 26; - column += c - offset; - continue; - } - - if (char.IsLetter(c)) - { - row = 0; - column = 0; - position = 0; - break; - } - - if (char.IsDigit(c)) - break; - - return false; - } - - if (position == 0) - return false; - - return int.TryParse(value[position..], NumberStyles.None, CultureInfo.InvariantCulture, out row) && row > 0; - } -} \ No newline at end of file diff --git a/src/MiniExcel.Core/Reflection/CustomPropertyHelper.cs b/src/MiniExcel.Core/Reflection/CustomPropertyHelper.cs index fd7cf0ba..416c0065 100644 --- a/src/MiniExcel.Core/Reflection/CustomPropertyHelper.cs +++ b/src/MiniExcel.Core/Reflection/CustomPropertyHelper.cs @@ -10,7 +10,7 @@ public static class CustomPropertyHelper var cell = new Dictionary(); for (int i = startCellIndex; i <= maxColumnIndex; i++) { - var key = ColumnHelper.GetAlphabetColumnName(i); + var key = CellReferenceConverter.GetAlphabeticalIndex(i); #if NETCOREAPP2_0_OR_GREATER cell.TryAdd(key, null); #else @@ -108,7 +108,7 @@ private static List GetSaveAsProperties(this Type type, Min throw new InvalidOperationException("Duplicate column name"); var maxkey = keys.Last(); - var maxIndex = ColumnHelper.GetColumnIndex(maxkey); + var maxIndex = CellReferenceConverter.GetNumericalIndex(maxkey); foreach (var p in props) { if (p?.ExcelColumnIndex is null) @@ -122,7 +122,7 @@ private static List GetSaveAsProperties(this Type type, Min return props; } - internal static string? DescriptionAttr(Type type, object? source) + public static string? GetDescriptionAttribute(Type type, object? source) { var name = source?.ToString(); return type.GetField(name) //For some database dirty data, there may be no way to change to the correct enumeration, will return NULL @@ -130,9 +130,9 @@ private static List GetSaveAsProperties(this Type type, Min ?? name; } - private static IEnumerable ConvertToExcelCustomPropertyInfo(PropertyInfo[] props, MiniExcelBaseConfiguration configuration) + private static IEnumerable GetExcelPropertyInfo(Type type, BindingFlags bindingFlags, MiniExcelBaseConfiguration configuration) { - // solve : https://github.com/mini-software/MiniExcel/issues/138 + var props = type.GetProperties(bindingFlags); var columnInfos = props.Select(p => { var gt = Nullable.GetUnderlyingType(p.PropertyType); @@ -172,12 +172,6 @@ private static List GetSaveAsProperties(this Type type, Min return columnInfos.Where(x => x is not null); } - private static IEnumerable GetExcelPropertyInfo(Type type, BindingFlags bindingFlags, MiniExcelBaseConfiguration configuration) - { - //TODO:assign column index - return ConvertToExcelCustomPropertyInfo(type.GetProperties(bindingFlags), configuration); - } - private static List GetDictionaryColumnInfo(IDictionary? dicString, IDictionary? dic, MiniExcelBaseConfiguration configuration) { var props = new List(); @@ -257,14 +251,15 @@ internal static bool TryGetTypeColumnInfo(Type? type, MiniExcelBaseConfiguration return false; } - props = GetSaveAsProperties(type, configuration); + props = type.GetSaveAsProperties(configuration); return true; } + internal static List GetColumnInfoFromValue(object value, MiniExcelBaseConfiguration configuration) => value switch { IDictionary genericDictionary => GetDictionaryColumnInfo(genericDictionary, null, configuration), IDictionary dictionary => GetDictionaryColumnInfo(null, dictionary, configuration), - _ => GetSaveAsProperties(value.GetType(), configuration) + _ => value.GetType().GetSaveAsProperties(configuration) }; private static bool ValueIsNeededToDetermineProperties(Type type) => @@ -330,17 +325,15 @@ internal static Dictionary GetHeaders(IDictionary .GroupBy(x => x.Name) .SelectMany(GroupToNameWithIndex) .ToDictionary(kv => trimNames ? kv.Name.Trim() : kv.Name, kv => kv.Index); - } - - private static IEnumerable DictToNameWithIndex(IDictionary dict) - { - return dict.Values.Select((obj, idx) => new NameIndexPair(idx, obj?.ToString() ?? "")); - } - private static IEnumerable GroupToNameWithIndex(IGrouping group) - { - return group.Select((grp, idx) => - new NameIndexPair(grp.Index, idx == 0 ? grp.Name : $"{grp.Name}_____{idx + 1}")); + static IEnumerable DictToNameWithIndex(IDictionary dict) + => dict.Values.Select((obj, idx) => + new NameIndexPair(idx, obj?.ToString() ?? "")); + + static IEnumerable GroupToNameWithIndex(IGrouping group) + => group.Select((grp, idx) => + new NameIndexPair(grp.Index, idx == 0 ? grp.Name : $"{grp.Name}_____{idx + 1}") + ); } private class NameIndexPair(int index, string name) diff --git a/src/MiniExcel.Core/Reflection/MiniExcelMapper.cs b/src/MiniExcel.Core/Reflection/MiniExcelMapper.cs index ad2223af..f7a028cf 100644 --- a/src/MiniExcel.Core/Reflection/MiniExcelMapper.cs +++ b/src/MiniExcel.Core/Reflection/MiniExcelMapper.cs @@ -7,7 +7,7 @@ namespace MiniExcelLib.Core.Reflection; public static partial class MiniExcelMapper { [CreateSyncVersion] - public static async IAsyncEnumerable MapQueryAsync(IAsyncEnumerable> values, string startCell, bool mapHeaderAsData, bool trimColumnNames, MiniExcelBaseConfiguration configuration, [EnumeratorCancellation] CancellationToken cancellationToken = default) where T : class, new() + public static async IAsyncEnumerable MapQueryAsync(IAsyncEnumerable> values, int rowOffset, bool mapHeaderAsData, bool trimColumnNames, MiniExcelBaseConfiguration configuration, Func? stringDecoderFunc = null, [EnumeratorCancellation] CancellationToken cancellationToken = default) where T : class, new() { cancellationToken.ThrowIfCancellationRequested(); @@ -50,7 +50,7 @@ public static partial class MiniExcelMapper if (aliasItemValue is not null) { - var newAliasValue = MapValue(v, pInfo, aliasItemValue, rowIndex, startCell, configuration); + var newAliasValue = MapValue(v, pInfo, aliasItemValue, rowIndex + rowOffset, configuration, stringDecoderFunc); } } } @@ -70,7 +70,7 @@ public static partial class MiniExcelMapper if (itemValue is not null) { - var newValue = MapValue(v, pInfo, itemValue, rowIndex, startCell, configuration); + var newValue = MapValue(v, pInfo, itemValue, rowIndex + rowOffset, configuration, stringDecoderFunc); } } @@ -79,7 +79,7 @@ public static partial class MiniExcelMapper } } - internal static object? MapValue(T v, MiniExcelColumnInfo pInfo, object itemValue, int rowIndex, string startCell, MiniExcelBaseConfiguration config) where T : class, new() + public static object? MapValue(T v, MiniExcelColumnInfo pInfo, object itemValue, int rowIndex, MiniExcelBaseConfiguration config, Func? stringDecoderFunc = null) where T : class, new() { try { @@ -241,7 +241,8 @@ public static partial class MiniExcelMapper else if (pInfo.Property.Info.PropertyType == typeof(string)) { - newValue = XmlHelper.DecodeString(itemValue?.ToString()); + var strValue = itemValue?.ToString(); + newValue = stringDecoderFunc?.Invoke(strValue) ?? strValue; } else if (pInfo.ExcludeNullableType.IsEnum) @@ -271,9 +272,8 @@ public static partial class MiniExcelMapper catch (Exception ex) when (ex is InvalidCastException or FormatException) { var columnName = pInfo.ExcelColumnName ?? pInfo.Property.Name; - var startRowIndex = ReferenceHelper.ConvertCellToCoordinates(startCell).Item2; - var errorRow = startRowIndex + rowIndex + 1; - + var errorRow = rowIndex + 1; + var msg = $"ColumnName: {columnName}, CellRow: {errorRow}, Value: {itemValue}. The value cannot be cast to type {pInfo.Property.Info.PropertyType.Name}."; throw new MiniExcelInvalidCastException(columnName, errorRow, itemValue, pInfo.Property.Info.PropertyType, msg); } diff --git a/src/MiniExcel.Core/WriteAdapters/MiniExcelWriteAdapterFactory.cs b/src/MiniExcel.Core/WriteAdapters/MiniExcelWriteAdapterFactory.cs index 9f6fa87c..4c89aa73 100644 --- a/src/MiniExcel.Core/WriteAdapters/MiniExcelWriteAdapterFactory.cs +++ b/src/MiniExcel.Core/WriteAdapters/MiniExcelWriteAdapterFactory.cs @@ -1,6 +1,4 @@ -using MiniExcelLib.Core.FluentMapping; - -namespace MiniExcelLib.Core.WriteAdapters; +namespace MiniExcelLib.Core.WriteAdapters; public static class MiniExcelWriteAdapterFactory { diff --git a/src/MiniExcel.Csv/Api/CsvExporter.cs b/src/MiniExcel.Csv/Api/CsvExporter.cs index 7ece7412..e9ac9039 100644 --- a/src/MiniExcel.Csv/Api/CsvExporter.cs +++ b/src/MiniExcel.Csv/Api/CsvExporter.cs @@ -52,48 +52,4 @@ public async Task ExportAsync(Stream stream, object value, bool printHead } #endregion - - #region Convert - - [CreateSyncVersion] - public async Task ConvertCsvToXlsxAsync(Stream csv, Stream xlsx, bool csvHasHeader = false, CancellationToken cancellationToken = default) - { - var value = new CsvImporter().QueryAsync(csv, useHeaderRow: csvHasHeader, cancellationToken: cancellationToken); - - await MiniExcel.Exporters - .GetOpenXmlExporter() - .ExportAsync(xlsx, value, printHeader: csvHasHeader, cancellationToken: cancellationToken) - .ConfigureAwait(false); - } - - [CreateSyncVersion] - public async Task ConvertCsvToXlsxAsync(string csvPath, string xlsx, bool csvHasHeader = false, CancellationToken cancellationToken = default) - { - using var csvStream = FileHelper.OpenSharedRead(csvPath); - using var xlsxStream = new FileStream(xlsx, FileMode.CreateNew); - - await ConvertCsvToXlsxAsync(csvStream, xlsxStream, csvHasHeader, cancellationToken).ConfigureAwait(false); - } - - [CreateSyncVersion] - public async Task ConvertXlsxToCsvAsync(string xlsx, string csvPath, bool xlsxHasHeader = true, CancellationToken cancellationToken = default) - { - using var xlsxStream = FileHelper.OpenSharedRead(xlsx); - using var csvStream = new FileStream(csvPath, FileMode.CreateNew); - - await ConvertXlsxToCsvAsync(xlsxStream, csvStream, xlsxHasHeader, cancellationToken).ConfigureAwait(false); - } - - [CreateSyncVersion] - public async Task ConvertXlsxToCsvAsync(Stream xlsx, Stream csv, bool xlsxHasHeader = true, CancellationToken cancellationToken = default) - { - var value = MiniExcel.Importers - .GetOpenXmlImporter() - .QueryAsync(xlsx, useHeaderRow: xlsxHasHeader, cancellationToken: cancellationToken) - .ConfigureAwait(false); - - await ExportAsync(csv, value, printHeader: xlsxHasHeader, cancellationToken: cancellationToken).ConfigureAwait(false); - } - - #endregion } \ No newline at end of file diff --git a/src/MiniExcel.Csv/CsvReader.cs b/src/MiniExcel.Csv/CsvReader.cs index 788857e7..7c6f2455 100644 --- a/src/MiniExcel.Csv/CsvReader.cs +++ b/src/MiniExcel.Csv/CsvReader.cs @@ -103,12 +103,12 @@ internal CsvReader(Stream stream, IMiniExcelConfiguration? configuration) if (_config.ReadEmptyStringAsNull) { for (int i = 0; i <= read.Length - 1; i++) - cell[ColumnHelper.GetAlphabetColumnName(i)] = read[i] is "" ? null : read[i]; + cell[CellReferenceConverter.GetAlphabeticalIndex(i)] = read[i] is var value and not "" ? value : null; } else { for (int i = 0; i <= read.Length - 1; i++) - cell[ColumnHelper.GetAlphabetColumnName(i)] = read[i]; + cell[CellReferenceConverter.GetAlphabeticalIndex(i)] = read[i]; } yield return cell; @@ -118,34 +118,35 @@ internal CsvReader(Stream stream, IMiniExcelConfiguration? configuration) [CreateSyncVersion] public IAsyncEnumerable QueryAsync(string? sheetName, string startCell, bool mapHeaderAsData, CancellationToken cancellationToken = default) where T : class, new() { + const int rowOffset = 0; // ranged queries are not supported for csv var records = QueryAsync(false, sheetName, startCell, cancellationToken); - return MiniExcelMapper.MapQueryAsync(records, startCell, mapHeaderAsData, false, _config, cancellationToken); + return MiniExcelMapper.MapQueryAsync(records, 0, mapHeaderAsData, false, _config, null, cancellationToken); } [CreateSyncVersion] public IAsyncEnumerable> QueryRangeAsync(bool useHeaderRow, string? sheetName, string startCell, string endCell, CancellationToken cancellationToken = default) { - throw new NotImplementedException("CSV does not implement QueryRange"); + throw new NotSupportedException("Ranged queries are not supported for csv file"); } [CreateSyncVersion] public IAsyncEnumerable QueryRangeAsync(string? sheetName, string startCell, string endCell, bool treatHeaderAsData, CancellationToken cancellationToken = default) where T : class, new() { var dynamicRecords = QueryRangeAsync(false, sheetName, startCell, endCell, cancellationToken); - return MiniExcelMapper.MapQueryAsync(dynamicRecords, startCell, treatHeaderAsData, false, _config, cancellationToken); + return MiniExcelMapper.MapQueryAsync(dynamicRecords, 0, treatHeaderAsData, false, _config, null, cancellationToken); } [CreateSyncVersion] public IAsyncEnumerable> QueryRangeAsync(bool useHeaderRow, string? sheetName, int startRowIndex, int startColumnIndex, int? endRowIndex, int? endColumnIndex, CancellationToken cancellationToken = default) { - throw new NotImplementedException("CSV does not implement QueryRange"); + throw new NotSupportedException("Ranged queries are not supported for csv file"); } [CreateSyncVersion] public IAsyncEnumerable QueryRangeAsync(string? sheetName, int startRowIndex, int startColumnIndex, int? endRowIndex, int? endColumnIndex, bool treatHeaderAsData, CancellationToken cancellationToken = default) where T : class, new() { var dynamicRecords = QueryRangeAsync(false, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, cancellationToken); - return MiniExcelMapper.MapQueryAsync(dynamicRecords, ConvertXyToCell(startRowIndex, startColumnIndex), treatHeaderAsData, false, _config, cancellationToken); + return MiniExcelMapper.MapQueryAsync(dynamicRecords, 0, treatHeaderAsData, false, _config, null, cancellationToken); } private static string ConvertXyToCell(int x, int y) @@ -177,4 +178,4 @@ public void Dispose() { ((Stream?)_stream)?.Dispose(); } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Csv/CsvHelper.cs b/src/MiniExcel.Csv/CsvSanitizer.cs similarity index 83% rename from src/MiniExcel.Csv/CsvHelper.cs rename to src/MiniExcel.Csv/CsvSanitizer.cs index 8ccc9a3a..60e2b1d8 100644 --- a/src/MiniExcel.Csv/CsvHelper.cs +++ b/src/MiniExcel.Csv/CsvSanitizer.cs @@ -1,9 +1,9 @@ namespace MiniExcelLib.Csv; -internal static class CsvHelper +public static class CsvSanitizer { /// If content contains special characters then use "{value}" format - public static string ConvertToCsvValue(string? value, CsvConfiguration configuration) + public static string SanitizeCsvField(string? value, CsvConfiguration configuration) { if (value is null) return string.Empty; diff --git a/src/MiniExcel.Csv/CsvWriter.cs b/src/MiniExcel.Csv/CsvWriter.cs index 5ad24a6e..7b220366 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(CsvHelper.ConvertToCsvValue(ToCsvString(column.Value, column.Prop), _configuration)); + rowBuilder.Append(CsvSanitizer.SanitizeCsvField(ToCsvString(column.Value, column.Prop), _configuration)); rowBuilder.Append(_configuration.Seperator); } @@ -223,25 +223,21 @@ public string ToCsvString(object? value, MiniExcelColumnInfo? p) private string GetHeader(List props) => string.Join( _configuration.Seperator.ToString(), - props.Select(s => CsvHelper.ConvertToCsvValue(s?.ExcelColumnName, _configuration))); + props.Select(s => CsvSanitizer.SanitizeCsvField(s?.ExcelColumnName, _configuration))); - protected virtual void Dispose(bool disposing) + private void Dispose(bool disposing) { if (!_disposed) { if (disposing) { _writer.Dispose(); - // TODO: dispose managed state (managed objects) } - // TODO: free unmanaged resources (unmanaged objects) and override finalizer - // TODO: set large fields to null _disposed = true; } } - // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources ~CsvWriter() { // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method @@ -254,4 +250,4 @@ public void Dispose() Dispose(disposing: true); GC.SuppressFinalize(this); } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/Api/OpenXmlExporter.cs b/src/MiniExcel.OpenXml/Api/OpenXmlExporter.cs similarity index 96% rename from src/MiniExcel.Core/Api/OpenXmlExporter.cs rename to src/MiniExcel.OpenXml/Api/OpenXmlExporter.cs index 84d34185..ed8a8810 100644 --- a/src/MiniExcel.Core/Api/OpenXmlExporter.cs +++ b/src/MiniExcel.OpenXml/Api/OpenXmlExporter.cs @@ -1,11 +1,9 @@ -// ReSharper disable once CheckNamespace -namespace MiniExcelLib.Core; +namespace MiniExcelLib.OpenXml.Api; public sealed partial class OpenXmlExporter { internal OpenXmlExporter() { } - [CreateSyncVersion] public async Task InsertSheetAsync(string path, object value, string? sheetName = "Sheet1", bool printHeader = true, bool overwriteSheet = false, OpenXmlConfiguration? configuration = null, diff --git a/src/MiniExcel.Core/Api/OpenXmlImporter.cs b/src/MiniExcel.OpenXml/Api/OpenXmlImporter.cs similarity index 97% rename from src/MiniExcel.Core/Api/OpenXmlImporter.cs rename to src/MiniExcel.OpenXml/Api/OpenXmlImporter.cs index 8b30d3f7..65d500a7 100644 --- a/src/MiniExcel.Core/Api/OpenXmlImporter.cs +++ b/src/MiniExcel.OpenXml/Api/OpenXmlImporter.cs @@ -1,7 +1,7 @@ using System.Dynamic; using MiniExcelLib.Core.DataReader; -using MiniExcelLib.Core.OpenXml.Models; -using MiniExcelLib.Core.OpenXml.Zip; +using MiniExcelLib.OpenXml; +using OpenXmlReader = MiniExcelLib.OpenXml.OpenXmlReader; // ReSharper disable once CheckNamespace namespace MiniExcelLib.Core; diff --git a/src/MiniExcel.Core/Api/OpenXmlTemplater.cs b/src/MiniExcel.OpenXml/Api/OpenXmlTemplater.cs similarity index 94% rename from src/MiniExcel.Core/Api/OpenXmlTemplater.cs rename to src/MiniExcel.OpenXml/Api/OpenXmlTemplater.cs index 6e3aab36..61120299 100644 --- a/src/MiniExcel.Core/Api/OpenXmlTemplater.cs +++ b/src/MiniExcel.OpenXml/Api/OpenXmlTemplater.cs @@ -1,5 +1,7 @@ -using MiniExcelLib.Core.OpenXml.Picture; -using MiniExcelLib.Core.OpenXml.Templates; +using MiniExcelLib.OpenXml; +using MiniExcelLib.OpenXml.Picture; +using MiniExcelLib.OpenXml.Templates; +using OpenXmlTemplate = MiniExcelLib.OpenXml.Templates.OpenXmlTemplate; // ReSharper disable once CheckNamespace namespace MiniExcelLib.Core; diff --git a/src/MiniExcel.OpenXml/Api/ProviderExtensions.cs b/src/MiniExcel.OpenXml/Api/ProviderExtensions.cs new file mode 100644 index 00000000..b5717dc6 --- /dev/null +++ b/src/MiniExcel.OpenXml/Api/ProviderExtensions.cs @@ -0,0 +1,10 @@ +using MiniExcelLib.Core; + +namespace MiniExcelLib.OpenXml.Api; + +public static class ProviderExtensions +{ + public static OpenXmlExporter GetOpenXmlExporter(this MiniExcelExporterProvider exporterProvider) => new(); + public static OpenXmlImporter GetOpenXmlImporter(this MiniExcelImporterProvider importerProvider) => new(); + public static OpenXmlTemplater GetOpenXmlTemplater(this MiniExcelTemplaterProvider templaterProvider) => new(); +} \ No newline at end of file diff --git a/src/MiniExcel.Core/OpenXml/Constants/ExcelContentTypes.cs b/src/MiniExcel.OpenXml/Constants/ExcelContentTypes.cs similarity index 92% rename from src/MiniExcel.Core/OpenXml/Constants/ExcelContentTypes.cs rename to src/MiniExcel.OpenXml/Constants/ExcelContentTypes.cs index 6ef0fe98..dcef2d61 100644 --- a/src/MiniExcel.Core/OpenXml/Constants/ExcelContentTypes.cs +++ b/src/MiniExcel.OpenXml/Constants/ExcelContentTypes.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Constants; +namespace MiniExcelLib.OpenXml.Constants; internal static class ExcelContentTypes { diff --git a/src/MiniExcel.Core/OpenXml/Constants/ExcelFileNames.cs b/src/MiniExcel.OpenXml/Constants/ExcelFileNames.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/Constants/ExcelFileNames.cs rename to src/MiniExcel.OpenXml/Constants/ExcelFileNames.cs index 0f7a6f26..1ea810f6 100644 --- a/src/MiniExcel.Core/OpenXml/Constants/ExcelFileNames.cs +++ b/src/MiniExcel.OpenXml/Constants/ExcelFileNames.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Constants; +namespace MiniExcelLib.OpenXml.Constants; internal static class ExcelFileNames { diff --git a/src/MiniExcel.Core/OpenXml/Constants/ExcelXml.cs b/src/MiniExcel.OpenXml/Constants/ExcelXml.cs similarity index 96% rename from src/MiniExcel.Core/OpenXml/Constants/ExcelXml.cs rename to src/MiniExcel.OpenXml/Constants/ExcelXml.cs index fd885fcc..868d512b 100644 --- a/src/MiniExcel.Core/OpenXml/Constants/ExcelXml.cs +++ b/src/MiniExcel.OpenXml/Constants/ExcelXml.cs @@ -1,6 +1,4 @@ -using MiniExcelLib.Core.OpenXml.Models; - -namespace MiniExcelLib.Core.OpenXml.Constants; +namespace MiniExcelLib.OpenXml.Constants; internal static class ExcelXml { diff --git a/src/MiniExcel.Core/OpenXml/Constants/Schemas.cs b/src/MiniExcel.OpenXml/Constants/Schemas.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/Constants/Schemas.cs rename to src/MiniExcel.OpenXml/Constants/Schemas.cs index 8af3ea62..72c2e08f 100644 --- a/src/MiniExcel.Core/OpenXml/Constants/Schemas.cs +++ b/src/MiniExcel.OpenXml/Constants/Schemas.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Constants; +namespace MiniExcelLib.OpenXml.Constants; internal static class Schemas { diff --git a/src/MiniExcel.Core/OpenXml/Constants/WorksheetXml.cs b/src/MiniExcel.OpenXml/Constants/WorksheetXml.cs similarity index 97% rename from src/MiniExcel.Core/OpenXml/Constants/WorksheetXml.cs rename to src/MiniExcel.OpenXml/Constants/WorksheetXml.cs index a82e5f11..f0f21498 100644 --- a/src/MiniExcel.Core/OpenXml/Constants/WorksheetXml.cs +++ b/src/MiniExcel.OpenXml/Constants/WorksheetXml.cs @@ -1,6 +1,6 @@ using MiniExcelLib.Core.Attributes; -namespace MiniExcelLib.Core.OpenXml.Constants; +namespace MiniExcelLib.OpenXml.Constants; internal static class WorksheetXml { diff --git a/src/MiniExcel.Core/FluentMapping/Api/MappingExporter.cs b/src/MiniExcel.OpenXml/FluentMapping/Api/MappingExporter.cs similarity index 92% rename from src/MiniExcel.Core/FluentMapping/Api/MappingExporter.cs rename to src/MiniExcel.OpenXml/FluentMapping/Api/MappingExporter.cs index 62e51654..d4dc10ea 100644 --- a/src/MiniExcel.Core/FluentMapping/Api/MappingExporter.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Api/MappingExporter.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping; +using Zomp.SyncMethodGenerator; + +namespace MiniExcelLib.OpenXml.FluentMapping.Api; public sealed partial class MappingExporter { diff --git a/src/MiniExcel.Core/FluentMapping/Api/MappingImporter.cs b/src/MiniExcel.OpenXml/FluentMapping/Api/MappingImporter.cs similarity index 93% rename from src/MiniExcel.Core/FluentMapping/Api/MappingImporter.cs rename to src/MiniExcel.OpenXml/FluentMapping/Api/MappingImporter.cs index d7a1e14d..f0d37781 100644 --- a/src/MiniExcel.Core/FluentMapping/Api/MappingImporter.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Api/MappingImporter.cs @@ -1,4 +1,7 @@ -namespace MiniExcelLib.Core.FluentMapping; +using System.Runtime.CompilerServices; +using Zomp.SyncMethodGenerator; + +namespace MiniExcelLib.OpenXml.FluentMapping.Api; public sealed partial class MappingImporter() { diff --git a/src/MiniExcel.Core/FluentMapping/Api/MappingTemplater.cs b/src/MiniExcel.OpenXml/FluentMapping/Api/MappingTemplater.cs similarity index 94% rename from src/MiniExcel.Core/FluentMapping/Api/MappingTemplater.cs rename to src/MiniExcel.OpenXml/FluentMapping/Api/MappingTemplater.cs index c2de939b..f185b088 100644 --- a/src/MiniExcel.Core/FluentMapping/Api/MappingTemplater.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Api/MappingTemplater.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping; +using Zomp.SyncMethodGenerator; + +namespace MiniExcelLib.OpenXml.FluentMapping.Api; public sealed partial class MappingTemplater() { diff --git a/src/MiniExcel.Core/FluentMapping/Api/ProviderExtensions.cs b/src/MiniExcel.OpenXml/FluentMapping/Api/ProviderExtensions.cs similarity index 90% rename from src/MiniExcel.Core/FluentMapping/Api/ProviderExtensions.cs rename to src/MiniExcel.OpenXml/FluentMapping/Api/ProviderExtensions.cs index 6ab369c2..1a4a502e 100644 --- a/src/MiniExcel.Core/FluentMapping/Api/ProviderExtensions.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Api/ProviderExtensions.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.Core; + +namespace MiniExcelLib.OpenXml.FluentMapping.Api; public static class ProviderExtensions { diff --git a/src/MiniExcel.Core/FluentMapping/CompiledMapping.cs b/src/MiniExcel.OpenXml/FluentMapping/CompiledMapping.cs similarity index 97% rename from src/MiniExcel.Core/FluentMapping/CompiledMapping.cs rename to src/MiniExcel.OpenXml/FluentMapping/CompiledMapping.cs index 84238b3c..322e2e51 100644 --- a/src/MiniExcel.Core/FluentMapping/CompiledMapping.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/CompiledMapping.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping; +using System.Collections; + +namespace MiniExcelLib.OpenXml.FluentMapping; internal class CompiledMapping { diff --git a/src/MiniExcel.Core/FluentMapping/Configuration/CollectionMappingBuilder.cs b/src/MiniExcel.OpenXml/FluentMapping/Configuration/CollectionMappingBuilder.cs similarity index 91% rename from src/MiniExcel.Core/FluentMapping/Configuration/CollectionMappingBuilder.cs rename to src/MiniExcel.OpenXml/FluentMapping/Configuration/CollectionMappingBuilder.cs index 57719ea8..9cae1c35 100644 --- a/src/MiniExcel.Core/FluentMapping/Configuration/CollectionMappingBuilder.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Configuration/CollectionMappingBuilder.cs @@ -1,4 +1,7 @@ -namespace MiniExcelLib.Core.FluentMapping.Configuration; +using System.Collections; +using System.Text.RegularExpressions; + +namespace MiniExcelLib.OpenXml.FluentMapping.Configuration; internal partial class CollectionMappingBuilder : ICollectionMappingBuilder where TCollection : IEnumerable { diff --git a/src/MiniExcel.Core/FluentMapping/Configuration/ICollectionMappingBuilder.cs b/src/MiniExcel.OpenXml/FluentMapping/Configuration/ICollectionMappingBuilder.cs similarity index 79% rename from src/MiniExcel.Core/FluentMapping/Configuration/ICollectionMappingBuilder.cs rename to src/MiniExcel.OpenXml/FluentMapping/Configuration/ICollectionMappingBuilder.cs index 03fd8dc7..ab459c4c 100644 --- a/src/MiniExcel.Core/FluentMapping/Configuration/ICollectionMappingBuilder.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Configuration/ICollectionMappingBuilder.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping.Configuration; +using System.Collections; + +namespace MiniExcelLib.OpenXml.FluentMapping.Configuration; public interface ICollectionMappingBuilder where TCollection : IEnumerable { diff --git a/src/MiniExcel.Core/FluentMapping/Configuration/IMappingConfiguration.cs b/src/MiniExcel.OpenXml/FluentMapping/Configuration/IMappingConfiguration.cs similarity index 80% rename from src/MiniExcel.Core/FluentMapping/Configuration/IMappingConfiguration.cs rename to src/MiniExcel.OpenXml/FluentMapping/Configuration/IMappingConfiguration.cs index c8200540..01c18bb7 100644 --- a/src/MiniExcel.Core/FluentMapping/Configuration/IMappingConfiguration.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Configuration/IMappingConfiguration.cs @@ -1,6 +1,7 @@ +using System.Collections; using System.Linq.Expressions; -namespace MiniExcelLib.Core.FluentMapping.Configuration; +namespace MiniExcelLib.OpenXml.FluentMapping.Configuration; public interface IMappingConfiguration { diff --git a/src/MiniExcel.Core/FluentMapping/Configuration/IPropertyMappingBuilder.cs b/src/MiniExcel.OpenXml/FluentMapping/Configuration/IPropertyMappingBuilder.cs similarity index 80% rename from src/MiniExcel.Core/FluentMapping/Configuration/IPropertyMappingBuilder.cs rename to src/MiniExcel.OpenXml/FluentMapping/Configuration/IPropertyMappingBuilder.cs index 8580ed9c..8d17686e 100644 --- a/src/MiniExcel.Core/FluentMapping/Configuration/IPropertyMappingBuilder.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Configuration/IPropertyMappingBuilder.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.FluentMapping.Configuration; +namespace MiniExcelLib.OpenXml.FluentMapping.Configuration; public interface IPropertyMappingBuilder { diff --git a/src/MiniExcel.Core/FluentMapping/Configuration/MappingConfiguration.cs b/src/MiniExcel.OpenXml/FluentMapping/Configuration/MappingConfiguration.cs similarity index 93% rename from src/MiniExcel.Core/FluentMapping/Configuration/MappingConfiguration.cs rename to src/MiniExcel.OpenXml/FluentMapping/Configuration/MappingConfiguration.cs index 1f35f778..7322cde7 100644 --- a/src/MiniExcel.Core/FluentMapping/Configuration/MappingConfiguration.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Configuration/MappingConfiguration.cs @@ -1,6 +1,7 @@ +using System.Collections; using System.Linq.Expressions; -namespace MiniExcelLib.Core.FluentMapping.Configuration; +namespace MiniExcelLib.OpenXml.FluentMapping.Configuration; internal class MappingConfiguration : IMappingConfiguration { diff --git a/src/MiniExcel.Core/FluentMapping/Configuration/PropertyMappingBuilder.cs b/src/MiniExcel.OpenXml/FluentMapping/Configuration/PropertyMappingBuilder.cs similarity index 91% rename from src/MiniExcel.Core/FluentMapping/Configuration/PropertyMappingBuilder.cs rename to src/MiniExcel.OpenXml/FluentMapping/Configuration/PropertyMappingBuilder.cs index f0c490fd..df514ec3 100644 --- a/src/MiniExcel.Core/FluentMapping/Configuration/PropertyMappingBuilder.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Configuration/PropertyMappingBuilder.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping.Configuration; +using System.Text.RegularExpressions; + +namespace MiniExcelLib.OpenXml.FluentMapping.Configuration; internal partial class PropertyMappingBuilder : IPropertyMappingBuilder { diff --git a/src/MiniExcel.Core/Helpers/ConversionHelper.cs b/src/MiniExcel.OpenXml/FluentMapping/Helpers/ConversionHelper.cs similarity index 96% rename from src/MiniExcel.Core/Helpers/ConversionHelper.cs rename to src/MiniExcel.OpenXml/FluentMapping/Helpers/ConversionHelper.cs index 1efad08b..45da6d89 100644 --- a/src/MiniExcel.Core/Helpers/ConversionHelper.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Helpers/ConversionHelper.cs @@ -1,7 +1,9 @@ using System.Collections.Concurrent; +using System.Globalization; using System.Linq.Expressions; +using System.Reflection; -namespace MiniExcelLib.Core.Helpers; +namespace MiniExcelLib.OpenXml.FluentMapping.Helpers; /// /// Optimized value conversion with caching diff --git a/src/MiniExcel.Core/Helpers/MappingMetadataExtractor.cs b/src/MiniExcel.OpenXml/FluentMapping/Helpers/MappingMetadataExtractor.cs similarity index 97% rename from src/MiniExcel.Core/Helpers/MappingMetadataExtractor.cs rename to src/MiniExcel.OpenXml/FluentMapping/Helpers/MappingMetadataExtractor.cs index 388a3e5e..0cd44fd5 100644 --- a/src/MiniExcel.Core/Helpers/MappingMetadataExtractor.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/Helpers/MappingMetadataExtractor.cs @@ -1,6 +1,10 @@ -using MiniExcelLib.Core.FluentMapping; +using System.Collections; +using System.Reflection; +using MiniExcelLib.Core.Helpers; +using MiniExcelLib.Core.Reflection; +using MiniExcelLib.OpenXml.FluentMapping.Helpers; -namespace MiniExcelLib.Core.Helpers; +namespace MiniExcelLib.OpenXml.FluentMapping; /// /// Helper class for extracting mapping metadata using reflection. diff --git a/src/MiniExcel.Core/OpenXml/MappedRow.cs b/src/MiniExcel.OpenXml/FluentMapping/MappedRow.cs similarity index 86% rename from src/MiniExcel.Core/OpenXml/MappedRow.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappedRow.cs index 2989984c..2c29e5d2 100644 --- a/src/MiniExcel.Core/OpenXml/MappedRow.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappedRow.cs @@ -1,6 +1,6 @@ -namespace MiniExcelLib.Core.OpenXml; +namespace MiniExcelLib.OpenXml; -internal struct MappedRow(int rowIndex) +public struct MappedRow(int rowIndex) { private const int MaxColumns = 100; private object?[]? _cells = null; diff --git a/src/MiniExcel.Core/FluentMapping/MappingCellStream.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingCellStream.cs similarity index 95% rename from src/MiniExcel.Core/FluentMapping/MappingCellStream.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingCellStream.cs index 1834de67..4f382695 100644 --- a/src/MiniExcel.Core/FluentMapping/MappingCellStream.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingCellStream.cs @@ -1,11 +1,7 @@ -using MiniExcelLib.Core.WriteAdapters; +using System.Collections; +using MiniExcelLib.Core.Abstractions; -namespace MiniExcelLib.Core.FluentMapping; - -internal interface IMappingCellStream -{ - IMiniExcelWriteAdapter CreateAdapter(); -} +namespace MiniExcelLib.OpenXml.FluentMapping; internal readonly struct MappingCellStream(IEnumerable items, CompiledMapping mapping, string[] columnLetters) : IMappingCellStream where T : class @@ -17,8 +13,7 @@ public IMiniExcelWriteAdapter CreateAdapter() => new MappingCellStreamAdapter(this, columnLetters); } -internal struct MappingCellEnumerator : IEnumerator - where T : class +internal struct MappingCellEnumerator : IEnumerator where T : class { private readonly IEnumerator _itemEnumerator; private readonly CompiledMapping _mapping; diff --git a/src/MiniExcel.Core/WriteAdapters/MappingCellStreamAdapter.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingCellStreamAdapter.cs similarity index 91% rename from src/MiniExcel.Core/WriteAdapters/MappingCellStreamAdapter.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingCellStreamAdapter.cs index f69d782b..e0579644 100644 --- a/src/MiniExcel.Core/WriteAdapters/MappingCellStreamAdapter.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingCellStreamAdapter.cs @@ -1,10 +1,10 @@ -using MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.Core.Abstractions; +using MiniExcelLib.Core.Reflection; -namespace MiniExcelLib.Core.WriteAdapters; +namespace MiniExcelLib.OpenXml.FluentMapping; internal class MappingCellStreamAdapter(MappingCellStream cellStream, string[] columnLetters) - : IMiniExcelWriteAdapter - where T : class + : IMiniExcelWriteAdapter where T : class { private readonly MappingCellStream _cellStream = cellStream; private readonly string[] _columnLetters = columnLetters; diff --git a/src/MiniExcel.Core/FluentMapping/MappingCompiler.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingCompiler.cs similarity index 96% rename from src/MiniExcel.Core/FluentMapping/MappingCompiler.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingCompiler.cs index 4c5a1490..b7dbae53 100644 --- a/src/MiniExcel.Core/FluentMapping/MappingCompiler.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingCompiler.cs @@ -1,7 +1,13 @@ +using System.Collections; using System.Linq.Expressions; -using MiniExcelLib.Core.FluentMapping.Configuration; +using System.Reflection; +using MiniExcelLib.Core.Helpers; +using MiniExcelLib.Core.Reflection; +using MiniExcelLib.OpenXml.FluentMapping.Configuration; +using MiniExcelLib.OpenXml.FluentMapping.Helpers; +using MiniExcelLib.OpenXml.Utils; -namespace MiniExcelLib.Core.FluentMapping; +namespace MiniExcelLib.OpenXml.FluentMapping; /// /// Compiles mapping configurations into optimized runtime representations for efficient Excel read/write operations. @@ -53,7 +59,7 @@ public static CompiledMapping Compile(MappingConfiguration? configurati if (prop.CellAddress is null) continue; - ReferenceHelper.ParseReference(prop.CellAddress, out int cellCol, out int cellRow); + CellReferenceConverter.TryParseCellReference(prop.CellAddress, out int cellCol, out int cellRow); properties.Add(new CompiledPropertyMapping { @@ -101,7 +107,7 @@ public static CompiledMapping Compile(MappingConfiguration? configurati if (coll.StartCell is null) continue; - ReferenceHelper.ParseReference(coll.StartCell, out int startCol, out int startRow); + CellReferenceConverter.TryParseCellReference(coll.StartCell, out int startCol, out int startRow); var compiledCollection = new CompiledCollectionMapping { @@ -772,4 +778,4 @@ private static int GetMaxColumnIndex(NestedMappingInfo nestedInfo, int currentMa return currentMax; } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/FluentMapping/MappingReader.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingReader.cs similarity index 97% rename from src/MiniExcel.Core/FluentMapping/MappingReader.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingReader.cs index 0ed06914..bf1181c2 100644 --- a/src/MiniExcel.Core/FluentMapping/MappingReader.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingReader.cs @@ -1,4 +1,8 @@ -namespace MiniExcelLib.Core.FluentMapping; +using System.Collections; +using System.Runtime.CompilerServices; +using Zomp.SyncMethodGenerator; + +namespace MiniExcelLib.OpenXml.FluentMapping; internal static partial class MappingReader where T : class, new() { diff --git a/src/MiniExcel.Core/FluentMapping/MappingRegistry.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingRegistry.cs similarity index 92% rename from src/MiniExcel.Core/FluentMapping/MappingRegistry.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingRegistry.cs index 90893f3a..54d8d629 100644 --- a/src/MiniExcel.Core/FluentMapping/MappingRegistry.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingRegistry.cs @@ -1,6 +1,7 @@ -using MiniExcelLib.Core.FluentMapping.Configuration; +using System.Reflection; +using MiniExcelLib.OpenXml.FluentMapping.Configuration; -namespace MiniExcelLib.Core.FluentMapping; +namespace MiniExcelLib.OpenXml.FluentMapping; public sealed class MappingRegistry { diff --git a/src/MiniExcel.Core/FluentMapping/MappingTemplateApplicator.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingTemplateApplicator.cs similarity index 95% rename from src/MiniExcel.Core/FluentMapping/MappingTemplateApplicator.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingTemplateApplicator.cs index ef165eaf..969eb35e 100644 --- a/src/MiniExcel.Core/FluentMapping/MappingTemplateApplicator.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingTemplateApplicator.cs @@ -1,4 +1,7 @@ -namespace MiniExcelLib.Core.FluentMapping; +using System.IO.Compression; +using Zomp.SyncMethodGenerator; + +namespace MiniExcelLib.OpenXml.FluentMapping; internal static partial class MappingTemplateApplicator where T : class { diff --git a/src/MiniExcel.Core/FluentMapping/MappingTemplateProcessor.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingTemplateProcessor.cs similarity index 95% rename from src/MiniExcel.Core/FluentMapping/MappingTemplateProcessor.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingTemplateProcessor.cs index dd21c705..10779bd6 100644 --- a/src/MiniExcel.Core/FluentMapping/MappingTemplateProcessor.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingTemplateProcessor.cs @@ -1,4 +1,10 @@ -namespace MiniExcelLib.Core.FluentMapping; +using System.Text; +using System.Xml; +using MiniExcelLib.OpenXml.Helpers; +using MiniExcelLib.OpenXml.Utils; +using Zomp.SyncMethodGenerator; + +namespace MiniExcelLib.OpenXml.FluentMapping; internal partial struct MappingTemplateProcessor(CompiledMapping mapping) where T : class { @@ -170,7 +176,7 @@ await writer.WriteAttributeStringAsync( if (!string.IsNullOrEmpty(cellRef)) { // Parse cell reference to get column and row - if (ReferenceHelper.TryParseCellReference(cellRef, out var col, out var row)) + if (CellReferenceConverter.TryParseCellReference(cellRef, out var col, out var row)) { // Track that we've written this column writtenColumns.Add(col); @@ -307,7 +313,7 @@ private async Task WriteNewRowAsync( // Try to get the value if (mapping.TryGetValue(handler, currentItem, out var value) && value is not null) { - var cellRef = ReferenceHelper.ConvertCoordinatesToCell(col, rowNumber); + var cellRef = CellReferenceConverter.GetCellFromCoordinates(col, rowNumber); await XmlCellWriter.WriteNewCellAsync(writer, cellRef, value).ConfigureAwait(false); } } @@ -343,7 +349,7 @@ private async Task WriteMissingCellsAsync( if (mapping.TryGetValue(handler, currentItem, out var value) && value is not null) { // Create cell reference - var cellRef = ReferenceHelper.ConvertCoordinatesToCell(col, rowNumber); + var cellRef = CellReferenceConverter.GetCellFromCoordinates(col, rowNumber); // Write the cell using centralized helper await XmlCellWriter.WriteNewCellAsync(writer, cellRef, value).ConfigureAwait(false); diff --git a/src/MiniExcel.Core/FluentMapping/MappingWriter.cs b/src/MiniExcel.OpenXml/FluentMapping/MappingWriter.cs similarity index 85% rename from src/MiniExcel.Core/FluentMapping/MappingWriter.cs rename to src/MiniExcel.OpenXml/FluentMapping/MappingWriter.cs index 656ddb89..9b87d963 100644 --- a/src/MiniExcel.Core/FluentMapping/MappingWriter.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/MappingWriter.cs @@ -1,7 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping; +namespace MiniExcelLib.OpenXml.FluentMapping; -internal static partial class MappingWriter - where T : class +internal static partial class MappingWriter where T : class { [CreateSyncVersion] public static async Task SaveAsAsync(Stream stream, IEnumerable value, CompiledMapping mapping, CancellationToken cancellationToken = default) @@ -29,8 +28,7 @@ private static async Task SaveAsOptimizedAsync(Stream stream, IEnumerable var columnLetters = new string[boundaries.MaxColumn - boundaries.MinColumn + 1]; for (int i = 0; i < columnLetters.Length; i++) { - var cellRef = ReferenceHelper.ConvertCoordinatesToCell(boundaries.MinColumn + i, 1); - columnLetters[i] = ReferenceHelper.GetCellLetter(cellRef); + columnLetters[i] = CellReferenceConverter.GetAlphabeticalIndex(boundaries.MinColumn + i); } // Create cell stream instead of dictionary rows @@ -43,4 +41,4 @@ private static async Task SaveAsOptimizedAsync(Stream stream, IEnumerable return await writer.SaveAsAsync(null, cancellationToken).ConfigureAwait(false); } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/FluentMapping/NestedMappingInfo.cs b/src/MiniExcel.OpenXml/FluentMapping/NestedMappingInfo.cs similarity index 94% rename from src/MiniExcel.Core/FluentMapping/NestedMappingInfo.cs rename to src/MiniExcel.OpenXml/FluentMapping/NestedMappingInfo.cs index 3d701b4f..300918a1 100644 --- a/src/MiniExcel.Core/FluentMapping/NestedMappingInfo.cs +++ b/src/MiniExcel.OpenXml/FluentMapping/NestedMappingInfo.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Core.FluentMapping; +using System.Collections; + +namespace MiniExcelLib.OpenXml.FluentMapping; /// /// Stores pre-compiled information about nested properties in collection mappings. diff --git a/src/MiniExcel.OpenXml/GlobalUsings.cs b/src/MiniExcel.OpenXml/GlobalUsings.cs new file mode 100644 index 00000000..05f2a69b --- /dev/null +++ b/src/MiniExcel.OpenXml/GlobalUsings.cs @@ -0,0 +1,19 @@ +// Global using directives + +global using System.Collections; +global using System.Data; +global using System.Globalization; +global using System.IO.Compression; +global using System.Reflection; +global using System.Runtime.CompilerServices; +global using System.Text; +global using System.Text.RegularExpressions; +global using System.Xml; +global using MiniExcelLib.Core.Abstractions; +global using MiniExcelLib.Core.Helpers; +global using MiniExcelLib.Core.Reflection; +global using MiniExcelLib.OpenXml.Helpers; +global using MiniExcelLib.OpenXml.Models; +global using MiniExcelLib.OpenXml.Utils; +global using MiniExcelLib.OpenXml.Zip; +global using Zomp.SyncMethodGenerator; diff --git a/src/MiniExcel.Core/Helpers/CellFormatter.cs b/src/MiniExcel.OpenXml/Helpers/CellFormatter.cs similarity index 95% rename from src/MiniExcel.Core/Helpers/CellFormatter.cs rename to src/MiniExcel.OpenXml/Helpers/CellFormatter.cs index cb7da44d..7bc79682 100644 --- a/src/MiniExcel.Core/Helpers/CellFormatter.cs +++ b/src/MiniExcel.OpenXml/Helpers/CellFormatter.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.Helpers; +namespace MiniExcelLib.OpenXml.Helpers; /// /// Utility class for formatting cell values consistently across the mapping system. diff --git a/src/MiniExcel.Core/Helpers/StringHelper.cs b/src/MiniExcel.OpenXml/Helpers/StringHelper.cs similarity index 83% rename from src/MiniExcel.Core/Helpers/StringHelper.cs rename to src/MiniExcel.OpenXml/Helpers/StringHelper.cs index 94ff906b..6d6331b1 100644 --- a/src/MiniExcel.Core/Helpers/StringHelper.cs +++ b/src/MiniExcel.OpenXml/Helpers/StringHelper.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.Helpers; +namespace MiniExcelLib.OpenXml.Helpers; internal static class StringHelper { diff --git a/src/MiniExcel.Core/Helpers/ThrowHelper.cs b/src/MiniExcel.OpenXml/Helpers/ThrowHelper.cs similarity index 93% rename from src/MiniExcel.Core/Helpers/ThrowHelper.cs rename to src/MiniExcel.OpenXml/Helpers/ThrowHelper.cs index a277600c..656e1c70 100644 --- a/src/MiniExcel.Core/Helpers/ThrowHelper.cs +++ b/src/MiniExcel.OpenXml/Helpers/ThrowHelper.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.Helpers; +namespace MiniExcelLib.OpenXml.Helpers; internal static class ThrowHelper { diff --git a/src/MiniExcel.Core/Helpers/XmlCellWriter.cs b/src/MiniExcel.OpenXml/Helpers/XmlCellWriter.cs similarity index 96% rename from src/MiniExcel.Core/Helpers/XmlCellWriter.cs rename to src/MiniExcel.OpenXml/Helpers/XmlCellWriter.cs index 49253738..db418ca2 100644 --- a/src/MiniExcel.Core/Helpers/XmlCellWriter.cs +++ b/src/MiniExcel.OpenXml/Helpers/XmlCellWriter.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.Helpers; +namespace MiniExcelLib.OpenXml.Helpers; /// /// Helper class for writing Excel cell XML with consistent formatting. diff --git a/src/MiniExcel.Core/Helpers/XmlHelper.cs b/src/MiniExcel.OpenXml/Helpers/XmlHelper.cs similarity index 93% rename from src/MiniExcel.Core/Helpers/XmlHelper.cs rename to src/MiniExcel.OpenXml/Helpers/XmlHelper.cs index ea12a6bf..04a3a4ef 100644 --- a/src/MiniExcel.Core/Helpers/XmlHelper.cs +++ b/src/MiniExcel.OpenXml/Helpers/XmlHelper.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.Helpers; +namespace MiniExcelLib.OpenXml.Helpers; /// XmlEncoder MIT Copyright ©2021 from https://github.com/ClosedXML internal static partial class XmlHelper @@ -52,7 +52,7 @@ public static string MinifyXml(string xml) => xml /// Encode to XML (special characteres: ' " > < &) /// public static string EncodeXml(string? value) => value is null ? "" - : XmlHelper.EncodeString(value) + : EncodeString(value) ?.Replace("&", "&") .Replace("<", "<") .Replace(">", ">") diff --git a/src/MiniExcel.OpenXml/MiniExcel.OpenXml.csproj b/src/MiniExcel.OpenXml/MiniExcel.OpenXml.csproj new file mode 100644 index 00000000..01eb701a --- /dev/null +++ b/src/MiniExcel.OpenXml/MiniExcel.OpenXml.csproj @@ -0,0 +1,20 @@ + + + + MiniExcelLib.OpenXml + + + + MiniExcel.OpenXml + MiniExcel.OpenXml + + + + + + + + + + + diff --git a/src/MiniExcel.Core/Attributes/MiniExcelSheetAttribute.cs b/src/MiniExcel.OpenXml/MiniExcelSheetAttribute.cs similarity index 76% rename from src/MiniExcel.Core/Attributes/MiniExcelSheetAttribute.cs rename to src/MiniExcel.OpenXml/MiniExcelSheetAttribute.cs index 182c4ffa..870104b7 100644 --- a/src/MiniExcel.Core/Attributes/MiniExcelSheetAttribute.cs +++ b/src/MiniExcel.OpenXml/MiniExcelSheetAttribute.cs @@ -1,6 +1,4 @@ -using MiniExcelLib.Core.OpenXml.Models; - -namespace MiniExcelLib.Core.Attributes; +namespace MiniExcelLib.OpenXml; [AttributeUsage(AttributeTargets.Class)] public class MiniExcelSheetAttribute : Attribute @@ -12,4 +10,4 @@ public class MiniExcelSheetAttribute : Attribute public class DynamicExcelSheetAttribute(string key) : MiniExcelSheetAttribute { public string Key { get; set; } = key; -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/Models/DrawingDto.cs b/src/MiniExcel.OpenXml/Models/DrawingDto.cs similarity index 64% rename from src/MiniExcel.Core/OpenXml/Models/DrawingDto.cs rename to src/MiniExcel.OpenXml/Models/DrawingDto.cs index 3a8ba087..43ddbcf4 100644 --- a/src/MiniExcel.Core/OpenXml/Models/DrawingDto.cs +++ b/src/MiniExcel.OpenXml/Models/DrawingDto.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; internal class DrawingDto { diff --git a/src/MiniExcel.Core/OpenXml/Models/ExcelRange.cs b/src/MiniExcel.OpenXml/Models/ExcelRange.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/Models/ExcelRange.cs rename to src/MiniExcel.OpenXml/Models/ExcelRange.cs index b541c7c8..bea1fd20 100644 --- a/src/MiniExcel.Core/OpenXml/Models/ExcelRange.cs +++ b/src/MiniExcel.OpenXml/Models/ExcelRange.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; public class ExcelRangeElement { diff --git a/src/MiniExcel.Core/OpenXml/Models/ExcelWidthCollection.cs b/src/MiniExcel.OpenXml/Models/ExcelWidthCollection.cs similarity index 95% rename from src/MiniExcel.Core/OpenXml/Models/ExcelWidthCollection.cs rename to src/MiniExcel.OpenXml/Models/ExcelWidthCollection.cs index 7ed738b4..e1ac0d38 100644 --- a/src/MiniExcel.Core/OpenXml/Models/ExcelWidthCollection.cs +++ b/src/MiniExcel.OpenXml/Models/ExcelWidthCollection.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; public sealed class ExcelColumnWidth { diff --git a/src/MiniExcel.Core/OpenXml/Models/ExcellSheetInfo.cs b/src/MiniExcel.OpenXml/Models/ExcellSheetInfo.cs similarity index 88% rename from src/MiniExcel.Core/OpenXml/Models/ExcellSheetInfo.cs rename to src/MiniExcel.OpenXml/Models/ExcellSheetInfo.cs index 79cd8869..57cb3efd 100644 --- a/src/MiniExcel.Core/OpenXml/Models/ExcellSheetInfo.cs +++ b/src/MiniExcel.OpenXml/Models/ExcellSheetInfo.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; internal class ExcellSheetInfo { diff --git a/src/MiniExcel.Core/OpenXml/Models/FileDto.cs b/src/MiniExcel.OpenXml/Models/FileDto.cs similarity index 88% rename from src/MiniExcel.Core/OpenXml/Models/FileDto.cs rename to src/MiniExcel.OpenXml/Models/FileDto.cs index 6a6ddc4a..8bb581f5 100644 --- a/src/MiniExcel.Core/OpenXml/Models/FileDto.cs +++ b/src/MiniExcel.OpenXml/Models/FileDto.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; internal class FileDto { diff --git a/src/MiniExcel.Core/OpenXml/Models/MergeCells.cs b/src/MiniExcel.OpenXml/Models/MergeCells.cs similarity index 77% rename from src/MiniExcel.Core/OpenXml/Models/MergeCells.cs rename to src/MiniExcel.OpenXml/Models/MergeCells.cs index a8c41919..b5b4ba3b 100644 --- a/src/MiniExcel.Core/OpenXml/Models/MergeCells.cs +++ b/src/MiniExcel.OpenXml/Models/MergeCells.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; internal class MergeCells { diff --git a/src/MiniExcel.Core/OpenXml/Models/SheetDto.cs b/src/MiniExcel.OpenXml/Models/SheetDto.cs similarity index 82% rename from src/MiniExcel.Core/OpenXml/Models/SheetDto.cs rename to src/MiniExcel.OpenXml/Models/SheetDto.cs index c18cb0ea..1bea641f 100644 --- a/src/MiniExcel.Core/OpenXml/Models/SheetDto.cs +++ b/src/MiniExcel.OpenXml/Models/SheetDto.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; internal class SheetDto { diff --git a/src/MiniExcel.Core/OpenXml/Models/SheetInfo.cs b/src/MiniExcel.OpenXml/Models/SheetInfo.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/Models/SheetInfo.cs rename to src/MiniExcel.OpenXml/Models/SheetInfo.cs index 5bea92b2..ac063d16 100644 --- a/src/MiniExcel.Core/OpenXml/Models/SheetInfo.cs +++ b/src/MiniExcel.OpenXml/Models/SheetInfo.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; public class SheetInfo(uint id, uint index, string name, SheetState sheetState, bool active) { diff --git a/src/MiniExcel.Core/OpenXml/Models/SheetRecord.cs b/src/MiniExcel.OpenXml/Models/SheetRecord.cs similarity index 92% rename from src/MiniExcel.Core/OpenXml/Models/SheetRecord.cs rename to src/MiniExcel.OpenXml/Models/SheetRecord.cs index 2bc57d71..57747254 100644 --- a/src/MiniExcel.Core/OpenXml/Models/SheetRecord.cs +++ b/src/MiniExcel.OpenXml/Models/SheetRecord.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Models; +namespace MiniExcelLib.OpenXml.Models; internal sealed class SheetRecord(string name, string state, uint id, string rid, bool active) { diff --git a/src/MiniExcel.Core/OpenXml/OpenXmlConfiguration.cs b/src/MiniExcel.OpenXml/OpenXmlConfiguration.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/OpenXmlConfiguration.cs rename to src/MiniExcel.OpenXml/OpenXmlConfiguration.cs index 3a63df41..0781d278 100644 --- a/src/MiniExcel.Core/OpenXml/OpenXmlConfiguration.cs +++ b/src/MiniExcel.OpenXml/OpenXmlConfiguration.cs @@ -1,7 +1,7 @@ -using MiniExcelLib.Core.Attributes; -using MiniExcelLib.Core.OpenXml.Styles; +using MiniExcelLib.Core; +using MiniExcelLib.OpenXml.Styles; -namespace MiniExcelLib.Core.OpenXml; +namespace MiniExcelLib.OpenXml; public class OpenXmlConfiguration : MiniExcelBaseConfiguration { @@ -44,4 +44,4 @@ public enum TableStyles { None, Default -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/OpenXmlReader.cs b/src/MiniExcel.OpenXml/OpenXmlReader.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/OpenXmlReader.cs rename to src/MiniExcel.OpenXml/OpenXmlReader.cs index 17be9ab8..6e5587ea 100644 --- a/src/MiniExcel.Core/OpenXml/OpenXmlReader.cs +++ b/src/MiniExcel.OpenXml/OpenXmlReader.cs @@ -1,12 +1,11 @@ using System.Collections.ObjectModel; -using MiniExcelLib.Core.OpenXml.Constants; -using MiniExcelLib.Core.OpenXml.Models; -using MiniExcelLib.Core.OpenXml.Styles; -using MiniExcelLib.Core.OpenXml.Zip; +using MiniExcelLib.Core; +using MiniExcelLib.OpenXml.Constants; +using MiniExcelLib.OpenXml.Styles; using MiniExcelMapper = MiniExcelLib.Core.Reflection.MiniExcelMapper; -using XmlReaderHelper = MiniExcelLib.Core.OpenXml.Utils.XmlReaderHelper; +using XmlReaderHelper = MiniExcelLib.OpenXml.Utils.XmlReaderHelper; -namespace MiniExcelLib.Core.OpenXml; +namespace MiniExcelLib.OpenXml; internal partial class OpenXmlReader : IMiniExcelReader { @@ -46,11 +45,16 @@ internal static async Task CreateAsync(Stream stream, IMiniExcelC [CreateSyncVersion] public IAsyncEnumerable QueryAsync(string? sheetName, string startCell, bool mapHeaderAsData, CancellationToken cancellationToken = default) where T : class, new() { - sheetName ??= ExcelPropertyHelper.GetExcellSheetInfo(typeof(T), _config)?.ExcelSheetName; - + sheetName ??= MiniExcelPropertyHelper.GetExcellSheetInfo(typeof(T), _config)?.ExcelSheetName; + var query = QueryAsync(false, sheetName, startCell, cancellationToken); + if (!CellReferenceConverter.TryParseCellReference(startCell, out _, out var rowOffset)) + { + throw new InvalidDataException($"Value {startCell} is not a valid cell reference."); + } + //Todo: Find a way if possible to remove the 'hasHeader' parameter to check whether or not to include // the first row in the result set in favor of modifying the already present 'useHeaderRow' to do the same job - return MiniExcelMapper.MapQueryAsync(QueryAsync(false, sheetName, startCell, cancellationToken), startCell, mapHeaderAsData, _config.TrimColumnNames, _config, cancellationToken); + return MiniExcelMapper.MapQueryAsync(query, rowOffset, mapHeaderAsData, _config.TrimColumnNames, _config, XmlHelper.DecodeString, cancellationToken); } [CreateSyncVersion] @@ -58,7 +62,7 @@ internal static async Task CreateAsync(Stream stream, IMiniExcelC { cancellationToken.ThrowIfCancellationRequested(); - if (!ReferenceHelper.ParseReference(startCell, out var startColumnIndex, out var startRowIndex)) + if (!CellReferenceConverter.TryParseCellReference(startCell, out var startColumnIndex, out var startRowIndex)) throw new InvalidDataException($"Value {startCell} is not a valid cell reference."); // convert to 0-based @@ -70,7 +74,7 @@ internal static async Task CreateAsync(Stream stream, IMiniExcelC int? endRowIndex = null; if (!string.IsNullOrWhiteSpace(endCell)) { - if (!ReferenceHelper.ParseReference(endCell, out int cIndex, out int rIndex)) + if (!CellReferenceConverter.TryParseCellReference(endCell, out int cIndex, out int rIndex)) throw new InvalidDataException($"Value {endCell} is not a valid cell reference."); // convert to 0-based @@ -84,7 +88,13 @@ internal static async Task CreateAsync(Stream stream, IMiniExcelC [CreateSyncVersion] public IAsyncEnumerable QueryRangeAsync(string? sheetName, string startCell, string endCell, bool treatHeaderAsData, CancellationToken cancellationToken = default) where T : class, new() { - return MiniExcelMapper.MapQueryAsync(QueryRangeAsync(false, sheetName, startCell, endCell, cancellationToken), startCell, treatHeaderAsData, _config.TrimColumnNames, _config, cancellationToken); + var query = QueryRangeAsync(false, sheetName, startCell, endCell, cancellationToken); + if (!CellReferenceConverter.TryParseCellReference(startCell, out _, out var rowOffset)) + { + throw new InvalidDataException($"Value {startCell} is not a valid cell reference."); + } + + return MiniExcelMapper.MapQueryAsync(query, rowOffset, treatHeaderAsData, _config.TrimColumnNames, _config, XmlHelper.DecodeString, cancellationToken); } [CreateSyncVersion] @@ -128,11 +138,12 @@ internal static async Task CreateAsync(Stream stream, IMiniExcelC [CreateSyncVersion] public IAsyncEnumerable QueryRangeAsync(string? sheetName, int startRowIndex, int startColumnIndex, int? endRowIndex, int? endColumnIndex, bool treatHeaderAsData, CancellationToken cancellationToken = default) where T : class, new() { - return MiniExcelMapper.MapQueryAsync(QueryRangeAsync(false, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, cancellationToken), ReferenceHelper.ConvertCoordinatesToCell(startColumnIndex, startRowIndex), treatHeaderAsData, _config.TrimColumnNames, _config, cancellationToken); + var query = QueryRangeAsync(false, sheetName, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, cancellationToken); + return MiniExcelMapper.MapQueryAsync(query, startRowIndex, treatHeaderAsData, _config.TrimColumnNames, _config, XmlHelper.DecodeString, cancellationToken); } [CreateSyncVersion] - internal async IAsyncEnumerable> InternalQueryRangeAsync(bool useHeaderRow, string? sheetName, int startRowIndex, int startColumnIndex, int? endRowIndex, int? endColumnIndex, [EnumeratorCancellation] CancellationToken cancellationToken = default) + private async IAsyncEnumerable> InternalQueryRangeAsync(bool useHeaderRow, string? sheetName, int startRowIndex, int startColumnIndex, int? endRowIndex, int? endColumnIndex, [EnumeratorCancellation] CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); @@ -384,7 +395,7 @@ private static void SetCellsValueAndHeaders(object? cellValue, bool useHeaderRow if (!useHeaderRow) { //if not using First Head then using A,B,C as index - cell[ColumnHelper.GetAlphabetColumnName(columnIndex)] = cellValue; + cell[CellReferenceConverter.GetAlphabeticalIndex(columnIndex)] = cellValue; return; } @@ -548,6 +559,7 @@ await reader.SkipAsync() .ConfigureAwait(false); var entry = entries.Single(w => w.FullName == "xl/_rels/workbook.xml.rels"); + #if NET10_0_OR_GREATER using var stream = await entry.OpenAsync(cancellationToken).ConfigureAwait(false); #else @@ -604,7 +616,7 @@ private async Task ReadCellAndSetColumnIndexAsync(XmlReader reade { newColumnIndex = columnIndex + 1; } - else if (ReferenceHelper.ParseReference(aR, out int referenceColumn, out _)) + else if (CellReferenceConverter.TryParseCellReference(aR, out int referenceColumn, out _)) { //TODO:need to check only need nextColumnIndex or columnIndex newColumnIndex = referenceColumn - 1; // ParseReference is 1-based @@ -767,7 +779,7 @@ internal async Task> GetDimensionsAsync(CancellationToken canc var r = reader.GetAttribute("r"); if (r is not null) { - if (ReferenceHelper.ParseReference(r, out var column, out var row)) + if (CellReferenceConverter.TryParseCellReference(r, out var column, out var row)) { column--; row--; @@ -789,7 +801,7 @@ internal async Task> GetDimensionsAsync(CancellationToken canc throw new InvalidDataException("No dimension data found for the sheet"); var rs = refAttr.Split(':'); - if (!ReferenceHelper.ParseReference(rs.Length == 2 ? rs[1] : rs[0], out var col, out var row)) + if (!CellReferenceConverter.TryParseCellReference(rs.Length == 2 ? rs[1] : rs[0], out var col, out var row)) throw new InvalidDataException("The dimensions of the sheet are invalid"); maxColumnIndex = col; @@ -921,7 +933,7 @@ internal static async Task TryGetMaxRowColumnIndexAs var r = reader.GetAttribute("r"); if (r is not null) { - if (ReferenceHelper.ParseReference(r, out var column, out var row)) + if (CellReferenceConverter.TryParseCellReference(r, out var column, out var row)) { column--; row--; @@ -945,7 +957,7 @@ internal static async Task TryGetMaxRowColumnIndexAs var rs = refAttr.Split(':'); // issue : https://github.com/mini-software/MiniExcel/issues/102 - if (!ReferenceHelper.ParseReference(rs.Length == 2 ? rs[1] : rs[0], out int cIndex, out int rIndex)) + if (!CellReferenceConverter.TryParseCellReference(rs.Length == 2 ? rs[1] : rs[0], out int cIndex, out int rIndex)) throw new InvalidDataException("The dimensions of the sheet are invalid"); maxRowIndex = rIndex - 1; @@ -1062,8 +1074,8 @@ internal static async Task TryGetMergeCellsAsync(ZipArchiveEntry sheetEntr if (refs.Length == 1) continue; - ReferenceHelper.ParseReference(refs[0], out var x1, out var y1); - ReferenceHelper.ParseReference(refs[1], out var x2, out var y2); + CellReferenceConverter.TryParseCellReference(refs[0], out var x1, out var y1); + CellReferenceConverter.TryParseCellReference(refs[1], out var x2, out var y2); mergeCells.MergesValues.Add(refs[0], null); @@ -1074,7 +1086,7 @@ internal static async Task TryGetMergeCellsAsync(ZipArchiveEntry sheetEntr for (int y = y1; y <= y2; y++) { if (!isFirst) - mergeCells.MergesMap.Add(ReferenceHelper.ConvertCoordinatesToCell(x, y), refs[0]); + mergeCells.MergesMap.Add(CellReferenceConverter.GetCellFromCoordinates(x, y), refs[0]); isFirst = false; } } @@ -1244,7 +1256,7 @@ public void Dispose() GC.SuppressFinalize(this); } - protected virtual void Dispose(bool disposing) + protected void Dispose(bool disposing) { if (!_disposed) { @@ -1259,4 +1271,4 @@ protected virtual void Dispose(bool disposing) _disposed = true; } } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/OpenXmlWriter.DefaultOpenXml.cs b/src/MiniExcel.OpenXml/OpenXmlWriter.DefaultOpenXml.cs similarity index 90% rename from src/MiniExcel.Core/OpenXml/OpenXmlWriter.DefaultOpenXml.cs rename to src/MiniExcel.OpenXml/OpenXmlWriter.DefaultOpenXml.cs index eb56f013..b6650bb8 100644 --- a/src/MiniExcel.Core/OpenXml/OpenXmlWriter.DefaultOpenXml.cs +++ b/src/MiniExcel.OpenXml/OpenXmlWriter.DefaultOpenXml.cs @@ -1,9 +1,7 @@ -using MiniExcelLib.Core.OpenXml.Constants; -using MiniExcelLib.Core.OpenXml.Models; -using MiniExcelLib.Core.OpenXml.Zip; +using MiniExcelLib.OpenXml.Constants; using static MiniExcelLib.Core.Helpers.ImageHelper; -namespace MiniExcelLib.Core.OpenXml; +namespace MiniExcelLib.OpenXml; internal partial class OpenXmlWriter : IMiniExcelWriter { @@ -104,7 +102,7 @@ private string GetPanes() WorksheetXml.StartPane( xSplit: _configuration.FreezeColumnCount > 0 ? _configuration.FreezeColumnCount : null, ySplit: _configuration.FreezeRowCount > 0 ? _configuration.FreezeRowCount : null, - topLeftCell: ReferenceHelper.ConvertCoordinatesToCell( + topLeftCell: CellReferenceConverter.GetCellFromCoordinates( _configuration.FreezeColumnCount + 1, _configuration.FreezeRowCount + 1 ), @@ -122,13 +120,13 @@ private string GetPanes() */ - var cellTr = ReferenceHelper.ConvertCoordinatesToCell(_configuration.FreezeColumnCount + 1, 1); + var cellTr = CellReferenceConverter.GetCellFromCoordinates(_configuration.FreezeColumnCount + 1, 1); sb.Append(WorksheetXml.PaneSelection("topRight", cellTr, cellTr)); - var cellBl = ReferenceHelper.ConvertCoordinatesToCell(1, _configuration.FreezeRowCount + 1); + var cellBl = CellReferenceConverter.GetCellFromCoordinates(1, _configuration.FreezeRowCount + 1); sb.Append(WorksheetXml.PaneSelection("bottomLeft", cellBl, cellBl)); - var cellBr = ReferenceHelper.ConvertCoordinatesToCell(_configuration.FreezeColumnCount + 1, _configuration.FreezeRowCount + 1); + var cellBr = CellReferenceConverter.GetCellFromCoordinates(_configuration.FreezeColumnCount + 1, _configuration.FreezeRowCount + 1); sb.Append(WorksheetXml.PaneSelection("bottomRight", cellBr, cellBr)); } else if (_configuration.FreezeColumnCount > 0) @@ -137,7 +135,7 @@ private string GetPanes() /* */ - var cellTr = ReferenceHelper.ConvertCoordinatesToCell(_configuration.FreezeColumnCount, 1); + var cellTr = CellReferenceConverter.GetCellFromCoordinates(_configuration.FreezeColumnCount, 1); sb.Append(WorksheetXml.PaneSelection("topRight", cellTr, cellTr)); } @@ -179,7 +177,7 @@ private Tuple GetCellValue(int rowIndex, int cellIndex, #endif if (type.IsEnum) { - var description = CustomPropertyHelper.DescriptionAttr(type, value); + var description = CustomPropertyHelper.GetDescriptionAttribute(type, value); return Tuple.Create("2", "str", description ?? value.ToString()); } @@ -333,8 +331,8 @@ private static string GetDimensionRef(int maxRowIndex, int maxColumnIndex) { (<= 1, 0) => "A1", (_, <= 1) => $"A1:A{maxRowIndex}", - (0, _) => $"A1:{ColumnHelper.GetAlphabetColumnName(maxColumnIndex - 1)}1", - _ => $"A1:{ColumnHelper.GetAlphabetColumnName(maxColumnIndex - 1)}{maxRowIndex}" + (0, _) => $"A1:{CellReferenceConverter.GetAlphabeticalIndex(maxColumnIndex - 1)}1", + _ => $"A1:{CellReferenceConverter.GetAlphabeticalIndex(maxColumnIndex - 1)}{maxRowIndex}" }; } diff --git a/src/MiniExcel.Core/OpenXml/OpenXmlWriter.cs b/src/MiniExcel.OpenXml/OpenXmlWriter.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/OpenXmlWriter.cs rename to src/MiniExcel.OpenXml/OpenXmlWriter.cs index a487a870..c15b896c 100644 --- a/src/MiniExcel.Core/OpenXml/OpenXmlWriter.cs +++ b/src/MiniExcel.OpenXml/OpenXmlWriter.cs @@ -1,12 +1,11 @@ -using MiniExcelLib.Core.OpenXml.Constants; -using MiniExcelLib.Core.OpenXml.Models; -using MiniExcelLib.Core.OpenXml.Styles.Builder; -using MiniExcelLib.Core.OpenXml.Zip; -using MiniExcelLib.Core.WriteAdapters; using System.ComponentModel; using System.Xml.Linq; +using MiniExcelLib.Core; +using MiniExcelLib.Core.WriteAdapters; +using MiniExcelLib.OpenXml.Constants; +using MiniExcelLib.OpenXml.Styles.Builder; -namespace MiniExcelLib.Core.OpenXml; +namespace MiniExcelLib.OpenXml; internal partial class OpenXmlWriter : IMiniExcelWriter { @@ -24,7 +23,7 @@ internal partial class OpenXmlWriter : IMiniExcelWriter private int _currentSheetIndex = 0; - internal OpenXmlWriter(Stream stream, object? value, string? sheetName, IMiniExcelConfiguration? configuration, bool printHeader) + private OpenXmlWriter(Stream stream, object? value, string? sheetName, IMiniExcelConfiguration? configuration, bool printHeader) { _stream = stream; @@ -189,7 +188,7 @@ private async Task CreateSheetXmlAsync(object? values, string sheetPath, IP #else using var zipStream = entry.Open(); #endif - using var writer = new SafeStreamWriter(zipStream, Utf8WithBom, _configuration.BufferSize); + using var writer = new EnhancedStreamWriter(zipStream, Utf8WithBom, _configuration.BufferSize); if (values is null) { @@ -205,13 +204,13 @@ private async Task CreateSheetXmlAsync(object? values, string sheetPath, IP } [CreateSyncVersion] - private static async Task WriteEmptySheetAsync(SafeStreamWriter writer) + private static async Task WriteEmptySheetAsync(EnhancedStreamWriter writer) { await writer.WriteAsync(ExcelXml.EmptySheetXml).ConfigureAwait(false); } [CreateSyncVersion] - private static async Task WriteDimensionPlaceholderAsync(SafeStreamWriter writer) + private static async Task WriteDimensionPlaceholderAsync(EnhancedStreamWriter writer) { var dimensionPlaceholderPostition = await writer.WriteAndFlushAsync(WorksheetXml.StartDimension).ConfigureAwait(false); await writer.WriteAsync(WorksheetXml.DimensionPlaceholder).ConfigureAwait(false); // end of code will be replaced @@ -220,7 +219,7 @@ private static async Task WriteDimensionPlaceholderAsync(SafeStreamWriter } [CreateSyncVersion] - private static async Task WriteDimensionAsync(SafeStreamWriter writer, int maxRowIndex, int maxColumnIndex, long placeholderPosition) + private static async Task WriteDimensionAsync(EnhancedStreamWriter writer, int maxRowIndex, int maxColumnIndex, long placeholderPosition) { // Flush and save position so that we can get back again. var position = await writer.FlushAsync().ConfigureAwait(false); @@ -232,7 +231,7 @@ private static async Task WriteDimensionAsync(SafeStreamWriter writer, int maxRo } [CreateSyncVersion] - private async Task WriteValuesAsync(SafeStreamWriter writer, object values, CancellationToken cancellationToken, IProgress? progress = null) + private async Task WriteValuesAsync(EnhancedStreamWriter writer, object values, CancellationToken cancellationToken, IProgress? progress = null) { cancellationToken.ThrowIfCancellationRequested(); @@ -247,7 +246,7 @@ private async Task WriteValuesAsync(SafeStreamWriter writer, object values, var isKnownCount = writeAdapter is not null && writeAdapter.TryGetKnownCount(out count); #if SYNC_ONLY - var props = writeAdapter?.GetColumns(); + var props = writeAdapter?.GetColumns(); #else var props = writeAdapter is not null ? writeAdapter.GetColumns() @@ -374,7 +373,7 @@ private async Task WriteValuesAsync(SafeStreamWriter writer, object values, } [CreateSyncVersion] - private static async Task WriteColumnWidthPlaceholdersAsync(SafeStreamWriter writer, int count, CancellationToken cancellationToken = default) + private static async Task WriteColumnWidthPlaceholdersAsync(EnhancedStreamWriter writer, int count, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); @@ -384,7 +383,7 @@ private static async Task WriteColumnWidthPlaceholdersAsync(SafeStreamWrit } [CreateSyncVersion] - private static async Task OverwriteColumnWidthPlaceholdersAsync(SafeStreamWriter writer, long placeholderPosition, IEnumerable? columnWidths, CancellationToken cancellationToken = default) + private static async Task OverwriteColumnWidthPlaceholdersAsync(EnhancedStreamWriter writer, long placeholderPosition, IEnumerable? columnWidths, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); @@ -398,7 +397,7 @@ private static async Task OverwriteColumnWidthPlaceholdersAsync(SafeStreamWriter } [CreateSyncVersion] - private static async Task WriteColumnsWidthsAsync(SafeStreamWriter writer, IEnumerable? columnWidths, CancellationToken cancellationToken = default) + private static async Task WriteColumnsWidthsAsync(EnhancedStreamWriter writer, IEnumerable? columnWidths, CancellationToken cancellationToken = default) { var hasWrittenStart = false; @@ -422,7 +421,7 @@ private static async Task WriteColumnsWidthsAsync(SafeStreamWriter writer, IEnum } [CreateSyncVersion] - private async Task PrintHeaderAsync(SafeStreamWriter writer, List props, CancellationToken cancellationToken = default) + private async Task PrintHeaderAsync(EnhancedStreamWriter writer, List props, CancellationToken cancellationToken = default) { const int yIndex = 1; await writer.WriteAsync(WorksheetXml.StartRow(yIndex), cancellationToken).ConfigureAwait(false); @@ -436,7 +435,7 @@ private async Task PrintHeaderAsync(SafeStreamWriter writer, List ReferenceHelper.ConvertCellToCoordinates(CellAddress).Item1 -1; - internal int RowNumber => ReferenceHelper.ConvertCellToCoordinates(CellAddress).Item2 - 1; + internal int ColumnNumber => CellReferenceConverter.TryParseCellReference(CellAddress, out var column, out _) + ? column - 1 + : throw new InvalidDataException($"Value {CellAddress} is not a valid cell reference."); + + internal int RowNumber => CellReferenceConverter.TryParseCellReference(CellAddress, out var _, out var row) + ? row - 1 + : throw new InvalidDataException($"Value {CellAddress} is not a valid cell reference."); + public int WidthPx { get; set; } = 80; public int HeightPx { get; set; } = 24; diff --git a/src/MiniExcel.Core/OpenXml/Picture/OpenXmlPictureImplement.cs b/src/MiniExcel.OpenXml/Picture/OpenXmlPictureImplement.cs similarity index 97% rename from src/MiniExcel.Core/OpenXml/Picture/OpenXmlPictureImplement.cs rename to src/MiniExcel.OpenXml/Picture/OpenXmlPictureImplement.cs index 8e9d9859..3ce90e38 100644 --- a/src/MiniExcel.Core/OpenXml/Picture/OpenXmlPictureImplement.cs +++ b/src/MiniExcel.OpenXml/Picture/OpenXmlPictureImplement.cs @@ -1,8 +1,7 @@ using System.Drawing; using MiniExcelLib.Core.Enums; -using MiniExcelLib.Core.OpenXml.Zip; -namespace MiniExcelLib.Core.OpenXml.Picture; +namespace MiniExcelLib.OpenXml.Picture; internal static partial class MiniExcelPictureImplement { diff --git a/src/MiniExcel.Core/OpenXml/Styles/Builder/DefaultSheetStyleBuilder.cs b/src/MiniExcel.OpenXml/Styles/Builder/DefaultSheetStyleBuilder.cs similarity index 98% rename from src/MiniExcel.Core/OpenXml/Styles/Builder/DefaultSheetStyleBuilder.cs rename to src/MiniExcel.OpenXml/Styles/Builder/DefaultSheetStyleBuilder.cs index 8a5e67df..4216a8d9 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/Builder/DefaultSheetStyleBuilder.cs +++ b/src/MiniExcel.OpenXml/Styles/Builder/DefaultSheetStyleBuilder.cs @@ -1,7 +1,7 @@ using System.Drawing; using MiniExcelLib.Core.Enums; -namespace MiniExcelLib.Core.OpenXml.Styles.Builder; +namespace MiniExcelLib.OpenXml.Styles.Builder; internal partial class DefaultSheetStyleBuilder(SheetStyleBuildContext context, OpenXmlStyleOptions styleOptions) : SheetStyleBuilderBase(context) diff --git a/src/MiniExcel.Core/OpenXml/Styles/Builder/ISheetStyleBuilder.cs b/src/MiniExcel.OpenXml/Styles/Builder/ISheetStyleBuilder.cs similarity index 73% rename from src/MiniExcel.Core/OpenXml/Styles/Builder/ISheetStyleBuilder.cs rename to src/MiniExcel.OpenXml/Styles/Builder/ISheetStyleBuilder.cs index 7e8685a6..b7423b25 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/Builder/ISheetStyleBuilder.cs +++ b/src/MiniExcel.OpenXml/Styles/Builder/ISheetStyleBuilder.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Styles.Builder; +namespace MiniExcelLib.OpenXml.Styles.Builder; internal partial interface ISheetStyleBuilder { diff --git a/src/MiniExcel.Core/OpenXml/Styles/Builder/MinimalSheetStyleBuilder.cs b/src/MiniExcel.OpenXml/Styles/Builder/MinimalSheetStyleBuilder.cs similarity index 96% rename from src/MiniExcel.Core/OpenXml/Styles/Builder/MinimalSheetStyleBuilder.cs rename to src/MiniExcel.OpenXml/Styles/Builder/MinimalSheetStyleBuilder.cs index 929dd03d..c4811cb5 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/Builder/MinimalSheetStyleBuilder.cs +++ b/src/MiniExcel.OpenXml/Styles/Builder/MinimalSheetStyleBuilder.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Styles.Builder; +namespace MiniExcelLib.OpenXml.Styles.Builder; internal partial class MinimalSheetStyleBuilder(SheetStyleBuildContext context) : SheetStyleBuilderBase(context) { diff --git a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuildContext.cs b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuildContext.cs similarity index 96% rename from src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuildContext.cs rename to src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuildContext.cs index ec1b2772..7b1cea3d 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuildContext.cs +++ b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuildContext.cs @@ -1,8 +1,7 @@ using MiniExcelLib.Core.Attributes; -using MiniExcelLib.Core.OpenXml.Constants; -using MiniExcelLib.Core.OpenXml.Zip; +using MiniExcelLib.OpenXml.Constants; -namespace MiniExcelLib.Core.OpenXml.Styles.Builder; +namespace MiniExcelLib.OpenXml.Styles.Builder; internal class SheetStyleBuildContext : IDisposable { diff --git a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuildResult.cs b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuildResult.cs similarity index 72% rename from src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuildResult.cs rename to src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuildResult.cs index 47b63da7..53a504d4 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuildResult.cs +++ b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuildResult.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Styles.Builder; +namespace MiniExcelLib.OpenXml.Styles.Builder; internal class SheetStyleBuildResult(Dictionary cellXfIdMap) { diff --git a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuilderBase.cs b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuilderBase.cs similarity index 97% rename from src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuilderBase.cs rename to src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuilderBase.cs index 33f0b15f..5440893c 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuilderBase.cs +++ b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuilderBase.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Styles.Builder; +namespace MiniExcelLib.OpenXml.Styles.Builder; internal abstract partial class SheetStyleBuilderBase(SheetStyleBuildContext context) : ISheetStyleBuilder { diff --git a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuilderHelper.cs b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuilderHelper.cs similarity index 70% rename from src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuilderHelper.cs rename to src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuilderHelper.cs index 5249ac59..7bacddd6 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/Builder/SheetStyleBuilderHelper.cs +++ b/src/MiniExcel.OpenXml/Styles/Builder/SheetStyleBuilderHelper.cs @@ -1,6 +1,6 @@ using MiniExcelLib.Core.Attributes; -namespace MiniExcelLib.Core.OpenXml.Styles.Builder; +namespace MiniExcelLib.OpenXml.Styles.Builder; public static class SheetStyleBuilderHelper { @@ -14,14 +14,14 @@ public static IEnumerable GenerateStyleIds(int startUp .Where(x => !string.IsNullOrWhiteSpace(x.Format) && new OpenXmlNumberFormatHelper(x.Format).IsValid) .GroupBy(x => x.Format); - foreach (var g in cols) + foreach (var group in cols) { - foreach (var col in g) + foreach (var col in group) { - col.FormatId = startUpCellXfs + index; + col.SetFormatId(startUpCellXfs + index); } - yield return g.First(); + yield return group.First(); index++; } } diff --git a/src/MiniExcel.Core/OpenXml/Styles/OpenXmlHeaderStyle.cs b/src/MiniExcel.OpenXml/Styles/OpenXmlHeaderStyle.cs similarity index 91% rename from src/MiniExcel.Core/OpenXml/Styles/OpenXmlHeaderStyle.cs rename to src/MiniExcel.OpenXml/Styles/OpenXmlHeaderStyle.cs index ef75a92e..3f0b14b3 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/OpenXmlHeaderStyle.cs +++ b/src/MiniExcel.OpenXml/Styles/OpenXmlHeaderStyle.cs @@ -1,7 +1,7 @@ using System.Drawing; using MiniExcelLib.Core.Enums; -namespace MiniExcelLib.Core.OpenXml.Styles; +namespace MiniExcelLib.OpenXml.Styles; public class OpenXmlHeaderStyle { diff --git a/src/MiniExcel.Core/OpenXml/Styles/OpenXmlStyleOptions.cs b/src/MiniExcel.OpenXml/Styles/OpenXmlStyleOptions.cs similarity index 73% rename from src/MiniExcel.Core/OpenXml/Styles/OpenXmlStyleOptions.cs rename to src/MiniExcel.OpenXml/Styles/OpenXmlStyleOptions.cs index 06afe430..1b3d048b 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/OpenXmlStyleOptions.cs +++ b/src/MiniExcel.OpenXml/Styles/OpenXmlStyleOptions.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Styles; +namespace MiniExcelLib.OpenXml.Styles; public class OpenXmlStyleOptions { diff --git a/src/MiniExcel.Core/OpenXml/Styles/OpenXmlStyles.cs b/src/MiniExcel.OpenXml/Styles/OpenXmlStyles.cs similarity index 95% rename from src/MiniExcel.Core/OpenXml/Styles/OpenXmlStyles.cs rename to src/MiniExcel.OpenXml/Styles/OpenXmlStyles.cs index dcf39cb2..760b29a7 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/OpenXmlStyles.cs +++ b/src/MiniExcel.OpenXml/Styles/OpenXmlStyles.cs @@ -1,8 +1,7 @@ -using MiniExcelLib.Core.OpenXml.Constants; -using MiniExcelLib.Core.OpenXml.Zip; -using XmlReaderHelper = MiniExcelLib.Core.OpenXml.Utils.XmlReaderHelper; +using MiniExcelLib.OpenXml.Constants; +using XmlReaderHelper = MiniExcelLib.OpenXml.Utils.XmlReaderHelper; -namespace MiniExcelLib.Core.OpenXml.Styles; +namespace MiniExcelLib.OpenXml.Styles; internal class OpenXmlStyles { diff --git a/src/MiniExcel.Core/OpenXml/Styles/SheetStyleElementInfos.cs b/src/MiniExcel.OpenXml/Styles/SheetStyleElementInfos.cs similarity index 89% rename from src/MiniExcel.Core/OpenXml/Styles/SheetStyleElementInfos.cs rename to src/MiniExcel.OpenXml/Styles/SheetStyleElementInfos.cs index 3ab807e8..db6bc188 100644 --- a/src/MiniExcel.Core/OpenXml/Styles/SheetStyleElementInfos.cs +++ b/src/MiniExcel.OpenXml/Styles/SheetStyleElementInfos.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Styles; +namespace MiniExcelLib.OpenXml.Styles; public class SheetStyleElementInfos { diff --git a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.Impl.cs b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs similarity index 95% rename from src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.Impl.cs rename to src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs index b73e6760..96f2899d 100644 --- a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.Impl.cs +++ b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.Impl.cs @@ -1,7 +1,7 @@ using MiniExcelLib.Core.Attributes; -using MiniExcelLib.Core.OpenXml.Constants; +using MiniExcelLib.OpenXml.Constants; -namespace MiniExcelLib.Core.OpenXml.Templates; +namespace MiniExcelLib.OpenXml.Templates; #region Utils internal class XRowInfo @@ -57,11 +57,11 @@ public XMergeCell(XmlElement mergeCell) //TODO: width,height var xy1 = refs[0]; - X1 = ColumnHelper.GetColumnIndex(StringHelper.GetLetters(refs[0])); + X1 = CellReferenceConverter.GetNumericalIndex(StringHelper.GetLetters(refs[0])); Y1 = StringHelper.GetNumber(xy1); var xy2 = refs[1]; - X2 = ColumnHelper.GetColumnIndex(StringHelper.GetLetters(refs[1])); + X2 = CellReferenceConverter.GetNumericalIndex(StringHelper.GetLetters(refs[1])); Y2 = StringHelper.GetNumber(xy2); Width = Math.Abs(X1 - X2) + 1; @@ -69,29 +69,29 @@ public XMergeCell(XmlElement mergeCell) } public XMergeCell(string x1, int y1, string x2, int y2) { - X1 = ColumnHelper.GetColumnIndex(x1); + X1 = CellReferenceConverter.GetNumericalIndex(x1); Y1 = y1; - X2 = ColumnHelper.GetColumnIndex(x2); + X2 = CellReferenceConverter.GetNumericalIndex(x2); Y2 = y2; Width = Math.Abs(X1 - X2) + 1; Height = Math.Abs(Y1 - Y2) + 1; } - public string XY1 => $"{ColumnHelper.GetAlphabetColumnName(X1)}{Y1}"; + public string XY1 => $"{CellReferenceConverter.GetAlphabeticalIndex(X1)}{Y1}"; public int X1 { get; set; } public int Y1 { get; set; } - public string XY2 => $"{ColumnHelper.GetAlphabetColumnName(X2)}{Y2}"; + public string XY2 => $"{CellReferenceConverter.GetAlphabeticalIndex(X2)}{Y2}"; public int X2 { get; set; } public int Y2 { get; set; } - public string Ref => $"{ColumnHelper.GetAlphabetColumnName(X1)}{Y1}:{ColumnHelper.GetAlphabetColumnName(X2)}{Y2}"; + public string Ref => $"{CellReferenceConverter.GetAlphabeticalIndex(X1)}{Y1}:{CellReferenceConverter.GetAlphabeticalIndex(X2)}{Y2}"; public XmlElement MergeCell { get; set; } public int Width { get; internal set; } public int Height { get; internal set; } public string ToXmlString(string prefix) - => $"<{prefix}mergeCell ref=\"{ColumnHelper.GetAlphabetColumnName(X1)}{Y1}:{ColumnHelper.GetAlphabetColumnName(X2)}{Y2}\"/>"; + => $"<{prefix}mergeCell ref=\"{CellReferenceConverter.GetAlphabeticalIndex(X1)}{Y1}:{CellReferenceConverter.GetAlphabeticalIndex(X2)}{Y2}\"/>"; } internal class MergeCellIndex(int rowStart, int rowEnd) @@ -237,7 +237,7 @@ private static IEnumerable ParseConditionalFormatRanges( continue; var row = int.Parse(match.Groups[2].Value); - var column = ColumnHelper.GetColumnIndex(match.Groups[1].Value); + var column = CellReferenceConverter.GetNumericalIndex(match.Groups[1].Value); rangeList.Add(new Range { StartColumn = column, @@ -254,9 +254,9 @@ private static IEnumerable ParseConditionalFormatRanges( { rangeList.Add(new Range { - StartColumn = ColumnHelper.GetColumnIndex(match1.Groups[1].Value), + StartColumn = CellReferenceConverter.GetNumericalIndex(match1.Groups[1].Value), StartRow = int.Parse(match1.Groups[2].Value), - EndColumn = ColumnHelper.GetColumnIndex(match2.Groups[1].Value), + EndColumn = CellReferenceConverter.GetNumericalIndex(match2.Groups[1].Value), EndRow = int.Parse(match2.Groups[2].Value) }); } @@ -486,7 +486,7 @@ await writer.WriteAsync($"<{prefix}sheetData>" }) .ToList(); - sqref.Value = string.Join(" ", ranges.Select(r => $"{ColumnHelper.GetAlphabetColumnName(r.StartColumn)}{r.StartRow}:{ColumnHelper.GetAlphabetColumnName(r.EndColumn)}{r.EndRow}")); + sqref.Value = string.Join(" ", ranges.Select(r => $"{CellReferenceConverter.GetAlphabeticalIndex(r.StartColumn)}{r.StartRow}:{CellReferenceConverter.GetAlphabeticalIndex(r.EndColumn)}{r.EndRow}")); newConditionalFormatRanges.Remove(conditionalFormat); newConditionalFormatRanges.Add(new ConditionalFormatRange { @@ -776,7 +776,7 @@ private async Task GenerateCellValuesAsync(GenerateCe } else if (type?.IsEnum ?? false) { - var description = CustomPropertyHelper.DescriptionAttr(type, cellValue); + var description = CustomPropertyHelper.GetDescriptionAttribute(type, cellValue); cellValueStr = XmlHelper.EncodeXml(description); } else @@ -1062,7 +1062,7 @@ private void ProcessFormulas(StringBuilder rowXml, int rowIndex) c.InsertBefore(fNode, v); c.RemoveChild(v); - var celRef = ReferenceHelper.ConvertCoordinatesToCell(ci + 1, rowIndex); + var celRef = CellReferenceConverter.GetCellFromCoordinates(ci + 1, rowIndex); _calcChainCellRefs.Add(celRef); } } diff --git a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.MergeCells.cs b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.MergeCells.cs similarity index 90% rename from src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.MergeCells.cs rename to src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.MergeCells.cs index ab990744..d5c74385 100644 --- a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.MergeCells.cs +++ b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.MergeCells.cs @@ -1,6 +1,4 @@ -using MiniExcelLib.Core.OpenXml.Zip; - -namespace MiniExcelLib.Core.OpenXml.Templates; +namespace MiniExcelLib.OpenXml.Templates; internal partial class OpenXmlTemplate { @@ -27,7 +25,7 @@ await stream.CopyToAsync(_outputFileStream #endif ).ConfigureAwait(false); - using var reader = await OpenXmlReader.CreateAsync(_outputFileStream, null, cancellationToken: cancellationToken).ConfigureAwait(false); + using var reader = await MiniExcelLib.OpenXml.OpenXmlReader.CreateAsync(_outputFileStream, null, cancellationToken: cancellationToken).ConfigureAwait(false); using var archive = new OpenXmlZip(_outputFileStream, mode: ZipArchiveMode.Update, true, Encoding.UTF8); //read sharedString diff --git a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.cs b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.cs similarity index 92% rename from src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.cs rename to src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.cs index ef77cdfd..fd48d178 100644 --- a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlTemplate.cs +++ b/src/MiniExcel.OpenXml/Templates/OpenXmlTemplate.cs @@ -1,7 +1,8 @@ -using MiniExcelLib.Core.OpenXml.Constants; -using MiniExcelLib.Core.OpenXml.Zip; +using MiniExcelLib.Core; +using MiniExcelLib.OpenXml.Constants; +using CalcChainHelper = MiniExcelLib.OpenXml.Utils.CalcChainHelper; -namespace MiniExcelLib.Core.OpenXml.Templates; +namespace MiniExcelLib.OpenXml.Templates; internal partial class OpenXmlTemplate : IMiniExcelTemplate { @@ -53,7 +54,7 @@ public async Task SaveAsByTemplateAsync(Stream templateStream, object value, Can throw new ArgumentException("The template stream must be seekable"); templateStream.Seek(0, SeekOrigin.Begin); - using var templateReader = await OpenXmlReader.CreateAsync(templateStream, null, cancellationToken: cancellationToken).ConfigureAwait(false); + using var templateReader = await MiniExcelLib.OpenXml.OpenXmlReader.CreateAsync(templateStream, null, cancellationToken: cancellationToken).ConfigureAwait(false); using var outputFileArchive = new OpenXmlZip(_outputFileStream, mode: ZipArchiveMode.Create, true, Encoding.UTF8, isUpdateMode: false); try @@ -112,8 +113,8 @@ await originalEntryStream.CopyToAsync(newEntryStream templateStream.Position = 0; //read all xlsx sheets - var templateSheets = templateReader.Archive.ZipFile.Entries - .Where(w => + var templateSheets = Enumerable + .Where(templateReader.Archive.ZipFile.Entries, w => w.FullName.StartsWith("xl/worksheets/sheet", StringComparison.OrdinalIgnoreCase) || w.FullName.StartsWith("/xl/worksheets/sheet", StringComparison.OrdinalIgnoreCase)); diff --git a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlValueExtractor.cs b/src/MiniExcel.OpenXml/Templates/OpenXmlValueExtractor.cs similarity index 88% rename from src/MiniExcel.Core/OpenXml/Templates/OpenXmlValueExtractor.cs rename to src/MiniExcel.OpenXml/Templates/OpenXmlValueExtractor.cs index c2df7ce1..421762a2 100644 --- a/src/MiniExcel.Core/OpenXml/Templates/OpenXmlValueExtractor.cs +++ b/src/MiniExcel.OpenXml/Templates/OpenXmlValueExtractor.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Templates; +namespace MiniExcelLib.OpenXml.Templates; public class OpenXmlValueExtractor : IInputValueExtractor { @@ -12,7 +12,7 @@ public class OpenXmlValueExtractor : IInputValueExtractor return valueDictionary.ToDictionary( x => x.Key, x => x.Value is IDataReader dataReader - ? TypeHelper.ConvertToEnumerableDictionary(dataReader).ToList() + ? dataReader.ToEnumerableDictionaries().ToList() : x.Value)!; } diff --git a/src/MiniExcel.Core/OpenXml/Utils/CalcChainHelper.cs b/src/MiniExcel.OpenXml/Utils/CalcChainHelper.cs similarity index 95% rename from src/MiniExcel.Core/OpenXml/Utils/CalcChainHelper.cs rename to src/MiniExcel.OpenXml/Utils/CalcChainHelper.cs index c2bae0ce..42d93e11 100644 --- a/src/MiniExcel.Core/OpenXml/Utils/CalcChainHelper.cs +++ b/src/MiniExcel.OpenXml/Utils/CalcChainHelper.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Utils; +namespace MiniExcelLib.OpenXml.Utils; internal static partial class CalcChainHelper { @@ -30,4 +30,4 @@ await writer.WriteAsync($""" /// NumberFormat from NuGet ExcelNumberFormat MIT@License @@ -10,8 +10,7 @@ public static class DateTimeHelper /**Below Code from ExcelDataReader @MIT License**/ // All OA dates must be strictly in between OADateMinAsDouble and OADateMaxAsDouble private const double OADateMinAsDouble = -657435.0; - private const double OADateMaxAsDouble = 2958466.0; internal static bool IsValidOADateTime(double value) => value is > OADateMinAsDouble and < OADateMaxAsDouble; -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/Utils/MiniExcelPropertyHelper.cs b/src/MiniExcel.OpenXml/Utils/MiniExcelPropertyHelper.cs similarity index 86% rename from src/MiniExcel.Core/OpenXml/Utils/MiniExcelPropertyHelper.cs rename to src/MiniExcel.OpenXml/Utils/MiniExcelPropertyHelper.cs index 0e153d97..b9766a72 100644 --- a/src/MiniExcel.Core/OpenXml/Utils/MiniExcelPropertyHelper.cs +++ b/src/MiniExcel.OpenXml/Utils/MiniExcelPropertyHelper.cs @@ -1,9 +1,8 @@ -using MiniExcelLib.Core.Attributes; -using MiniExcelLib.Core.OpenXml.Models; +using MiniExcelLib.Core; -namespace MiniExcelLib.Core.OpenXml.Utils; +namespace MiniExcelLib.OpenXml.Utils; -internal static class ExcelPropertyHelper +internal static class MiniExcelPropertyHelper { internal static ExcellSheetInfo GetExcellSheetInfo(Type type, MiniExcelBaseConfiguration configuration) { @@ -36,4 +35,4 @@ internal static ExcellSheetInfo GetExcellSheetInfo(Type type, MiniExcelBaseConfi return sheetInfo; } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/Utils/OpenXmlNumberFormatHelper.cs b/src/MiniExcel.OpenXml/Utils/OpenXmlNumberFormatHelper.cs similarity index 96% rename from src/MiniExcel.Core/OpenXml/Utils/OpenXmlNumberFormatHelper.cs rename to src/MiniExcel.OpenXml/Utils/OpenXmlNumberFormatHelper.cs index 813067bc..aa65d8e0 100644 --- a/src/MiniExcel.Core/OpenXml/Utils/OpenXmlNumberFormatHelper.cs +++ b/src/MiniExcel.OpenXml/Utils/OpenXmlNumberFormatHelper.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Utils; +namespace MiniExcelLib.OpenXml.Utils; /// /// This code edit from https://github.com/andersnm/ExcelNumberFormat @@ -1006,4 +1006,4 @@ public static bool IsDigit09(string token) "1" or "2" or "3" or "4" or "5" or "6" or "7" or "8" or "9" => true, _ => false }; -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/Utils/SharedStringsDiskCache.cs b/src/MiniExcel.OpenXml/Utils/SharedStringsDiskCache.cs similarity index 95% rename from src/MiniExcel.Core/OpenXml/Utils/SharedStringsDiskCache.cs rename to src/MiniExcel.OpenXml/Utils/SharedStringsDiskCache.cs index bbc113bd..0aca3bf3 100644 --- a/src/MiniExcel.Core/OpenXml/Utils/SharedStringsDiskCache.cs +++ b/src/MiniExcel.OpenXml/Utils/SharedStringsDiskCache.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Utils; +namespace MiniExcelLib.OpenXml.Utils; internal class SharedStringsDiskCache : IDictionary, IDisposable { @@ -158,4 +158,4 @@ protected virtual void Dispose(bool disposing) _disposedValue = true; } } -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/Utils/XmlReaderHelper.cs b/src/MiniExcel.OpenXml/Utils/XmlReaderHelper.cs similarity index 95% rename from src/MiniExcel.Core/OpenXml/Utils/XmlReaderHelper.cs rename to src/MiniExcel.OpenXml/Utils/XmlReaderHelper.cs index e65e60ed..da4a4e00 100644 --- a/src/MiniExcel.Core/OpenXml/Utils/XmlReaderHelper.cs +++ b/src/MiniExcel.OpenXml/Utils/XmlReaderHelper.cs @@ -1,6 +1,6 @@ -using MiniExcelLib.Core.OpenXml.Constants; +using MiniExcelLib.OpenXml.Constants; -namespace MiniExcelLib.Core.OpenXml.Utils; +namespace MiniExcelLib.OpenXml.Utils; internal static partial class XmlReaderHelper { @@ -201,4 +201,4 @@ private static async Task ReadRichTextRunAsync(XmlReader reader, Cancell XmlResolver = null, Async = async, }; -} \ No newline at end of file +} diff --git a/src/MiniExcel.Core/OpenXml/Zip/MiniExcelZipArchive.cs b/src/MiniExcel.OpenXml/Zip/MiniExcelZipArchive.cs similarity index 85% rename from src/MiniExcel.Core/OpenXml/Zip/MiniExcelZipArchive.cs rename to src/MiniExcel.OpenXml/Zip/MiniExcelZipArchive.cs index 9df07bdc..069e49d7 100644 --- a/src/MiniExcel.Core/OpenXml/Zip/MiniExcelZipArchive.cs +++ b/src/MiniExcel.OpenXml/Zip/MiniExcelZipArchive.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Zip; +namespace MiniExcelLib.OpenXml.Zip; public class MiniExcelZipArchive(Stream stream, ZipArchiveMode mode, bool leaveOpen, Encoding entryNameEncoding) : ZipArchive(stream, mode, leaveOpen, entryNameEncoding) diff --git a/src/MiniExcel.Core/OpenXml/Zip/OpenXmlZip.cs b/src/MiniExcel.OpenXml/Zip/OpenXmlZip.cs similarity index 94% rename from src/MiniExcel.Core/OpenXml/Zip/OpenXmlZip.cs rename to src/MiniExcel.OpenXml/Zip/OpenXmlZip.cs index abc594fd..b85daad3 100644 --- a/src/MiniExcel.Core/OpenXml/Zip/OpenXmlZip.cs +++ b/src/MiniExcel.OpenXml/Zip/OpenXmlZip.cs @@ -1,6 +1,6 @@ using System.Collections.ObjectModel; -namespace MiniExcelLib.Core.OpenXml.Zip; +namespace MiniExcelLib.OpenXml.Zip; /// Copy & modified by ExcelDataReader ZipWorker @MIT License internal class OpenXmlZip : IDisposable diff --git a/src/MiniExcel.Core/OpenXml/Zip/ZipPackageInfo.cs b/src/MiniExcel.OpenXml/Zip/ZipPackageInfo.cs similarity index 82% rename from src/MiniExcel.Core/OpenXml/Zip/ZipPackageInfo.cs rename to src/MiniExcel.OpenXml/Zip/ZipPackageInfo.cs index 4cee1d50..f8ca652a 100644 --- a/src/MiniExcel.Core/OpenXml/Zip/ZipPackageInfo.cs +++ b/src/MiniExcel.OpenXml/Zip/ZipPackageInfo.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Core.OpenXml.Zip; +namespace MiniExcelLib.OpenXml.Zip; internal class ZipPackageInfo(ZipArchiveEntry zipArchiveEntry, string contentType) { diff --git a/src/MiniExcel/Attributes.cs b/src/MiniExcel/Attributes.cs index 058f6464..6dc24a20 100644 --- a/src/MiniExcel/Attributes.cs +++ b/src/MiniExcel/Attributes.cs @@ -1,4 +1,5 @@ using MiniExcelLib.Core.Attributes; +using MiniExcelLib.OpenXml; // ReSharper disable CheckNamespace namespace MiniExcelLibs.Attributes; @@ -22,4 +23,4 @@ public sealed class ExcelIgnoreAttribute(bool excelIgnore = true) : MiniExcelIgn public sealed class ExcelSheetAttribute : MiniExcelSheetAttribute; -public sealed class DynamicExcelSheetAttribute(string key) : MiniExcelLib.Core.Attributes.DynamicExcelSheetAttribute(key); \ No newline at end of file +public sealed class DynamicExcelSheetAttribute(string key) : MiniExcelLib.OpenXml.DynamicExcelSheetAttribute(key); diff --git a/src/MiniExcel/Configuration.cs b/src/MiniExcel/Configuration.cs index 3d8c396a..88028e39 100644 --- a/src/MiniExcel/Configuration.cs +++ b/src/MiniExcel/Configuration.cs @@ -1,6 +1,5 @@ using MiniExcelLib.Core; - namespace MiniExcelLibs { public interface IConfiguration : IMiniExcelConfiguration; @@ -8,7 +7,7 @@ public interface IConfiguration : IMiniExcelConfiguration; namespace MiniExcelLibs.OpenXml { - public sealed class OpenXmlConfiguration : MiniExcelLib.Core.OpenXml.OpenXmlConfiguration, IConfiguration; + public sealed class OpenXmlConfiguration : MiniExcelLib.OpenXml.OpenXmlConfiguration, IConfiguration; } namespace MiniExcelLibs.Csv diff --git a/src/MiniExcel/MiniExcel.cs b/src/MiniExcel/MiniExcel.cs index ebdef08b..498b6b91 100644 --- a/src/MiniExcel/MiniExcel.cs +++ b/src/MiniExcel/MiniExcel.cs @@ -1,13 +1,15 @@ using System.Data; +using MiniExcelLib; using MiniExcelLib.Core.DataReader; -using MiniExcelLib.Core.OpenXml.Models; -using MiniExcelLib.Core.OpenXml.Picture; using MiniExcelLib.Csv; +using MiniExcelLib.OpenXml.Api; +using MiniExcelLib.OpenXml.Models; +using MiniExcelLib.OpenXml.Picture; using MiniExcelLibs.OpenXml; using Zomp.SyncMethodGenerator; using NewMiniExcel = MiniExcelLib.Core.MiniExcel; -using OpenXmlExporter = MiniExcelLib.Core.OpenXmlExporter; +using OpenXmlExporter = MiniExcelLib.OpenXml.Api.OpenXmlExporter; using OpenXmlImporter = MiniExcelLib.Core.OpenXmlImporter; using OpenXmlTemplater = MiniExcelLib.Core.OpenXmlTemplater; @@ -30,7 +32,7 @@ public static async Task AddPictureAsync(string path, CancellationToken cancella [CreateSyncVersion] public static async Task AddPictureAsync(Stream excelStream, CancellationToken cancellationToken = default, params MiniExcelPicture[] images) - => await ExcelTemplater.AddPictureAsync(excelStream, cancellationToken, images).ConfigureAwait(false); + => await ExcelTemplater.AddPictureAsync(excelStream, cancellationToken, images).ConfigureAwait(false); public static MiniExcelDataReader GetReader(string path, bool useHeaderRow = false, string? sheetName = null, ExcelType excelType = ExcelType.UNKNOWN, string startCell = "A1", IConfiguration? configuration = null) { @@ -348,17 +350,17 @@ public static async Task> GetSheetDimensionsAsync(this Stream [CreateSyncVersion] public static async Task ConvertCsvToXlsxAsync(string csv, string xlsx, CancellationToken cancellationToken = default) - => await CsvExporter.ConvertCsvToXlsxAsync(csv, xlsx, cancellationToken: cancellationToken).ConfigureAwait(false); + => await MiniExcelConverter.ConvertCsvToXlsxAsync(csv, xlsx, cancellationToken: cancellationToken).ConfigureAwait(false); [CreateSyncVersion] public static async Task ConvertCsvToXlsxAsync(Stream csv, Stream xlsx, CancellationToken cancellationToken = default) - => await CsvExporter.ConvertCsvToXlsxAsync(csv, xlsx, cancellationToken: cancellationToken).ConfigureAwait(false); + => await MiniExcelConverter.ConvertCsvToXlsxAsync(csv, xlsx, cancellationToken: cancellationToken).ConfigureAwait(false); [CreateSyncVersion] public static async Task ConvertXlsxToCsvAsync(string xlsx, string csv, CancellationToken cancellationToken = default) - => await CsvExporter.ConvertXlsxToCsvAsync(xlsx, csv, cancellationToken: cancellationToken).ConfigureAwait(false); + => await MiniExcelConverter.ConvertXlsxToCsvAsync(xlsx, csv, cancellationToken: cancellationToken).ConfigureAwait(false); [CreateSyncVersion] public static async Task ConvertXlsxToCsvAsync(Stream xlsx, Stream csv, CancellationToken cancellationToken = default) - => await CsvExporter.ConvertXlsxToCsvAsync(xlsx, csv, cancellationToken: cancellationToken).ConfigureAwait(false); + => await MiniExcelConverter.ConvertXlsxToCsvAsync(xlsx, csv, cancellationToken: cancellationToken).ConfigureAwait(false); } \ No newline at end of file diff --git a/src/MiniExcel/MiniExcel.csproj b/src/MiniExcel/MiniExcel.csproj index c05de8ac..cee79d8b 100644 --- a/src/MiniExcel/MiniExcel.csproj +++ b/src/MiniExcel/MiniExcel.csproj @@ -12,6 +12,7 @@ + diff --git a/src/MiniExcel/MiniExcelConverter.cs b/src/MiniExcel/MiniExcelConverter.cs new file mode 100644 index 00000000..564e6e96 --- /dev/null +++ b/src/MiniExcel/MiniExcelConverter.cs @@ -0,0 +1,54 @@ +using MiniExcelLib.Core; +using MiniExcelLib.Core.Helpers; +using MiniExcelLib.Csv; +using MiniExcelLib.OpenXml.Api; +using Zomp.SyncMethodGenerator; + +namespace MiniExcelLib; + +public static partial class MiniExcelConverter +{ + [CreateSyncVersion] + public static async Task ConvertCsvToXlsxAsync(Stream csv, Stream xlsx, bool csvHasHeader = false, CancellationToken cancellationToken = default) + { + var value = MiniExcel.Importers + .GetCsvImporter() + .QueryAsync(csv, useHeaderRow: csvHasHeader, cancellationToken: cancellationToken); + + await MiniExcel.Exporters + .GetOpenXmlExporter() + .ExportAsync(xlsx, value, printHeader: csvHasHeader, cancellationToken: cancellationToken) + .ConfigureAwait(false); + } + + [CreateSyncVersion] + public static async Task ConvertCsvToXlsxAsync(string csvPath, string xlsx, bool csvHasHeader = false, CancellationToken cancellationToken = default) + { + using var csvStream = FileHelper.OpenSharedRead(csvPath); + using var xlsxStream = new FileStream(xlsx, FileMode.CreateNew); + + await ConvertCsvToXlsxAsync(csvStream, xlsxStream, csvHasHeader, cancellationToken).ConfigureAwait(false); + } + + [CreateSyncVersion] + public static async Task ConvertXlsxToCsvAsync(string xlsx, string csvPath, bool xlsxHasHeader = true, CancellationToken cancellationToken = default) + { + using var xlsxStream = FileHelper.OpenSharedRead(xlsx); + using var csvStream = new FileStream(csvPath, FileMode.CreateNew); + + await ConvertXlsxToCsvAsync(xlsxStream, csvStream, xlsxHasHeader, cancellationToken).ConfigureAwait(false); + } + + [CreateSyncVersion] + public static async Task ConvertXlsxToCsvAsync(Stream xlsx, Stream csv, bool xlsxHasHeader = true, CancellationToken cancellationToken = default) + { + var value = MiniExcel.Importers + .GetOpenXmlImporter() + .QueryAsync(xlsx, useHeaderRow: xlsxHasHeader, cancellationToken: cancellationToken) + .ConfigureAwait(false); + + await MiniExcel.Exporters + .GetCsvExporter() + .ExportAsync(csv, value, printHeader: xlsxHasHeader, cancellationToken: cancellationToken).ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/tests/MiniExcel.Csv.Tests/AsyncIssueTests.cs b/tests/MiniExcel.Csv.Tests/AsyncIssueTests.cs index 99a5d3af..a4274917 100644 --- a/tests/MiniExcel.Csv.Tests/AsyncIssueTests.cs +++ b/tests/MiniExcel.Csv.Tests/AsyncIssueTests.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Csv.Tests; +using MiniExcelLib.OpenXml.Api; + +namespace MiniExcelLib.Csv.Tests; public class AsyncIssueTests { diff --git a/tests/MiniExcel.Csv.Tests/IssueTests.cs b/tests/MiniExcel.Csv.Tests/IssueTests.cs index d5bfc0e0..4296d402 100644 --- a/tests/MiniExcel.Csv.Tests/IssueTests.cs +++ b/tests/MiniExcel.Csv.Tests/IssueTests.cs @@ -1,4 +1,6 @@ -namespace MiniExcelLib.Csv.Tests; +using MiniExcelLib.OpenXml.Api; + +namespace MiniExcelLib.Csv.Tests; public class IssueTests { @@ -497,9 +499,9 @@ public void TestIssue292() { var xlsxPath = PathHelper.GetFile("/xlsx/TestIssue292.xlsx"); using var csvPath = AutoDeletingPath.Create(ExcelType.Csv); - _csvExporter.ConvertXlsxToCsv(xlsxPath, csvPath.ToString(), false); + MiniExcelConverter.ConvertXlsxToCsv(xlsxPath, csvPath.ToString(), false); - var actualCotent = File.ReadAllText(csvPath.ToString()); + var actualContent = File.ReadAllText(csvPath.ToString()); Assert.Equal( """ Name,Age,Name,Age @@ -507,13 +509,13 @@ public void TestIssue292() Henry,44,Jerry,44 """, - actualCotent); + actualContent); } { var csvPath = PathHelper.GetFile("/csv/TestIssue292.csv"); using var path = AutoDeletingPath.Create(); - _csvExporter.ConvertCsvToXlsx(csvPath, path.ToString()); + MiniExcelConverter.ConvertCsvToXlsx(csvPath, path.ToString()); var rows = _openXmlImporter.Query(path.ToString()).ToList(); Assert.Equal(3, rows.Count); @@ -566,7 +568,7 @@ public void TestIssue261() var csvPath = PathHelper.GetFile("csv/TestCsvToXlsx.csv"); using var path = AutoDeletingPath.Create(); - _csvExporter.ConvertCsvToXlsx(csvPath, path.FilePath); + MiniExcelConverter.ConvertCsvToXlsx(csvPath, path.FilePath); var rows = _openXmlImporter.Query(path.ToString()).ToList(); Assert.Equal("Name", rows[0].A); diff --git a/tests/MiniExcel.Csv.Tests/MiniExcel.Csv.Tests.csproj b/tests/MiniExcel.Csv.Tests/MiniExcel.Csv.Tests.csproj index 34584ca1..7e818ea0 100644 --- a/tests/MiniExcel.Csv.Tests/MiniExcel.Csv.Tests.csproj +++ b/tests/MiniExcel.Csv.Tests/MiniExcel.Csv.Tests.csproj @@ -25,7 +25,7 @@ - + @@ -41,7 +41,7 @@ - + diff --git a/tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingCompilerTests.cs b/tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingCompilerTests.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingCompilerTests.cs rename to tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingCompilerTests.cs index 490bf9ff..72057b6e 100644 --- a/tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingCompilerTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingCompilerTests.cs @@ -1,6 +1,6 @@ -using MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping; -namespace MiniExcelLib.Tests.FluentMapping +namespace MiniExcelLib.OpenXml.Tests.FluentMapping { /// /// Tests for the mapping compiler and optimization system. diff --git a/tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingTemplateTests.cs b/tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingTemplateTests.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingTemplateTests.cs rename to tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingTemplateTests.cs index b6c561f5..d0084c2d 100644 --- a/tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingTemplateTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingTemplateTests.cs @@ -1,7 +1,8 @@ -using MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping.Api; using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests.FluentMapping; +namespace MiniExcelLib.OpenXml.Tests.FluentMapping; public class MiniExcelMappingTemplateTests { diff --git a/tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingTests.cs b/tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingTests.cs similarity index 97% rename from tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingTests.cs rename to tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingTests.cs index 754d314b..1ee34c57 100644 --- a/tests/MiniExcel.Core.Tests/FluentMapping/MiniExcelMappingTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/FluentMapping/MiniExcelMappingTests.cs @@ -1,7 +1,8 @@ using System.Reflection; -using MiniExcelLib.Core.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping; +using MiniExcelLib.OpenXml.FluentMapping.Api; -namespace MiniExcelLib.Tests.FluentMapping +namespace MiniExcelLib.OpenXml.Tests.FluentMapping { public class MiniExcelMappingTests { @@ -455,7 +456,7 @@ public async Task Collection_WithItemMappingOnly_ShouldWriteAndReadCorrectly() var gridProp = departmentMapping.GetType().GetProperty("OptimizedCellGrid", BindingFlags.Instance | BindingFlags.Public); var grid = gridProp?.GetValue(departmentMapping) as Array; Assert.NotNull(grid); - var handlerType = typeof(MappingRegistry).Assembly.GetType("MiniExcelLib.Core.FluentMapping.OptimizedCellHandler"); + var handlerType = typeof(MappingRegistry).Assembly.GetType("MiniExcelLib.OpenXml.FluentMapping.OptimizedCellHandler"); Assert.NotNull(handlerType); var valueSetterProperty = handlerType!.GetProperty("ValueSetter", BindingFlags.Instance | BindingFlags.Public); var propertyNameProperty = handlerType.GetProperty("PropertyName", BindingFlags.Instance | BindingFlags.Public); diff --git a/tests/MiniExcel.Core.Tests/MiniExcel.Core.Tests.csproj b/tests/MiniExcel.OpenXml.Tests/MiniExcel.OpenXml.Tests.csproj similarity index 86% rename from tests/MiniExcel.Core.Tests/MiniExcel.Core.Tests.csproj rename to tests/MiniExcel.OpenXml.Tests/MiniExcel.OpenXml.Tests.csproj index bd5da2bd..ffe2eebc 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcel.Core.Tests.csproj +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcel.OpenXml.Tests.csproj @@ -10,7 +10,7 @@ true true ..\..\src\miniexcel.snk - MiniExcelLib.Tests + MiniExcelLib.OpenXml.Tests @@ -31,6 +31,7 @@ + @@ -49,8 +50,9 @@ - - + + + diff --git a/tests/MiniExcel.Core.Tests/MiniExcelAutoAdjustWidthTests.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelAutoAdjustWidthTests.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/MiniExcelAutoAdjustWidthTests.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelAutoAdjustWidthTests.cs index e9046b9c..5b6ba009 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelAutoAdjustWidthTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelAutoAdjustWidthTests.cs @@ -1,9 +1,9 @@ using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; -using MiniExcelLib.Core.OpenXml.Models; +using MiniExcelLib.OpenXml.Models; using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelAutoAdjustWidthTests { diff --git a/tests/MiniExcel.Core.Tests/MiniExcelIssueAsyncTests.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelIssueAsyncTests.cs similarity index 97% rename from tests/MiniExcel.Core.Tests/MiniExcelIssueAsyncTests.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelIssueAsyncTests.cs index 967d912b..bfcffb32 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelIssueAsyncTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelIssueAsyncTests.cs @@ -1,6 +1,7 @@ -using MiniExcelLib.Tests.Common.Utils; +using MiniExcelLib.OpenXml.Tests.Utils; +using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelIssueAsyncTests(ITestOutputHelper output) { diff --git a/tests/MiniExcel.Core.Tests/MiniExcelIssueTests.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelIssueTests.cs similarity index 97% rename from tests/MiniExcel.Core.Tests/MiniExcelIssueTests.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelIssueTests.cs index 0113a093..fd6b7e91 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelIssueTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelIssueTests.cs @@ -2,12 +2,13 @@ using System.Text.RegularExpressions; using MiniExcelLib.Core.Enums; using MiniExcelLib.Core.Exceptions; -using MiniExcelLib.Core.OpenXml.Picture; -using MiniExcelLib.Core.OpenXml.Utils; +using MiniExcelLib.OpenXml.Picture; +using MiniExcelLib.OpenXml.Tests.Utils; +using MiniExcelLib.OpenXml.Utils; using MiniExcelLib.Tests.Common.Utils; using NPOI.XSSF.UserModel; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelIssueTests(ITestOutputHelper output) { @@ -558,8 +559,6 @@ public void TestIssue343() [Fact] public void TestIssueI4YCLQ_2() { - var c = GeneralHelper.ConvertColumnName(1); - var c2 = GeneralHelper.ConvertColumnName(3); var path = PathHelper.GetFile("xlsx/TestIssueI4YCLQ_2.xlsx"); var rows = _excelImporter.Query(path, startCell: "B2").ToList(); diff --git a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlAsyncTests.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlAsyncTests.cs similarity index 97% rename from tests/MiniExcel.Core.Tests/MiniExcelOpenXmlAsyncTests.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlAsyncTests.cs index 8b7ba6fa..f4e8dd5d 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlAsyncTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlAsyncTests.cs @@ -1,8 +1,9 @@ using ClosedXML.Excel; using ExcelDataReader; +using MiniExcelLib.OpenXml.Tests.Utils; using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelOpenXmlAsyncTests { diff --git a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlConfigurationTest.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlConfigurationTest.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/MiniExcelOpenXmlConfigurationTest.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlConfigurationTest.cs index 242d90c2..0ea02695 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlConfigurationTest.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlConfigurationTest.cs @@ -1,7 +1,7 @@ using MiniExcelLib.Core.Helpers; using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelOpenXmlConfigurationTest { diff --git a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlMultipleSheetAsyncTests.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlMultipleSheetAsyncTests.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/MiniExcelOpenXmlMultipleSheetAsyncTests.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlMultipleSheetAsyncTests.cs index f15b0dbc..f408a51a 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlMultipleSheetAsyncTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlMultipleSheetAsyncTests.cs @@ -1,6 +1,6 @@ using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelOpenXmlMultipleSheetAsyncTests { diff --git a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlMultipleSheetTests.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlMultipleSheetTests.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/MiniExcelOpenXmlMultipleSheetTests.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlMultipleSheetTests.cs index 159695fc..c9e79a2e 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlMultipleSheetTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlMultipleSheetTests.cs @@ -1,7 +1,7 @@ -using MiniExcelLib.Core.OpenXml.Models; +using MiniExcelLib.OpenXml.Models; using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelOpenXmlMultipleSheetTests { diff --git a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlTests.cs b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlTests.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/MiniExcelOpenXmlTests.cs rename to tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlTests.cs index 6835276b..c49651ec 100644 --- a/tests/MiniExcel.Core.Tests/MiniExcelOpenXmlTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/MiniExcelOpenXmlTests.cs @@ -1,9 +1,10 @@ using ClosedXML.Excel; using ExcelDataReader; -using MiniExcelLib.Core.OpenXml.Utils; +using MiniExcelLib.OpenXml.Tests.Utils; using MiniExcelLib.Tests.Common.Utils; +using FileHelper = MiniExcelLib.OpenXml.Tests.Utils.FileHelper; -namespace MiniExcelLib.Tests; +namespace MiniExcelLib.OpenXml.Tests; public class MiniExcelOpenXmlTests(ITestOutputHelper output) { @@ -157,11 +158,10 @@ public void QueryRangeToIDictionary() Assert.Equal(2d, rows[1]["B"]); Assert.Equal(null!, rows[2]["A"]); - var startCellXY = ReferenceHelper.ConvertCellToCoordinates("A2"); - var endCellXY = ReferenceHelper.ConvertCellToCoordinates("C7"); - rows = _excelImporter.QueryRange(path, startRowIndex: startCellXY.Item2, startColumnIndex: startCellXY.Item1, endRowIndex: endCellXY.Item2, endColumnIndex: endCellXY.Item1) + rows = _excelImporter.QueryRange(path, startRowIndex: 2, startColumnIndex: 1, endRowIndex: 7, endColumnIndex: 3) .Cast>() .ToList(); + Assert.Equal(5, rows.Count); Assert.Equal(3, rows[0].Count); Assert.Equal(2d, rows[1]["B"]); diff --git a/tests/MiniExcel.Core.Tests/SaveByTemplate/InputValueExtractorTests.cs b/tests/MiniExcel.OpenXml.Tests/SaveByTemplate/InputValueExtractorTests.cs similarity index 97% rename from tests/MiniExcel.Core.Tests/SaveByTemplate/InputValueExtractorTests.cs rename to tests/MiniExcel.OpenXml.Tests/SaveByTemplate/InputValueExtractorTests.cs index e5df32a9..d1a4d925 100644 --- a/tests/MiniExcel.Core.Tests/SaveByTemplate/InputValueExtractorTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/SaveByTemplate/InputValueExtractorTests.cs @@ -1,6 +1,6 @@ -using MiniExcelLib.Core.OpenXml.Templates; +using MiniExcelLib.OpenXml.Templates; -namespace MiniExcelLib.Tests.SaveByTemplate; +namespace MiniExcelLib.OpenXml.Tests.SaveByTemplate; public class InputValueExtractorTests { diff --git a/tests/MiniExcel.Core.Tests/SaveByTemplate/MiniExcelTemplateAsyncTests.cs b/tests/MiniExcel.OpenXml.Tests/SaveByTemplate/MiniExcelTemplateAsyncTests.cs similarity index 97% rename from tests/MiniExcel.Core.Tests/SaveByTemplate/MiniExcelTemplateAsyncTests.cs rename to tests/MiniExcel.OpenXml.Tests/SaveByTemplate/MiniExcelTemplateAsyncTests.cs index 6fe714dc..50c8f3c3 100644 --- a/tests/MiniExcel.Core.Tests/SaveByTemplate/MiniExcelTemplateAsyncTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/SaveByTemplate/MiniExcelTemplateAsyncTests.cs @@ -1,6 +1,7 @@ -using MiniExcelLib.Tests.Common.Utils; +using MiniExcelLib.OpenXml.Tests.Utils; +using MiniExcelLib.Tests.Common.Utils; -namespace MiniExcelLib.Tests.SaveByTemplate; +namespace MiniExcelLib.OpenXml.Tests.SaveByTemplate; public class MiniExcelTemplateAsyncTests { diff --git a/tests/MiniExcel.Core.Tests/SaveByTemplate/MiniExcelTemplateTests.cs b/tests/MiniExcel.OpenXml.Tests/SaveByTemplate/MiniExcelTemplateTests.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/SaveByTemplate/MiniExcelTemplateTests.cs rename to tests/MiniExcel.OpenXml.Tests/SaveByTemplate/MiniExcelTemplateTests.cs index fc428bc3..7809a8f2 100644 --- a/tests/MiniExcel.Core.Tests/SaveByTemplate/MiniExcelTemplateTests.cs +++ b/tests/MiniExcel.OpenXml.Tests/SaveByTemplate/MiniExcelTemplateTests.cs @@ -1,9 +1,10 @@ using MiniExcelLib.Core.Enums; -using MiniExcelLib.Core.OpenXml.Picture; +using MiniExcelLib.OpenXml.Picture; +using MiniExcelLib.OpenXml.Tests.Utils; using MiniExcelLib.Tests.Common.Utils; using OfficeOpenXml.Drawing; -namespace MiniExcelLib.Tests.SaveByTemplate; +namespace MiniExcelLib.OpenXml.Tests.SaveByTemplate; public class MiniExcelTemplateTests { diff --git a/tests/MiniExcel.Core.Tests/Utils/EpplusLicense.cs b/tests/MiniExcel.OpenXml.Tests/Utils/EpplusLicense.cs similarity index 73% rename from tests/MiniExcel.Core.Tests/Utils/EpplusLicense.cs rename to tests/MiniExcel.OpenXml.Tests/Utils/EpplusLicense.cs index 6b9f4c81..37b8dcc8 100644 --- a/tests/MiniExcel.Core.Tests/Utils/EpplusLicense.cs +++ b/tests/MiniExcel.OpenXml.Tests/Utils/EpplusLicense.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Tests.Utils; +namespace MiniExcelLib.OpenXml.Tests.Utils; internal static class EpplusLicence { diff --git a/tests/MiniExcel.Core.Tests/Utils/FileHelper.cs b/tests/MiniExcel.OpenXml.Tests/Utils/FileHelper.cs similarity index 85% rename from tests/MiniExcel.Core.Tests/Utils/FileHelper.cs rename to tests/MiniExcel.OpenXml.Tests/Utils/FileHelper.cs index b0a7b122..7631b1c3 100644 --- a/tests/MiniExcel.Core.Tests/Utils/FileHelper.cs +++ b/tests/MiniExcel.OpenXml.Tests/Utils/FileHelper.cs @@ -1,4 +1,4 @@ -namespace MiniExcelLib.Tests.Utils; +namespace MiniExcelLib.OpenXml.Tests.Utils; public static class FileHelper { diff --git a/tests/MiniExcel.Core.Tests/Utils/SheetHelper.cs b/tests/MiniExcel.OpenXml.Tests/Utils/SheetHelper.cs similarity index 96% rename from tests/MiniExcel.Core.Tests/Utils/SheetHelper.cs rename to tests/MiniExcel.OpenXml.Tests/Utils/SheetHelper.cs index 740179ad..eb89374b 100644 --- a/tests/MiniExcel.Core.Tests/Utils/SheetHelper.cs +++ b/tests/MiniExcel.OpenXml.Tests/Utils/SheetHelper.cs @@ -2,7 +2,7 @@ using System.Xml.Linq; using System.Xml.XPath; -namespace MiniExcelLib.Tests.Utils; +namespace MiniExcelLib.OpenXml.Tests.Utils; internal static class SheetHelper {