Skip to content

Commit 16d8e48

Browse files
Fixed parsing bug in the conversion to double (#734)
* Added support for Uri mapping * Fixed parsing bug in the conversion to double - Fixed problem where, after the latest commit, numeric strings were not being converted to double correctly due to a ToString call that lacked invariant localization - Also added a missing Dispose call in MiniExcelDataReader, and a couple more superficial changes
1 parent d221726 commit 16d8e48

File tree

5 files changed

+27
-37
lines changed

5 files changed

+27
-37
lines changed

src/MiniExcel/MiniExcelDataReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ public override string GetName(int i)
6969
/// <inheritdoc/>
7070
public override int GetOrdinal(string name)
7171
{
72-
_keys.IndexOf(name);
7372
return _keys.IndexOf(name);
7473
}
7574

@@ -81,6 +80,7 @@ protected override void Dispose(bool disposing)
8180
if (disposing)
8281
{
8382
_stream?.Dispose();
83+
_source?.Dispose();
8484
}
8585
_disposed = true;
8686
}

src/MiniExcel/OpenXml/ExcelOpenXmlSheetReader.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.IO;
88
using System.IO.Compression;
99
using System.Linq;
10-
using System.Text.RegularExpressions;
1110
using System.Threading;
1211
using System.Threading.Tasks;
1312
using System.Xml;
@@ -496,14 +495,8 @@ private void SetCellsValueAndHeaders(object cellValue, bool useHeaderRow, ref Di
496495

497496
if (itemValue == null)
498497
continue;
499-
if (pInfo.ExcludeNullableType == typeof(double) && (!Regex.IsMatch(itemValue?.ToString(), "^-?\\d+(\\.\\d+)?([eE][-+]?\\d+)?$") || itemValue?.ToString().Trim().Equals("NaN") == true))//double.NaN 无效值处理
500-
{
501-
newV = TypeHelper.TypeMapping(v, pInfo, newV, double.NaN, rowIndex, startCell, configuration);
502-
}
503-
else
504-
{
505-
newV = TypeHelper.TypeMapping(v, pInfo, newV, itemValue, rowIndex, startCell, configuration);
506-
}
498+
499+
newV = TypeHelper.TypeMapping(v, pInfo, newV, itemValue, rowIndex, startCell, configuration);
507500
}
508501
}
509502
rowIndex++;

src/MiniExcel/Utils/TypeHelper.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ public static IEnumerable<IDictionary<string, object>> ConvertToEnumerableDictio
1616
while (reader.Read())
1717
{
1818
yield return Enumerable.Range(0, reader.FieldCount)
19-
.ToDictionary(
20-
i => reader.GetName(i),
21-
i => reader.GetValue(i));
19+
.ToDictionary(reader.GetName, reader.GetValue);
2220
}
2321
}
2422

@@ -69,7 +67,9 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals
6967
var columnName = pInfo.ExcelColumnName ?? pInfo.Property.Name;
7068
var startRowIndex = ReferenceHelper.ConvertCellToXY(startCell).Item2;
7169
var errorRow = startRowIndex + rowIndex + 1;
72-
throw new ExcelInvalidCastException(columnName, errorRow, itemValue, pInfo.Property.Info.PropertyType, $"ColumnName : {columnName}, CellRow : {errorRow}, Value : {itemValue}, it can't cast to {pInfo.Property.Info.PropertyType.Name} type.");
70+
71+
var msg = $"ColumnName: {columnName}, CellRow: {errorRow}, Value: {itemValue}. The value cannot be cast to type {pInfo.Property.Info.PropertyType.Name}.";
72+
throw new ExcelInvalidCastException(columnName, errorRow, itemValue, pInfo.Property.Info.PropertyType, msg);
7373
}
7474
}
7575

@@ -96,7 +96,7 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals
9696
else if (DateTimeOffset.TryParse(vs, _config.Culture, DateTimeStyles.None, out var _v))
9797
newValue = _v;
9898
else
99-
throw new InvalidCastException($"{vs} can't cast to datetime");
99+
throw new InvalidCastException($"{vs} cannot be cast to DateTime");
100100
}
101101
else if (pInfo.ExcludeNullableType == typeof(DateTime))
102102
{
@@ -127,7 +127,7 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals
127127
else if (double.TryParse(vs, NumberStyles.None, CultureInfo.InvariantCulture, out var _d))
128128
newValue = DateTimeHelper.FromOADate(_d);
129129
else
130-
throw new InvalidCastException($"{vs} can't cast to datetime");
130+
throw new InvalidCastException($"{vs} cannot be cast to DateTime");
131131
}
132132
else if (pInfo.ExcludeNullableType == typeof(TimeSpan))
133133
{
@@ -153,7 +153,12 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals
153153
else if (double.TryParse(vs, NumberStyles.None, CultureInfo.InvariantCulture, out var _d))
154154
newValue = TimeSpan.FromMilliseconds(_d);
155155
else
156-
throw new InvalidCastException($"{vs} can't cast to TimeSpan");
156+
throw new InvalidCastException($"{vs} cannot be cast to TimeSpan");
157+
}
158+
else if (pInfo.ExcludeNullableType == typeof(double)) // && (!Regex.IsMatch(itemValue.ToString(), @"^-?\d+(\.\d+)?([eE][-+]?\d+)?$") || itemValue.ToString().Trim().Equals("NaN")))
159+
{
160+
var invariantString = Convert.ToString(itemValue, CultureInfo.InvariantCulture);
161+
newValue = double.TryParse(invariantString, NumberStyles.Any, CultureInfo.InvariantCulture, out var _v2) ? _v2 : double.NaN;
157162
}
158163
else if (pInfo.ExcludeNullableType == typeof(bool))
159164
{
@@ -204,6 +209,5 @@ public static bool IsAsyncEnumerable(this Type type, out Type genericArgument)
204209
return genericArgument != null;
205210
}
206211
#endif
207-
208212
}
209213
}

