diff --git a/src/MiniExcel/MiniExcelDataReader.cs b/src/MiniExcel/MiniExcelDataReader.cs index 5d525174..6a130444 100644 --- a/src/MiniExcel/MiniExcelDataReader.cs +++ b/src/MiniExcel/MiniExcelDataReader.cs @@ -69,7 +69,6 @@ public override string GetName(int i) /// public override int GetOrdinal(string name) { - _keys.IndexOf(name); return _keys.IndexOf(name); } @@ -81,6 +80,7 @@ protected override void Dispose(bool disposing) if (disposing) { _stream?.Dispose(); + _source?.Dispose(); } _disposed = true; } diff --git a/src/MiniExcel/OpenXml/ExcelOpenXmlSheetReader.cs b/src/MiniExcel/OpenXml/ExcelOpenXmlSheetReader.cs index d3db6528..67537af2 100644 --- a/src/MiniExcel/OpenXml/ExcelOpenXmlSheetReader.cs +++ b/src/MiniExcel/OpenXml/ExcelOpenXmlSheetReader.cs @@ -7,7 +7,6 @@ using System.IO; using System.IO.Compression; using System.Linq; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Xml; @@ -496,14 +495,8 @@ private void SetCellsValueAndHeaders(object cellValue, bool useHeaderRow, ref Di if (itemValue == null) continue; - if (pInfo.ExcludeNullableType == typeof(double) && (!Regex.IsMatch(itemValue?.ToString(), "^-?\\d+(\\.\\d+)?([eE][-+]?\\d+)?$") || itemValue?.ToString().Trim().Equals("NaN") == true))//double.NaN 无效值处理 - { - newV = TypeHelper.TypeMapping(v, pInfo, newV, double.NaN, rowIndex, startCell, configuration); - } - else - { - newV = TypeHelper.TypeMapping(v, pInfo, newV, itemValue, rowIndex, startCell, configuration); - } + + newV = TypeHelper.TypeMapping(v, pInfo, newV, itemValue, rowIndex, startCell, configuration); } } rowIndex++; diff --git a/src/MiniExcel/Utils/TypeHelper.cs b/src/MiniExcel/Utils/TypeHelper.cs index 5daef177..bcacf328 100644 --- a/src/MiniExcel/Utils/TypeHelper.cs +++ b/src/MiniExcel/Utils/TypeHelper.cs @@ -16,9 +16,7 @@ public static IEnumerable> ConvertToEnumerableDictio while (reader.Read()) { yield return Enumerable.Range(0, reader.FieldCount) - .ToDictionary( - i => reader.GetName(i), - i => reader.GetValue(i)); + .ToDictionary(reader.GetName, reader.GetValue); } } @@ -69,7 +67,9 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals var columnName = pInfo.ExcelColumnName ?? pInfo.Property.Name; var startRowIndex = ReferenceHelper.ConvertCellToXY(startCell).Item2; var errorRow = startRowIndex + rowIndex + 1; - 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."); + + var msg = $"ColumnName: {columnName}, CellRow: {errorRow}, Value: {itemValue}. The value cannot be cast to type {pInfo.Property.Info.PropertyType.Name}."; + throw new ExcelInvalidCastException(columnName, errorRow, itemValue, pInfo.Property.Info.PropertyType, msg); } } @@ -96,7 +96,7 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals else if (DateTimeOffset.TryParse(vs, _config.Culture, DateTimeStyles.None, out var _v)) newValue = _v; else - throw new InvalidCastException($"{vs} can't cast to datetime"); + throw new InvalidCastException($"{vs} cannot be cast to DateTime"); } else if (pInfo.ExcludeNullableType == typeof(DateTime)) { @@ -127,7 +127,7 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals else if (double.TryParse(vs, NumberStyles.None, CultureInfo.InvariantCulture, out var _d)) newValue = DateTimeHelper.FromOADate(_d); else - throw new InvalidCastException($"{vs} can't cast to datetime"); + throw new InvalidCastException($"{vs} cannot be cast to DateTime"); } else if (pInfo.ExcludeNullableType == typeof(TimeSpan)) { @@ -153,7 +153,12 @@ public static bool IsNumericType(Type type, bool isNullableUnderlyingType = fals else if (double.TryParse(vs, NumberStyles.None, CultureInfo.InvariantCulture, out var _d)) newValue = TimeSpan.FromMilliseconds(_d); else - throw new InvalidCastException($"{vs} can't cast to TimeSpan"); + throw new InvalidCastException($"{vs} cannot be cast to TimeSpan"); + } + else if (pInfo.ExcludeNullableType == typeof(double)) // && (!Regex.IsMatch(itemValue.ToString(), @"^-?\d+(\.\d+)?([eE][-+]?\d+)?$") || itemValue.ToString().Trim().Equals("NaN"))) + { + var invariantString = Convert.ToString(itemValue, CultureInfo.InvariantCulture); + newValue = double.TryParse(invariantString, NumberStyles.Any, CultureInfo.InvariantCulture, out var _v2) ? _v2 : double.NaN; } else if (pInfo.ExcludeNullableType == typeof(bool)) { @@ -204,6 +209,5 @@ public static bool IsAsyncEnumerable(this Type type, out Type genericArgument) return genericArgument != null; } #endif - } } diff --git a/src/MiniExcel/Utils/XmlReaderHelper.cs b/src/MiniExcel/Utils/XmlReaderHelper.cs index bc63b472..5b03e5e5 100644 --- a/src/MiniExcel/Utils/XmlReaderHelper.cs +++ b/src/MiniExcel/Utils/XmlReaderHelper.cs @@ -9,7 +9,7 @@ namespace MiniExcelLibs.Utils internal static class XmlReaderHelper { /// - /// Pass and + /// Pass <?xml> and <worksheet> /// /// public static void PassXmlDeclartionAndWorksheet(this XmlReader reader) @@ -26,7 +26,7 @@ public static void SkipToNextSameLevelDom(XmlReader reader) { while (!reader.EOF) { - if (!XmlReaderHelper.SkipContent(reader)) + if (!SkipContent(reader)) break; } } @@ -65,36 +65,29 @@ public static bool IsStartElement(XmlReader reader, string name, params string[] public static string GetAttribute(XmlReader reader, string name, params string[] nss) { - foreach (var ns in nss) - { - var attribute = reader.GetAttribute(name, ns); - if (attribute != null) - { - return attribute; - } - } - - return null; + return nss + .Select(ns => reader.GetAttribute(name, ns)) + .FirstOrDefault(at => at != null); } public static IEnumerable GetSharedStrings(Stream stream, params string[] nss) { using (var reader = XmlReader.Create(stream)) { - if (!XmlReaderHelper.IsStartElement(reader, "sst", nss)) + if (!IsStartElement(reader, "sst", nss)) yield break; - if (!XmlReaderHelper.ReadFirstContent(reader)) + if (!ReadFirstContent(reader)) yield break; while (!reader.EOF) { - if (XmlReaderHelper.IsStartElement(reader, "si", nss)) + if (IsStartElement(reader, "si", nss)) { var value = StringHelper.ReadStringItem(reader); yield return value; } - else if (!XmlReaderHelper.SkipContent(reader)) + else if (!SkipContent(reader)) { break; } diff --git a/tests/MiniExcelTests/MiniExcelIssueTests.cs b/tests/MiniExcelTests/MiniExcelIssueTests.cs index 2ddc4893..7cb626f8 100644 --- a/tests/MiniExcelTests/MiniExcelIssueTests.cs +++ b/tests/MiniExcelTests/MiniExcelIssueTests.cs @@ -1190,7 +1190,7 @@ public void TestIssue209() Assert.Equal(4, ex.Row); Assert.Equal("Error", ex.Value); Assert.Equal(typeof(int), ex.InvalidCastType); - Assert.Equal("ColumnName : SEQ, CellRow : 4, Value : Error, it can't cast to Int32 type.", ex.Message); + Assert.Equal("ColumnName: SEQ, CellRow: 4, Value: Error. The value cannot be cast to type Int32.", ex.Message); } } @@ -1739,7 +1739,7 @@ public void TestIssueI3X2ZL() catch (InvalidCastException ex) { Assert.Equal( - "ColumnName : Col2, CellRow : 6, Value : error, it can't cast to DateTime type.", + "ColumnName: Col2, CellRow: 6, Value: error. The value cannot be cast to type DateTime.", ex.Message ); } @@ -1752,7 +1752,7 @@ public void TestIssueI3X2ZL() catch (InvalidCastException ex) { Assert.Equal( - "ColumnName : Col1, CellRow : 3, Value : error, it can't cast to Int32 type.", + "ColumnName: Col1, CellRow: 3, Value: error. The value cannot be cast to type Int32.", ex.Message ); }