Pārlūkot izejas kodu

Added GetTextQuotePrefix

Piotr Czajkowski 1 stundu atpakaļ
vecāks
revīzija
b814a28f67

+ 1 - 1
ExcelORM/ExcelORM/ExcelDynamicReader.cs

@@ -37,7 +37,7 @@ public sealed class ExcelDynamicReader : IDisposable
 
                 var cellItem = item with
                 {
-                    Value = cell.Value.ToObject()
+                    Value = cell.ToObject()
                 };
 
                 dynamicRow.Add(cellItem);

+ 1 - 1
ExcelORM/ExcelORM/ExcelReader.cs

@@ -50,7 +50,7 @@ public sealed class ExcelReader : IDisposable
                         continue;
                     }
 
-                    current.SetPropertyValue(property, cell.Value);
+                    current.SetPropertyValue(property, cell);
                 }
                 catch (ArgumentException e)
                 {

+ 1 - 1
ExcelORM/ExcelORM/Models/Formula.cs

@@ -9,7 +9,7 @@ namespace ExcelORM.Models
         public override void SetCellValue(IXLCell cell) => cell.FormulaA1 = FormulaA1;
         public override void GetValueFromCell(IXLCell cell)
         {
-            Value = cell.Value.ToObject();
+            Value = cell.ToObject();
             if (cell.HasFormula) FormulaA1 = cell.FormulaA1;
         }
     }

+ 1 - 1
ExcelORM/ExcelORM/Models/Hyperlink.cs

@@ -14,7 +14,7 @@ namespace ExcelORM.Models
 
         public override void GetValueFromCell(IXLCell cell)
         {
-            Value = cell.Value.ToObject();
+            Value = cell.ToObject();
             if (cell.HasHyperlink) Link = cell.GetHyperlink();
         }
     }

+ 30 - 22
ExcelORM/ExcelORM/TypeExtensions.cs

@@ -28,33 +28,33 @@ public static class TypeExtensions
             ? enumValue : Enum.GetValues(property.PropertyType).GetValue(0);
     }
 
-    private static object? GetAdditionalTypeFromText(XLCellValue value, PropertyInfo? property = null)
+    private static object? GetAdditionalTypeFromText(IXLCell cell, PropertyInfo? property = null)
     {
-        if (property == null) return value.GetText();
+        if (property == null) return cell.GetTextQuotePrefix();
 
         var pt = property.PropertyType;
         switch (pt)
         {
             case var _ when pt == typeof(Guid) || pt == typeof(Guid?):
-                return HandleGuid(value, property);
+                return HandleGuid(cell.Value, property);
             case var _ when pt == typeof(DateTime):
-                if (DateTime.TryParse(value.GetText(), out var dateValueNotNull)) return dateValueNotNull;
+                if (DateTime.TryParse(cell.GetTextQuotePrefix(), out var dateValueNotNull)) return dateValueNotNull;
                 break;
             case var _ when pt == typeof(DateTime?):
-                if (DateTime.TryParse(value.GetText(), out var dateValue)) return dateValue;
+                if (DateTime.TryParse(cell.GetTextQuotePrefix(), out var dateValue)) return dateValue;
                 return null;
             case var _ when pt == typeof(DateOnly):
-                if (DateOnly.TryParse(value.GetText(), out var dateOnlyValueNotNull)) return dateOnlyValueNotNull;
+                if (DateOnly.TryParse(cell.GetTextQuotePrefix(), out var dateOnlyValueNotNull)) return dateOnlyValueNotNull;
                 break;
             case var _ when pt == typeof(DateOnly?):
-                if (DateOnly.TryParse(value.GetText(), out var dateOnlyValue)) return dateOnlyValue;
+                if (DateOnly.TryParse(cell.GetTextQuotePrefix(), out var dateOnlyValue)) return dateOnlyValue;
                 return null;
             case { IsEnum: true }:
             case var _ when Nullable.GetUnderlyingType(pt) is { IsEnum: true }:
-                return HandleEnum(value, property, Nullable.GetUnderlyingType(property.PropertyType));
+                return HandleEnum(cell.Value, property, Nullable.GetUnderlyingType(property.PropertyType));
         }
 
-        return value.GetText();
+        return cell.GetTextQuotePrefix();
     }
 
     private static object? GetSpecificNumberType(XLCellValue value, PropertyInfo? property)
@@ -81,24 +81,24 @@ public static class TypeExtensions
     }
 
     // Borrowed from https://github.com/ClosedXML/ClosedXML/blob/develop/ClosedXML/Excel/XLCellValue.cs#L361
-    public static object? ToObject(this XLCellValue value, PropertyInfo? property = null)
+    public static object? ToObject(this IXLCell cell, PropertyInfo? property = null)
     {
-        return value.Type switch
+        return cell.Value.Type switch
         {
             XLDataType.Blank => null,
-            XLDataType.Boolean => value.GetBoolean(),
-            XLDataType.Number => GetSpecificNumberType(value, property),
-            XLDataType.Text => GetAdditionalTypeFromText(value, property),
-            XLDataType.Error => value.GetError(),
-            XLDataType.DateTime => value.GetDateTime(),
-            XLDataType.TimeSpan => value.GetTimeSpan(),
+            XLDataType.Boolean => cell.Value.GetBoolean(),
+            XLDataType.Number => GetSpecificNumberType(cell.Value, property),
+            XLDataType.Text => GetAdditionalTypeFromText(cell, property),
+            XLDataType.Error => cell.Value.GetError(),
+            XLDataType.DateTime => cell.Value.GetDateTime(),
+            XLDataType.TimeSpan => cell.Value.GetTimeSpan(),
             _ => throw new InvalidCastException()
         };
     }
 
