diff --git a/src/LinqToExcel.Tests/ColumnMappings_IntegrationTests.cs b/src/LinqToExcel.Tests/ColumnMappings_IntegrationTests.cs index 6613f2f..ebb1a76 100644 --- a/src/LinqToExcel.Tests/ColumnMappings_IntegrationTests.cs +++ b/src/LinqToExcel.Tests/ColumnMappings_IntegrationTests.cs @@ -139,6 +139,22 @@ public void annotated_properties_map_to_columns() Assert.AreEqual("N", rival.IsActive, "IsActive"); } + [Test] + public void annotated_properties_map_to_similar_columns() + { + var companies = from c in _repo.Worksheet(_worksheetName) + where c.Name == "Taylor University" + select c; + + var rival = companies.ToList().First(); + Assert.AreEqual(1, companies.ToList().Count, "Result Count"); + Assert.AreEqual("Taylor University", rival.Name, "Name"); + Assert.AreEqual("Your Mom", rival.CEO, "CEO"); + Assert.AreEqual(400, rival.EmployeeCount, "EmployeeCount"); + Assert.AreEqual(new DateTime(1988, 7, 26), rival.StartDate, "StartDate"); + Assert.AreEqual("N", rival.IsActive, "IsActive"); + } + [Test] public void two_transformations_with_the_same_property_but_in_different_types() { diff --git a/src/LinqToExcel.Tests/CompanyWithSimilarColumnsAnnotations.cs b/src/LinqToExcel.Tests/CompanyWithSimilarColumnsAnnotations.cs new file mode 100644 index 0000000..5cc7131 --- /dev/null +++ b/src/LinqToExcel.Tests/CompanyWithSimilarColumnsAnnotations.cs @@ -0,0 +1,23 @@ +using System; +using LinqToExcel.Attributes; + +namespace LinqToExcel.Tests +{ + public class CompanyWithSimilarColumnsAnnotations + { + [ExcelColumn(new[] { "Company Title", "Company", "Business Title" })] + public string Name { get; set; } + + [ExcelColumn(new[] { "Boss", "Head", "Executive" })] + public string CEO { get; set; } + + [ExcelColumn(new[] { "Number People", "People Count" })] + public int EmployeeCount { get; set; } + + [ExcelColumn(new[] { "Initiation Date", "Init Date" })] + public DateTime StartDate { get; set; } + + [ExcelColumn(new[] { "Active", "Is Active" })] + public string IsActive { get; set; } + } +} diff --git a/src/LinqToExcel/Attributes/ExcelColumnAttribute.cs b/src/LinqToExcel/Attributes/ExcelColumnAttribute.cs index 1269b7b..5a54c50 100644 --- a/src/LinqToExcel/Attributes/ExcelColumnAttribute.cs +++ b/src/LinqToExcel/Attributes/ExcelColumnAttribute.cs @@ -1,4 +1,8 @@ using System; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Globalization; namespace LinqToExcel.Attributes { @@ -7,15 +11,42 @@ public sealed class ExcelColumnAttribute : Attribute { private readonly string _columnName; - public ExcelColumnAttribute(string columnName) + private readonly string[] _similarColumnNames; + private readonly bool _forceToSimilar; + + private readonly Regex pattern = new Regex(@"(?:( +[d|n](o|e|a|os|as))|( +(?:a(?:nd?)?|the|to|[io]n|from|with|of|for))) +| +|_+|-+|'+|`+"); + + public ExcelColumnAttribute(string columnName, string[] similarColumnNames = null, bool forceToSimilar = false) { _columnName = columnName; + _similarColumnNames = similarColumnNames; + _forceToSimilar = forceToSimilar; } + public ExcelColumnAttribute(string[] similarColumnNames, bool forceToSimilar = true): this(null, similarColumnNames, forceToSimilar) { } + public string ColumnName { get { return _columnName; } } + public bool IsForced + { + get { return _forceToSimilar; } + } + + public bool HasSimilarColumn(string columnName) + { + return !string.IsNullOrEmpty(_similarColumnNames?.ToList().Find(x => Clear(x) == Clear(columnName))); + } + + private string Clear(string s) + { + s = new string(s.Normalize(NormalizationForm.FormD) + .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != UnicodeCategory.NonSpacingMark) + .ToArray()); + + return pattern.Replace(s.Trim().ToLower(), ""); + } } } diff --git a/src/LinqToExcel/LinqToExcel.csproj b/src/LinqToExcel/LinqToExcel.csproj index 2fb9ebb..47ba74e 100644 --- a/src/LinqToExcel/LinqToExcel.csproj +++ b/src/LinqToExcel/LinqToExcel.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/LinqToExcel/Query/ExcelQueryable.cs b/src/LinqToExcel/Query/ExcelQueryable.cs index 871aec1..317f007 100644 --- a/src/LinqToExcel/Query/ExcelQueryable.cs +++ b/src/LinqToExcel/Query/ExcelQueryable.cs @@ -27,7 +27,11 @@ internal ExcelQueryable(ExcelQueryArgs args, ILogManagerFactory logManagerFactor ExcelColumnAttribute att = (ExcelColumnAttribute)Attribute.GetCustomAttribute(property, typeof(ExcelColumnAttribute)); if (att != null && !args.ColumnMappings.ContainsKey(property.Name)) { - args.ColumnMappings.Add(property.Name, att.ColumnName); + var columnNames = ExcelUtilities.GetColumnNames(args); + + args.ColumnMappings.Add(property.Name, !att.IsForced ? + att.ColumnName : + columnNames.ToList().Find(x => att.HasSimilarColumn(x))??att.ColumnName); } } }