diff --git a/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML.csproj index 8b9ecc4..84c5f14 100644 --- a/ClosedXML/ClosedXML.csproj +++ b/ClosedXML/ClosedXML.csproj @@ -49,6 +49,10 @@ True ..\packages\DocumentFormat.OpenXml.2.5\lib\DocumentFormat.OpenXml.dll + + ..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll + True + diff --git a/ClosedXML/Excel/Cells/XLCell.cs b/ClosedXML/Excel/Cells/XLCell.cs index 7a131ed..4b1b6a3 100644 --- a/ClosedXML/Excel/Cells/XLCell.cs +++ b/ClosedXML/Excel/Cells/XLCell.cs @@ -11,6 +11,7 @@ namespace ClosedXML.Excel { using Attributes; + using FastMember; internal class XLCell : IXLCell, IXLStylized { @@ -244,19 +245,7 @@ _cellValue = dtTest.ToOADate().ToInvariantString(); } - else if ( - value is sbyte - || value is byte - || value is short - || value is ushort - || value is int - || value is uint - || value is long - || value is ulong - || value is float - || value is double - || value is decimal - ) + else if (value.GetType().IsNumber()) { if ((value is double || value is float) && (Double.IsNaN((Double)Convert.ChangeType(value, typeof(Double))) || Double.IsInfinity((Double)Convert.ChangeType(value, typeof(Double))))) @@ -513,16 +502,21 @@ } else { - BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; + const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; var memberCache = new Dictionary>(); + var accessorCache = new Dictionary(); IEnumerable members = null; + TypeAccessor accessor = null; bool isPlainObject = itemType == typeof(object); if (!isPlainObject) + { members = itemType.GetFields(bindingFlags).Cast() .Concat(itemType.GetProperties(bindingFlags)) .Where(mi => !XLColumnAttribute.IgnoreMember(mi)) .OrderBy(mi => XLColumnAttribute.GetOrder(mi)); + accessor = TypeAccessor.Create(itemType); + } foreach (T m in data) { @@ -532,12 +526,20 @@ // This is very inefficient and we prefer type of T to be a concrete class or struct var type = m.GetType(); if (!memberCache.ContainsKey(type)) - memberCache.Add(type, type.GetFields(bindingFlags).Cast() + { + var _accessor = TypeAccessor.Create(type); + + var _members = type.GetFields(bindingFlags).Cast() .Concat(type.GetProperties(bindingFlags)) .Where(mi => !XLColumnAttribute.IgnoreMember(mi)) - .OrderBy(mi => XLColumnAttribute.GetOrder(mi))); + .OrderBy(mi => XLColumnAttribute.GetOrder(mi)); + + memberCache.Add(type, _members); + accessorCache.Add(type, _accessor); + } members = memberCache[type]; + accessor = accessorCache[type]; } var co = Address.ColumnNumber; @@ -627,14 +629,7 @@ foreach (var mi in members) { - var fi = mi as FieldInfo; - var pi = mi as PropertyInfo; - - if (fi != null) - SetValue(fi.GetValue(m), ro, co); - else if (pi != null && mi as IEnumerable == null) - SetValue(pi.GetValue(m, null), ro, co); - + SetValue(accessor[m, mi.Name], ro, co); co++; } } @@ -711,9 +706,32 @@ var maxCo = 0; var isDataTable = false; var isDataReader = false; + + const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; + var memberCache = new Dictionary>(); + var accessorCache = new Dictionary(); + IEnumerable members = null; + TypeAccessor accessor = null; + foreach (var m in data) { var itemType = m.GetType(); + if (!memberCache.ContainsKey(itemType)) + { + var _accessor = TypeAccessor.Create(itemType); + + var _members = itemType.GetFields(bindingFlags).Cast() + .Concat(itemType.GetProperties(bindingFlags)) + .Where(mi => !XLColumnAttribute.IgnoreMember(mi)) + .OrderBy(mi => XLColumnAttribute.GetOrder(mi)); + + memberCache.Add(itemType, _members); + accessorCache.Add(itemType, _accessor); + } + + members = memberCache[itemType]; + accessor = accessorCache[itemType]; + var co = Address.ColumnNumber; if (itemType.IsPrimitive || itemType == typeof(String) || itemType == typeof(DateTime) || itemType.IsNumber()) @@ -757,18 +775,9 @@ } else { - var fieldInfo = itemType.GetFields(); - foreach (var info in fieldInfo) + foreach (var mi in members) { - SetValue(info.GetValue(m), ro, co); - co++; - } - - var propertyInfo = itemType.GetProperties(); - foreach (var info in propertyInfo) - { - if ((info as IEnumerable) == null) - SetValue(info.GetValue(m, null), ro, co); + SetValue(accessor[m, mi.Name], ro, co); co++; } } diff --git a/ClosedXML/Excel/IXLTheme.cs b/ClosedXML/Excel/IXLTheme.cs index b4daa78..b4e1ccb 100644 --- a/ClosedXML/Excel/IXLTheme.cs +++ b/ClosedXML/Excel/IXLTheme.cs @@ -1,4 +1,6 @@ - +using ClosedXML.Excel; +using System.Drawing; + namespace ClosedXML.Excel { public interface IXLTheme @@ -15,5 +17,7 @@ XLColor Accent6 { get; set; } XLColor Hyperlink { get; set; } XLColor FollowedHyperlink { get; set; } + + XLColor ResolveThemeColor(XLThemeColor themeColor); } } diff --git a/ClosedXML/Excel/Style/Dictionary.cs b/ClosedXML/Excel/Style/Dictionary.cs deleted file mode 100644 index b866775..0000000 --- a/ClosedXML/Excel/Style/Dictionary.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace ClosedXML.Excel.Style -{ - class Dictionary - { - } -} diff --git a/ClosedXML/Excel/XLTheme.cs b/ClosedXML/Excel/XLTheme.cs index 288b063..3c5e839 100644 --- a/ClosedXML/Excel/XLTheme.cs +++ b/ClosedXML/Excel/XLTheme.cs @@ -1,7 +1,9 @@ - +using FastMember; +using System.Linq; + namespace ClosedXML.Excel { - internal class XLTheme: IXLTheme + internal class XLTheme : IXLTheme { public XLColor Background1 { get; set; } public XLColor Text1 { get; set; } @@ -15,5 +17,17 @@ public XLColor Accent6 { get; set; } public XLColor Hyperlink { get; set; } public XLColor FollowedHyperlink { get; set; } + + private TypeAccessor accessor = TypeAccessor.Create(typeof(XLTheme)); + + public XLColor ResolveThemeColor(XLThemeColor themeColor) + { + var tc = themeColor.ToString(); + var members = accessor.GetMembers(); + if (members.Any(m => m.Name.Equals(tc))) + return accessor[this, tc] as XLColor; + else + return null; + } } } diff --git a/ClosedXML/packages.config b/ClosedXML/packages.config index dfe0d07..682875d 100644 --- a/ClosedXML/packages.config +++ b/ClosedXML/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj b/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj index b828af4..f2acadf 100644 --- a/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj +++ b/ClosedXML_Net3.5/ClosedXML_Net3.5.csproj @@ -45,6 +45,10 @@ ..\packages\DocumentFormat.OpenXml.1.0\lib\DocumentFormat.OpenXml.dll True + + ..\packages\FastMember.Signed.1.1.0\lib\net35\FastMember.Signed.dll + True + diff --git a/ClosedXML_Net3.5/packages.config b/ClosedXML_Net3.5/packages.config index db6cf16..6908883 100644 --- a/ClosedXML_Net3.5/packages.config +++ b/ClosedXML_Net3.5/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/ClosedXML_Tests/Excel/Misc/StylesTests.cs b/ClosedXML_Tests/Excel/Misc/StylesTests.cs index a00a47e..d60e69f 100644 --- a/ClosedXML_Tests/Excel/Misc/StylesTests.cs +++ b/ClosedXML_Tests/Excel/Misc/StylesTests.cs @@ -63,5 +63,19 @@ Assert.AreEqual(XLBorderStyleValues.Thick, range.LastColumn().Cell(2).Style.Border.RightBorder); Assert.AreEqual(XLBorderStyleValues.Double, range.LastColumn().Cell(3).Style.Border.RightBorder); } + + [Test] + public void ResolveThemeColors() + { + using (var wb = new XLWorkbook()) + { + string color; + color = wb.Theme.ResolveThemeColor(XLThemeColor.Accent1).Color.ToHex(); + Assert.AreEqual("FF4F81BD", color); + + color = wb.Theme.ResolveThemeColor(XLThemeColor.Background1).Color.ToHex(); + Assert.AreEqual("FFFFFFFF", color); + } + } } -} \ No newline at end of file +}