src/MiniExcel/Utils/XmlReaderHelper.cs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace MiniExcelLibs.Utils
99
internal static class XmlReaderHelper
1010
{
1111
/// <summary>
12-
/// Pass <?xml> and <worksheet>
12+
/// Pass &lt;?xml&gt; and &lt;worksheet&gt;
1313
/// </summary>
1414
/// <param name="reader"></param>
1515
public static void PassXmlDeclartionAndWorksheet(this XmlReader reader)
@@ -26,7 +26,7 @@ public static void SkipToNextSameLevelDom(XmlReader reader)
2626
{
2727
while (!reader.EOF)
2828
{
29-
if (!XmlReaderHelper.SkipContent(reader))
29+
if (!SkipContent(reader))
3030
break;
3131
}
3232
}
@@ -65,36 +65,29 @@ public static bool IsStartElement(XmlReader reader, string name, params string[]
6565

6666
public static string GetAttribute(XmlReader reader, string name, params string[] nss)
6767
{
68-
foreach (var ns in nss)
69-
{
70-
var attribute = reader.GetAttribute(name, ns);
71-
if (attribute != null)
72-
{
73-
return attribute;
74-
}
75-
}
76-
77-
return null;
68+
return nss
69+
.Select(ns => reader.GetAttribute(name, ns))
70+
.FirstOrDefault(at => at != null);
7871
}
7972

8073
public static IEnumerable<string> GetSharedStrings(Stream stream, params string[] nss)
8174
{
8275
using (var reader = XmlReader.Create(stream))
8376
{
84-
if (!XmlReaderHelper.IsStartElement(reader, "sst", nss))
77+
if (!IsStartElement(reader, "sst", nss))
8578
yield break;
8679

87-
if (!XmlReaderHelper.ReadFirstContent(reader))
80+
if (!ReadFirstContent(reader))
8881
yield break;
8982

9083
while (!reader.EOF)
9184
{
92-
if (XmlReaderHelper.IsStartElement(reader, "si", nss))
85+
if (IsStartElement(reader, "si", nss))
9386
{
9487
var value = StringHelper.ReadStringItem(reader);
9588
yield return value;
9689
}
97-
else if (!XmlReaderHelper.SkipContent(reader))
90+
else if (!SkipContent(reader))
9891
{
9992
break;
10093
}

tests/MiniExcelTests/MiniExcelIssueTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ public void TestIssue209()
11901190
Assert.Equal(4, ex.Row);
11911191
Assert.Equal("Error", ex.Value);
11921192
Assert.Equal(typeof(int), ex.InvalidCastType);
1193-
Assert.Equal("ColumnName : SEQ, CellRow : 4, Value : Error, it can't cast to Int32 type.", ex.Message);
1193+
Assert.Equal("ColumnName: SEQ, CellRow: 4, Value: Error. The value cannot be cast to type Int32.", ex.Message);
11941194
}
11951195
}
11961196

@@ -1739,7 +1739,7 @@ public void TestIssueI3X2ZL()
17391739
catch (InvalidCastException ex)
17401740
{
17411741
Assert.Equal(
1742-
"ColumnName : Col2, CellRow : 6, Value : error, it can't cast to DateTime type.",
1742+
"ColumnName: Col2, CellRow: 6, Value: error. The value cannot be cast to type DateTime.",
17431743
ex.Message
17441744
);
17451745
}
@@ -1752,7 +1752,7 @@ public void TestIssueI3X2ZL()
17521752
catch (InvalidCastException ex)
17531753
{
17541754
Assert.Equal(
1755-
"ColumnName : Col1, CellRow : 3, Value : error, it can't cast to Int32 type.",
1755+
"ColumnName: Col1, CellRow: 3, Value: error. The value cannot be cast to type Int32.",
17561756
ex.Message
17571757
);
17581758
}

0 commit comments

Comments
 (0)