-    public static void SetPropertyValue<T>(this T currentObject, PropertyInfo property, XLCellValue value)
+    public static void SetPropertyValue<T>(this T currentObject, PropertyInfo property, IXLCell cell)
     {
-        var valueToSet = value.ToObject(property);
+        var valueToSet = cell.ToObject(property);
 
         try
         {
@@ -109,22 +109,30 @@ public static class TypeExtensions
             // If the property type is string, try to set it directly from the XLCellValue's string representation.
             if (property.PropertyType == typeof(string))
             {
-                property.SetValue(currentObject, value.ToString());
+                property.SetValue(currentObject, cell.GetTextQuotePrefix());
             }
             else
             {
                 // If it's not a string property, and the initial assignment failed,
                 // re-throw with more context.
-                throw new InvalidCastException($"Could not set property '{property.Name}' of type '{property.PropertyType.Name}' with value '{valueToSet}' (original XLCellValue: '{value}'). " +
+                throw new InvalidCastException($"Could not set property '{property.Name}' of type '{property.PropertyType.Name}' with value '{valueToSet}' (original XLCellValue: '{cell.Value}'). " +
                                                $"The value returned by ToObject was incompatible, and the property type is not string for fallback conversion. See inner exception for details.", ex);
             }
         }
         catch (Exception ex) // Catch any other unexpected exceptions from SetValue
         {
             throw new InvalidOperationException($"An unexpected error occurred while setting property '{property.Name}' of type '{property.PropertyType.Name}'. " +
-                                                $"Value attempted to set: '{valueToSet}' (original XLCellValue: '{value}'). See inner exception for details.", ex);
+                                                $"Value attempted to set: '{valueToSet}' (original XLCellValue: '{cell.Value}'). See inner exception for details.", ex);
         }
     }
 
     public static bool Skip(this PropertyInfo property) => property.GetCustomAttributes(typeof(SkipAttribute), false).FirstOrDefault() != null;
+    
+    public static string GetTextQuotePrefix(this IXLCell? cell)
+    {
+        if (cell == null) return string.Empty;
+
+        var value = cell.GetString();
+        return cell.Style.IncludeQuotePrefix ? $"'{value}" : value;
+    }
 }

+ 16 - 8
ExcelORM/ExcelORMTests/TypeExtensionsTests.cs

@@ -10,10 +10,12 @@ public class TypeExtensionsTests
     [Fact]
     public void ToObject_DateTimeAsString()
     {
-        XLCellValue value = "7/27/2025";
+        XLWorkbook wb = new();
+        var ws = wb.Worksheets.Add("Sheet1");
+        var cell = ws.Cell(1, 1).SetValue("7/27/2025");
         
         var propertyInfo = typeof(TypeExtensionsTests).GetProperty("DateTimeProperty");
-        var readValue = value.ToObject(propertyInfo);
+        var readValue = cell.ToObject(propertyInfo);
         Assert.IsType<DateTime>(readValue);
     }
     
@@ -22,10 +24,12 @@ public class TypeExtensionsTests
     [Fact]
     public void ToObject_DateOnlyAsString()
     {
-        XLCellValue value = "7/27/2025";
+        XLWorkbook wb = new();
+        var ws = wb.Worksheets.Add("Sheet1");
+        var cell = ws.Cell(1, 1).SetValue("7/27/2025");
         
         var propertyInfo = typeof(TypeExtensionsTests).GetProperty("DateOnlyProperty");
-        var readValue = value.ToObject(propertyInfo);
+        var readValue = cell.ToObject(propertyInfo);
         Assert.IsType<DateOnly>(readValue);
     }
      
@@ -34,10 +38,12 @@ public class TypeExtensionsTests
     [Fact]
     public void ToObject_GuidAsString()
     {
-        XLCellValue value = "00000000-0000-0000-0000-000000000001";
+        XLWorkbook wb = new();
+        var ws = wb.Worksheets.Add("Sheet1");
+        var cell = ws.Cell(1, 1).SetValue("00000000-0000-0000-0000-000000000001");
         
         var propertyInfo = typeof(TypeExtensionsTests).GetProperty("GuidProperty");
-        var readValue = value.ToObject(propertyInfo);
+        var readValue = cell.ToObject(propertyInfo);
         Assert.IsType<Guid>(readValue);
         Assert.NotEqual(Guid.Empty, readValue);
     }
@@ -47,10 +53,12 @@ public class TypeExtensionsTests
     [Fact]
     public void ToObject_EnumAsString()
     {
-        XLCellValue value = "Second";
+        XLWorkbook wb = new();
+        var ws = wb.Worksheets.Add("Sheet1");
+        var cell = ws.Cell(1, 1).SetValue("Second");
         
         var propertyInfo = typeof(TypeExtensionsTests).GetProperty("EnumProperty");
-        var readValue = value.ToObject(propertyInfo);
+        var readValue = cell.ToObject(propertyInfo);
         Assert.IsType<TestEnum>(readValue);
         Assert.NotEqual(TestEnum.First, readValue);
     }