diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..68cc179
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,20 @@
+# Source https://help.github.com/articles/dealing-with-line-endings
+# Set default behaviour, in case users don't have core.autocrlf set.
+* text=auto
+
+# Explicitly declare text files we want to always be normalized and converted
+# to native line endings on checkout.
+*.cs text diff=csharp eol=crlf
+
+# Declare files that will always have CRLF line endings on checkout.
+*.sln text eol=crlf
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
+*.dll binary
+*.gif binary
+*.ico binary
+*.xlsx binary
+
+core.autocrlf=true
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index cfa55f4..e5313db 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -12,3 +12,17 @@
**Did this work in previous versions of our tool? Which versions?**
- [ ] I attached a sample spreadsheet. (You can drag files on to this issue)
+
+**Code to reproduce problem:**
+```c#
+public void Main()
+{
+ // Where possible, post full code to reproduce your issue that adheres to:
+ // - Fully runnable. I should be able to copy and paste this code into a
+ // console application and run it without having to edit it much.
+ // - Declare all your variables (this follows from the previous point)
+ // - The code should be a minimal code sample to illustrate issue. The code
+ // samples on the wiki are good examples of the terseness that I want. Don't
+ // post your full application.
+}
+```
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 891ee85..6856874 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,13 +1,14 @@
-Fixes # .
-Changes proposed in this pull request:
- -
- -
- -
-
-How did I test this code:
- -
- -
- -
-
-- [ ] I attached a sample spreadsheet. (You can drag files on to this pull request)
+#### What's this PR do?
+#### Where should the reviewer start?
+#### How should this be manually tested?
+#### Any background context you want to provide?
+
+#### Screenshots (if appropriate)
+#### Questions:
+- Is there a blog post?
+- Does the knowledge base need an update?
+- Does this add new (C#) dependencies?
+
+- [ ] C# Code Review: @csreviewer
+- [ ] Test Automation Review: @csreviewer
\ No newline at end of file
diff --git a/.vs/config/applicationhost.config b/.vs/config/applicationhost.config
new file mode 100644
index 0000000..113af3d
--- /dev/null
+++ b/.vs/config/applicationhost.config
@@ -0,0 +1,1047 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/CONTRIBUTING.md
diff --git a/ClosedXML.sln b/ClosedXML.sln
index 4104ff4..b58a074 100644
--- a/ClosedXML.sln
+++ b/ClosedXML.sln
@@ -1,60 +1,55 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Sandbox", "ClosedXML_Sandbox\ClosedXML_Sandbox.csproj", "{38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5C94E22C-85AA-48FD-B082-CF929FFC6C31}"
- ProjectSection(SolutionItems) = preProject
- ClosedXML.vsmdi = ClosedXML.vsmdi
- EndProjectSection
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Examples", "ClosedXML_Examples\ClosedXML_Examples.csproj", "{03A518D0-1CB7-488E-861C-C4E782B27A46}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Net3.5", "ClosedXML_Net3.5\ClosedXML_Net3.5.csproj", "{5F43B12B-A900-40C6-9924-A0C0B032F791}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML", "ClosedXML\ClosedXML.csproj", "{BD5E6BFE-E837-4A35-BCA9-39667D873A20}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Tests", "ClosedXML_Tests\ClosedXML_Tests.csproj", "{09B066ED-E4A7-4545-A1A4-FF03DD524BDF}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{073CFB1C-43DC-4ADC-9D12-BB8D7B10C099}"
- ProjectSection(SolutionItems) = preProject
- .github\ISSUE_TEMPLATE.md = .github\ISSUE_TEMPLATE.md
- .github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Release|Any CPU.Build.0 = Release|Any CPU
- {03A518D0-1CB7-488E-861C-C4E782B27A46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {03A518D0-1CB7-488E-861C-C4E782B27A46}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {03A518D0-1CB7-488E-861C-C4E782B27A46}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {03A518D0-1CB7-488E-861C-C4E782B27A46}.Release|Any CPU.Build.0 = Release|Any CPU
- {5F43B12B-A900-40C6-9924-A0C0B032F791}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {5F43B12B-A900-40C6-9924-A0C0B032F791}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {5F43B12B-A900-40C6-9924-A0C0B032F791}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {5F43B12B-A900-40C6-9924-A0C0B032F791}.Release|Any CPU.Build.0 = Release|Any CPU
- {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Release|Any CPU.Build.0 = Release|Any CPU
- {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(TestCaseManagementSettings) = postSolution
- CategoryFile = ClosedXML.vsmdi
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Sandbox", "ClosedXML_Sandbox\ClosedXML_Sandbox.csproj", "{38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5C94E22C-85AA-48FD-B082-CF929FFC6C31}"
+ ProjectSection(SolutionItems) = preProject
+ appveyor.yml = appveyor.yml
+ ClosedXML.vsmdi = ClosedXML.vsmdi
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Examples", "ClosedXML_Examples\ClosedXML_Examples.csproj", "{03A518D0-1CB7-488E-861C-C4E782B27A46}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML", "ClosedXML\ClosedXML.csproj", "{BD5E6BFE-E837-4A35-BCA9-39667D873A20}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClosedXML_Tests", "ClosedXML_Tests\ClosedXML_Tests.csproj", "{09B066ED-E4A7-4545-A1A4-FF03DD524BDF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{073CFB1C-43DC-4ADC-9D12-BB8D7B10C099}"
+ ProjectSection(SolutionItems) = preProject
+ .github\ISSUE_TEMPLATE.md = .github\ISSUE_TEMPLATE.md
+ .github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {38B882F0-E6F2-45C5-9BE9-CDC27FBEB4AB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {03A518D0-1CB7-488E-861C-C4E782B27A46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {03A518D0-1CB7-488E-861C-C4E782B27A46}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {03A518D0-1CB7-488E-861C-C4E782B27A46}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {03A518D0-1CB7-488E-861C-C4E782B27A46}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BD5E6BFE-E837-4A35-BCA9-39667D873A20}.Release|Any CPU.Build.0 = Release|Any CPU
+ {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {09B066ED-E4A7-4545-A1A4-FF03DD524BDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(TestCaseManagementSettings) = postSolution
+ CategoryFile = ClosedXML.vsmdi
+ EndGlobalSection
+EndGlobal
diff --git a/ClosedXML/AttributeExtensions.cs b/ClosedXML/AttributeExtensions.cs
new file mode 100644
index 0000000..be35455
--- /dev/null
+++ b/ClosedXML/AttributeExtensions.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace ClosedXML
+{
+ public static class AttributeExtensions
+ {
+ public static TAttribute[] GetAttributes(
+ this MemberInfo member)
+ where TAttribute : Attribute
+ {
+ var attributes = member.GetCustomAttributes(typeof(TAttribute), true);
+
+ return (TAttribute[])attributes;
+ }
+
+ public static MethodInfo GetMethod(this T instance, Expression> methodSelector)
+ {
+ return ((MethodCallExpression)methodSelector.Body).Method;
+ }
+
+ public static MethodInfo GetMethod(this T instance, Expression> methodSelector)
+ {
+ return ((MethodCallExpression)methodSelector.Body).Method;
+ }
+
+ public static bool HasAttribute(
+ this MemberInfo member)
+ where TAttribute : Attribute
+ {
+ return GetAttributes(member).Any();
+ }
+ }
+}
diff --git a/ClosedXML/Attributes/ColumnOrderAttribute.cs b/ClosedXML/Attributes/ColumnOrderAttribute.cs
deleted file mode 100644
index b85c541..0000000
--- a/ClosedXML/Attributes/ColumnOrderAttribute.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-
-namespace ClosedXML.Attributes
-{
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
- public class ColumnOrderAttribute : Attribute
- {
- public ColumnOrderAttribute(long order)
- {
- this.Order = order;
- }
-
- public long Order { get; private set; }
- }
-}
diff --git a/ClosedXML/Attributes/XLColumnAttribute.cs b/ClosedXML/Attributes/XLColumnAttribute.cs
new file mode 100644
index 0000000..41b541b
--- /dev/null
+++ b/ClosedXML/Attributes/XLColumnAttribute.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using ClosedXML;
+using ClosedXML.Excel;
+
+namespace ClosedXML.Attributes
+{
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
+ public class XLColumnAttribute : Attribute
+ {
+ public String Header { get; set; }
+ public Boolean Ignore { get; set; }
+ public Int32 Order { get; set; }
+
+ private static XLColumnAttribute GetXLColumnAttribute(MemberInfo mi)
+ {
+ if (!mi.HasAttribute()) return null;
+ return mi.GetAttributes().First();
+ }
+
+ internal static String GetHeader(MemberInfo mi)
+ {
+ var attribute = GetXLColumnAttribute(mi);
+ if (attribute == null) return null;
+ return XLHelper.IsNullOrWhiteSpace(attribute.Header) ? null : attribute.Header;
+ }
+
+ internal static Int32 GetOrder(MemberInfo mi)
+ {
+ var attribute = GetXLColumnAttribute(mi);
+ if (attribute == null) return Int32.MaxValue;
+ return attribute.Order;
+ }
+
+ internal static Boolean IgnoreMember(MemberInfo mi)
+ {
+ var attribute = GetXLColumnAttribute(mi);
+ if (attribute == null) return false;
+ return attribute.Ignore;
+ }
+ }
+}
diff --git a/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML.csproj
index 5960577..7de9988 100644
--- a/ClosedXML/ClosedXML.csproj
+++ b/ClosedXML/ClosedXML.csproj
@@ -10,9 +10,8 @@
Properties
ClosedXML
ClosedXML
- v4.0
+ v4.5.2
512
- Client
..\
true
@@ -26,6 +25,7 @@
prompt
4
1591
+ false
pdbonly
@@ -37,6 +37,7 @@
4
bin\Release\ClosedXML.xml
1591
+ false
true
@@ -45,13 +46,16 @@
ClosedXML.snk
-
+
+ ..\packages\DocumentFormat.OpenXml.2.7.2\lib\net40\DocumentFormat.OpenXml.dll
True
- ..\packages\DocumentFormat.OpenXml.2.5\lib\DocumentFormat.OpenXml.dll
+
+
+ ..\packages\FastMember.Signed.1.1.0\lib\net40\FastMember.Signed.dll
+ True
-
@@ -61,16 +65,26 @@
-
+
+
+
+
+
+
+
+
+
+
+
@@ -328,9 +342,10 @@
.editorconfig
-
+
+ Designer
+
-
+
diff --git a/ClosedXML/Excel/AutoFilters/IXLAutoFilter.cs b/ClosedXML/Excel/AutoFilters/IXLAutoFilter.cs
index 8859848..e1a87a7 100644
--- a/ClosedXML/Excel/AutoFilters/IXLAutoFilter.cs
+++ b/ClosedXML/Excel/AutoFilters/IXLAutoFilter.cs
@@ -1,16 +1,16 @@
-using System;
-namespace ClosedXML.Excel
-{
- using System.Collections.Generic;
-
- public interface IXLAutoFilter: IDisposable
- {
- IXLFilterColumn Column(String column);
- IXLFilterColumn Column(Int32 column);
-
- IXLAutoFilter Sort(Int32 columnToSortBy = 1, XLSortOrder sortOrder = XLSortOrder.Ascending, Boolean matchCase = false, Boolean ignoreBlanks = true);
- Boolean Sorted { get; set; }
- XLSortOrder SortOrder { get; set; }
- Int32 SortColumn { get; set; }
- }
+using System;
+namespace ClosedXML.Excel
+{
+ using System.Collections.Generic;
+
+ public interface IXLAutoFilter: IDisposable
+ {
+ IXLFilterColumn Column(String column);
+ IXLFilterColumn Column(Int32 column);
+
+ IXLAutoFilter Sort(Int32 columnToSortBy = 1, XLSortOrder sortOrder = XLSortOrder.Ascending, Boolean matchCase = false, Boolean ignoreBlanks = true);
+ Boolean Sorted { get; set; }
+ XLSortOrder SortOrder { get; set; }
+ Int32 SortColumn { get; set; }
+ }
}
\ No newline at end of file
diff --git a/ClosedXML/Excel/AutoFilters/IXLBaseAutoFilter.cs b/ClosedXML/Excel/AutoFilters/IXLBaseAutoFilter.cs
index b3f8d66..88ca907 100644
--- a/ClosedXML/Excel/AutoFilters/IXLBaseAutoFilter.cs
+++ b/ClosedXML/Excel/AutoFilters/IXLBaseAutoFilter.cs
@@ -1,25 +1,25 @@
-using System;
-namespace ClosedXML.Excel
-{
- using System.Collections.Generic;
- public enum XLFilterType { Regular, Custom, TopBottom, Dynamic }
- public enum XLFilterDynamicType { AboveAverage, BelowAverage }
- public enum XLTopBottomPart { Top, Bottom}
- public interface IXLBaseAutoFilter
- {
- Boolean Enabled { get; set; }
- IXLRange Range { get; set; }
- IXLBaseAutoFilter Set(IXLRangeBase range);
- IXLBaseAutoFilter Clear();
-
- IXLFilterColumn Column(String column);
- IXLFilterColumn Column(Int32 column);
-
- IXLBaseAutoFilter Sort(Int32 columnToSortBy, XLSortOrder sortOrder = XLSortOrder.Ascending, Boolean matchCase = false, Boolean ignoreBlanks = true);
- Boolean Sorted { get; set; }
- XLSortOrder SortOrder { get; set; }
- Int32 SortColumn { get; set; }
-
-
- }
+using System;
+namespace ClosedXML.Excel
+{
+ using System.Collections.Generic;
+ public enum XLFilterType { Regular, Custom, TopBottom, Dynamic }
+ public enum XLFilterDynamicType { AboveAverage, BelowAverage }
+ public enum XLTopBottomPart { Top, Bottom}
+ public interface IXLBaseAutoFilter
+ {
+ Boolean Enabled { get; set; }
+ IXLRange Range { get; set; }
+ IXLBaseAutoFilter Set(IXLRangeBase range);
+ IXLBaseAutoFilter Clear();
+
+ IXLFilterColumn Column(String column);
+ IXLFilterColumn Column(Int32 column);
+
+ IXLBaseAutoFilter Sort(Int32 columnToSortBy, XLSortOrder sortOrder = XLSortOrder.Ascending, Boolean matchCase = false, Boolean ignoreBlanks = true);
+ Boolean Sorted { get; set; }
+ XLSortOrder SortOrder { get; set; }
+ Int32 SortColumn { get; set; }
+
+
+ }
}
\ No newline at end of file
diff --git a/ClosedXML/Excel/AutoFilters/IXLCustomFilteredColumn.cs b/ClosedXML/Excel/AutoFilters/IXLCustomFilteredColumn.cs
index 85cec03..37c6a17 100644
--- a/ClosedXML/Excel/AutoFilters/IXLCustomFilteredColumn.cs
+++ b/ClosedXML/Excel/AutoFilters/IXLCustomFilteredColumn.cs
@@ -1,19 +1,19 @@
-using System;
-namespace ClosedXML.Excel
-{
- public interface IXLCustomFilteredColumn
- {
- void EqualTo(T value) where T : IComparable;
- void NotEqualTo(T value) where T : IComparable;
- void GreaterThan(T value) where T : IComparable;
- void LessThan(T value) where T : IComparable;
- void EqualOrGreaterThan(T value) where T : IComparable;
- void EqualOrLessThan(T value) where T : IComparable;
- void BeginsWith(String value);
- void NotBeginsWith(String value);
- void EndsWith(String value);
- void NotEndsWith(String value);
- void Contains(String value);
- void NotContains(String value);
- }
+using System;
+namespace ClosedXML.Excel
+{
+ public interface IXLCustomFilteredColumn
+ {
+ void EqualTo(T value) where T : IComparable;
+ void NotEqualTo(T value) where T : IComparable;
+ void GreaterThan(T value) where T : IComparable;
+ void LessThan(T value) where T : IComparable;
+ void EqualOrGreaterThan(T value) where T : IComparable;
+ void EqualOrLessThan(T value) where T : IComparable;
+ void BeginsWith(String value);
+ void NotBeginsWith(String value);
+ void EndsWith(String value);
+ void NotEndsWith(String value);
+ void Contains(String value);
+ void NotContains(String value);
+ }
}
\ No newline at end of file
diff --git a/ClosedXML/Excel/AutoFilters/IXLFilterColumn.cs b/ClosedXML/Excel/AutoFilters/IXLFilterColumn.cs
index 159faf9..41376c8 100644
--- a/ClosedXML/Excel/AutoFilters/IXLFilterColumn.cs
+++ b/ClosedXML/Excel/AutoFilters/IXLFilterColumn.cs
@@ -1,46 +1,46 @@
-using System;
-namespace ClosedXML.Excel
-{
- public enum XLTopBottomType { Items, Percent }
- public interface IXLFilterColumn
- {
- void Clear();
-
- IXLFilteredColumn AddFilter(T value) where T : IComparable;
-
- void Top(Int32 value, XLTopBottomType type = XLTopBottomType.Items);
- void Bottom(Int32 value, XLTopBottomType type = XLTopBottomType.Items);
- void AboveAverage();
- void BelowAverage();
-
- IXLFilterConnector EqualTo(T value) where T : IComparable;
- IXLFilterConnector NotEqualTo(T value) where T : IComparable;
- IXLFilterConnector GreaterThan(T value) where T : IComparable;
- IXLFilterConnector LessThan(T value) where T : IComparable;
- IXLFilterConnector EqualOrGreaterThan(T value) where T : IComparable;
- IXLFilterConnector EqualOrLessThan(T value) where T : IComparable;
- void Between(T minValue, T maxValue) where T : IComparable;
- void NotBetween(T minValue, T maxValue) where T : IComparable;
- IXLFilterConnector BeginsWith(String value);
- IXLFilterConnector NotBeginsWith(String value);
- IXLFilterConnector EndsWith(String value);
- IXLFilterConnector NotEndsWith(String value);
- IXLFilterConnector Contains(String value);
- IXLFilterConnector NotContains(String value);
-
- XLFilterType FilterType { get; set; }
- Int32 TopBottomValue { get; set; }
- XLTopBottomType TopBottomType { get; set; }
- XLTopBottomPart TopBottomPart { get; set; }
- XLFilterDynamicType DynamicType { get; set; }
- Double DynamicValue { get; set; }
-
- IXLFilterColumn SetFilterType(XLFilterType value);
- IXLFilterColumn SetTopBottomValue(Int32 value);
- IXLFilterColumn SetTopBottomType(XLTopBottomType value);
- IXLFilterColumn SetTopBottomPart(XLTopBottomPart value);
- IXLFilterColumn SetDynamicType(XLFilterDynamicType value);
- IXLFilterColumn SetDynamicValue(Double value);
-
- }
+using System;
+namespace ClosedXML.Excel
+{
+ public enum XLTopBottomType { Items, Percent }
+ public interface IXLFilterColumn
+ {
+ void Clear();
+
+ IXLFilteredColumn AddFilter(T value) where T : IComparable;
+
+ void Top(Int32 value, XLTopBottomType type = XLTopBottomType.Items);
+ void Bottom(Int32 value, XLTopBottomType type = XLTopBottomType.Items);
+ void AboveAverage();
+ void BelowAverage();
+
+ IXLFilterConnector EqualTo(T value) where T : IComparable;
+ IXLFilterConnector NotEqualTo(T value) where T : IComparable;
+ IXLFilterConnector GreaterThan(T value) where T : IComparable;
+ IXLFilterConnector LessThan(T value) where T : IComparable;
+ IXLFilterConnector EqualOrGreaterThan(T value) where T : IComparable;
+ IXLFilterConnector EqualOrLessThan(T value) where T : IComparable;
+ void Between(T minValue, T maxValue) where T : IComparable;
+ void NotBetween(T minValue, T maxValue) where T : IComparable;
+ IXLFilterConnector BeginsWith(String value);
+ IXLFilterConnector NotBeginsWith(String value);
+ IXLFilterConnector EndsWith(String value);
+ IXLFilterConnector NotEndsWith(String value);
+ IXLFilterConnector Contains(String value);
+ IXLFilterConnector NotContains(String value);
+
+ XLFilterType FilterType { get; set; }
+ Int32 TopBottomValue { get; set; }
+ XLTopBottomType TopBottomType { get; set; }
+ XLTopBottomPart TopBottomPart { get; set; }
+ XLFilterDynamicType DynamicType { get; set; }
+ Double DynamicValue { get; set; }
+
+ IXLFilterColumn SetFilterType(XLFilterType value);
+ IXLFilterColumn SetTopBottomValue(Int32 value);
+ IXLFilterColumn SetTopBottomType(XLTopBottomType value);
+ IXLFilterColumn SetTopBottomPart(XLTopBottomPart value);
+ IXLFilterColumn SetDynamicType(XLFilterDynamicType value);
+ IXLFilterColumn SetDynamicValue(Double value);
+
+ }
}
\ No newline at end of file
diff --git a/ClosedXML/Excel/AutoFilters/IXLFilterConnector.cs b/ClosedXML/Excel/AutoFilters/IXLFilterConnector.cs
index 7955869..d5d52be 100644
--- a/ClosedXML/Excel/AutoFilters/IXLFilterConnector.cs
+++ b/ClosedXML/Excel/AutoFilters/IXLFilterConnector.cs
@@ -1,10 +1,10 @@
-using System;
-
-namespace ClosedXML.Excel
-{
- public interface IXLFilterConnector
- {
- IXLCustomFilteredColumn And { get; }
- IXLCustomFilteredColumn Or { get; }
- }
-}
+using System;
+
+namespace ClosedXML.Excel
+{
+ public interface IXLFilterConnector
+ {
+ IXLCustomFilteredColumn And { get; }
+ IXLCustomFilteredColumn Or { get; }
+ }
+}
diff --git a/ClosedXML/Excel/AutoFilters/IXLFilteredColumn.cs b/ClosedXML/Excel/AutoFilters/IXLFilteredColumn.cs
index 6491f55..86db9db 100644
--- a/ClosedXML/Excel/AutoFilters/IXLFilteredColumn.cs
+++ b/ClosedXML/Excel/AutoFilters/IXLFilteredColumn.cs
@@ -1,8 +1,8 @@
-using System;
-namespace ClosedXML.Excel
-{
- public interface IXLFilteredColumn
- {
- IXLFilteredColumn AddFilter(T value) where T : IComparable;
- }
+using System;
+namespace ClosedXML.Excel
+{
+ public interface IXLFilteredColumn
+ {
+ IXLFilteredColumn AddFilter(T value) where T : IComparable;
+ }
}
\ No newline at end of file
diff --git a/ClosedXML/Excel/AutoFilters/XLAutoFilter.cs b/ClosedXML/Excel/AutoFilters/XLAutoFilter.cs
index 28f4209..dcf4b76 100644
--- a/ClosedXML/Excel/AutoFilters/XLAutoFilter.cs
+++ b/ClosedXML/Excel/AutoFilters/XLAutoFilter.cs
@@ -1,165 +1,165 @@
-using System;
-using System.Linq;
-
-namespace ClosedXML.Excel
-{
- using System.Collections.Generic;
-
- internal class XLAutoFilter : IXLBaseAutoFilter, IXLAutoFilter
- {
- private readonly Dictionary _columns = new Dictionary();
-
- public XLAutoFilter()
- {
- Filters = new Dictionary>();
- }
-
- public Dictionary> Filters { get; private set; }
-
- #region IXLAutoFilter Members
-
- IXLAutoFilter IXLAutoFilter.Sort(Int32 columnToSortBy, XLSortOrder sortOrder, Boolean matchCase,
- Boolean ignoreBlanks)
- {
- return Sort(columnToSortBy, sortOrder, matchCase, ignoreBlanks);
- }
-
- public void Dispose()
- {
- if (Range != null)
- Range.Dispose();
- }
-
- #endregion
-
- #region IXLBaseAutoFilter Members
-
- public Boolean Enabled { get; set; }
- public IXLRange Range { get; set; }
-
- IXLBaseAutoFilter IXLBaseAutoFilter.Clear()
- {
- return Clear();
- }
-
- IXLBaseAutoFilter IXLBaseAutoFilter.Set(IXLRangeBase range)
- {
- return Set(range);
- }
-
- IXLBaseAutoFilter IXLBaseAutoFilter.Sort(Int32 columnToSortBy, XLSortOrder sortOrder, Boolean matchCase,
- Boolean ignoreBlanks)
- {
- return Sort(columnToSortBy, sortOrder, matchCase, ignoreBlanks);
- }
-
- public Boolean Sorted { get; set; }
- public XLSortOrder SortOrder { get; set; }
- public Int32 SortColumn { get; set; }
-
- public IXLFilterColumn Column(String column)
- {
- return Column(XLHelper.GetColumnNumberFromLetter(column));
- }
-
- public IXLFilterColumn Column(Int32 column)
- {
- XLFilterColumn filterColumn;
- if (!_columns.TryGetValue(column, out filterColumn))
- {
- filterColumn = new XLFilterColumn(this, column);
- _columns.Add(column, filterColumn);
- }
-
- return filterColumn;
- }
-
- #endregion
-
- public XLAutoFilter Set(IXLRangeBase range)
- {
- Range = range.AsRange();
- Enabled = true;
- return this;
- }
-
- public XLAutoFilter Clear()
- {
- if (!Enabled) return this;
-
- Enabled = false;
- Filters.Clear();
- foreach (IXLRangeRow row in Range.Rows().Where(r => r.RowNumber() > 1))
- row.WorksheetRow().Unhide();
- return this;
- }
-
- public XLAutoFilter Sort(Int32 columnToSortBy, XLSortOrder sortOrder, Boolean matchCase, Boolean ignoreBlanks)
- {
- if (!Enabled)
- throw new ApplicationException("Filter has not been enabled.");
-
- var ws = Range.Worksheet as XLWorksheet;
- ws.SuspendEvents();
- Range.Range(Range.FirstCell().CellBelow(), Range.LastCell()).Sort(columnToSortBy, sortOrder, matchCase,
- ignoreBlanks);
-
- Sorted = true;
- SortOrder = sortOrder;
- SortColumn = columnToSortBy;
-
- if (Enabled)
- {
- using (var rows = Range.Rows(2, Range.RowCount()))
- {
- foreach (IXLRangeRow row in rows)
- row.WorksheetRow().Unhide();
- }
-
- foreach (KeyValuePair> kp in Filters)
- {
- Boolean firstFilter = true;
- foreach (XLFilter filter in kp.Value)
- {
- Boolean isText = filter.Value is String;
- using (var rows = Range.Rows(2, Range.RowCount()))
- {
- foreach (IXLRangeRow row in rows)
- {
- Boolean match = isText
- ? filter.Condition(row.Cell(kp.Key).GetString())
- : row.Cell(kp.Key).DataType == XLCellValues.Number &&
- filter.Condition(row.Cell(kp.Key).GetDouble());
- if (firstFilter)
- {
- if (match)
- row.WorksheetRow().Unhide();
- else
- row.WorksheetRow().Hide();
- }
- else
- {
- if (filter.Connector == XLConnector.And)
- {
- if (!row.WorksheetRow().IsHidden)
- {
- if (match)
- row.WorksheetRow().Unhide();
- else
- row.WorksheetRow().Hide();
- }
- }
- else if (match)
- row.WorksheetRow().Unhide();
- }
- }
- firstFilter = false;
- }
- }
- }
- }
- ws.ResumeEvents();
- return this;
- }
- }
+using System;
+using System.Linq;
+
+namespace ClosedXML.Excel
+{
+ using System.Collections.Generic;
+
+ internal class XLAutoFilter : IXLBaseAutoFilter, IXLAutoFilter
+ {
+ private readonly Dictionary _columns = new Dictionary();
+
+ public XLAutoFilter()
+ {
+ Filters = new Dictionary>();
+ }
+
+ public Dictionary> Filters { get; private set; }
+
+ #region IXLAutoFilter Members
+
+ IXLAutoFilter IXLAutoFilter.Sort(Int32 columnToSortBy, XLSortOrder sortOrder, Boolean matchCase,
+ Boolean ignoreBlanks)
+ {
+ return Sort(columnToSortBy, sortOrder, matchCase, ignoreBlanks);
+ }
+
+ public void Dispose()
+ {
+ if (Range != null)
+ Range.Dispose();
+ }
+
+ #endregion
+
+ #region IXLBaseAutoFilter Members
+
+ public Boolean Enabled { get; set; }
+ public IXLRange Range { get; set; }
+
+ IXLBaseAutoFilter IXLBaseAutoFilter.Clear()
+ {
+ return Clear();
+ }
+
+ IXLBaseAutoFilter IXLBaseAutoFilter.Set(IXLRangeBase range)
+ {
+ return Set(range);
+ }
+
+ IXLBaseAutoFilter IXLBaseAutoFilter.Sort(Int32 columnToSortBy, XLSortOrder sortOrder, Boolean matchCase,
+ Boolean ignoreBlanks)
+ {
+ return Sort(columnToSortBy, sortOrder, matchCase, ignoreBlanks);
+ }
+
+ public Boolean Sorted { get; set; }
+ public XLSortOrder SortOrder { get; set; }
+ public Int32 SortColumn { get; set; }
+
+ public IXLFilterColumn Column(String column)
+ {
+ return Column(XLHelper.GetColumnNumberFromLetter(column));
+ }
+
+ public IXLFilterColumn Column(Int32 column)
+ {
+ XLFilterColumn filterColumn;
+ if (!_columns.TryGetValue(column, out filterColumn))
+ {
+ filterColumn = new XLFilterColumn(this, column);
+ _columns.Add(column, filterColumn);
+ }
+
+ return filterColumn;
+ }
+
+ #endregion
+
+ public XLAutoFilter Set(IXLRangeBase range)
+ {
+ Range = range.AsRange();
+ Enabled = true;
+ return this;
+ }
+
+ public XLAutoFilter Clear()
+ {
+ if (!Enabled) return this;
+
+ Enabled = false;
+ Filters.Clear();
+ foreach (IXLRangeRow row in Range.Rows().Where(r => r.RowNumber() > 1))
+ row.WorksheetRow().Unhide();
+ return this;
+ }
+
+ public XLAutoFilter Sort(Int32 columnToSortBy, XLSortOrder sortOrder, Boolean matchCase, Boolean ignoreBlanks)
+ {
+ if (!Enabled)
+ throw new ApplicationException("Filter has not been enabled.");
+
+ var ws = Range.Worksheet as XLWorksheet;
+ ws.SuspendEvents();
+ Range.Range(Range.FirstCell().CellBelow(), Range.LastCell()).Sort(columnToSortBy, sortOrder, matchCase,
+ ignoreBlanks);
+
+ Sorted = true;
+ SortOrder = sortOrder;
+ SortColumn = columnToSortBy;
+
+ if (Enabled)
+ {
+ using (var rows = Range.Rows(2, Range.RowCount()))
+ {
+ foreach (IXLRangeRow row in rows)
+ row.WorksheetRow().Unhide();
+ }
+
+ foreach (KeyValuePair> kp in Filters)
+ {
+ Boolean firstFilter = true;
+ foreach (XLFilter filter in kp.Value)
+ {
+ Boolean isText = filter.Value is String;
+ using (var rows = Range.Rows(2, Range.RowCount()))
+ {
+ foreach (IXLRangeRow row in rows)
+ {
+ Boolean match = isText
+ ? filter.Condition(row.Cell(kp.Key).GetString())
+ : row.Cell(kp.Key).DataType == XLCellValues.Number &&
+ filter.Condition(row.Cell(kp.Key).GetDouble());
+ if (firstFilter)
+ {
+ if (match)
+ row.WorksheetRow().Unhide();
+ else
+ row.WorksheetRow().Hide();
+ }
+ else
+ {
+ if (filter.Connector == XLConnector.And)
+ {
+ if (!row.WorksheetRow().IsHidden)
+ {
+ if (match)
+ row.WorksheetRow().Unhide();
+ else
+ row.WorksheetRow().Hide();
+ }
+ }
+ else if (match)
+ row.WorksheetRow().Unhide();
+ }
+ }
+ firstFilter = false;
+ }
+ }
+ }
+ }
+ ws.ResumeEvents();
+ return this;
+ }
+ }
}
\ No newline at end of file
diff --git a/ClosedXML/Excel/AutoFilters/XLCustomFilteredColumn.cs b/ClosedXML/Excel/AutoFilters/XLCustomFilteredColumn.cs
index 26fd585..d2cb44d 100644
--- a/ClosedXML/Excel/AutoFilters/XLCustomFilteredColumn.cs
+++ b/ClosedXML/Excel/AutoFilters/XLCustomFilteredColumn.cs
@@ -1,143 +1,143 @@
-using System;
-using System.Linq;
-
-namespace ClosedXML.Excel
-{
- internal class XLCustomFilteredColumn : IXLCustomFilteredColumn
- {
- private readonly XLAutoFilter _autoFilter;
- private readonly Int32 _column;
- private readonly XLConnector _connector;
-
- public XLCustomFilteredColumn(XLAutoFilter autoFilter, Int32 column, XLConnector connector)
- {
- _autoFilter = autoFilter;
- _column = column;
- _connector = connector;
- }
-
- #region IXLCustomFilteredColumn Members
-
- public void EqualTo(T value) where T: IComparable
- {
- if (typeof(T) == typeof(String))
- {
- ApplyCustomFilter(value, XLFilterOperator.Equal,
- v =>
- v.ToString().Equals(value.ToString(), StringComparison.InvariantCultureIgnoreCase));
- }
- else
- {
- ApplyCustomFilter(value, XLFilterOperator.Equal,
- v => v.CastTo().CompareTo(value) == 0);
- }
- }
-
- public void NotEqualTo(T value) where T: IComparable
- {
- if (typeof(T) == typeof(String))
- {
- ApplyCustomFilter(value, XLFilterOperator.NotEqual,
- v =>
- !v.ToString().Equals(value.ToString(), StringComparison.InvariantCultureIgnoreCase));
- }
- else
- {
- ApplyCustomFilter(value, XLFilterOperator.NotEqual,
- v => v.CastTo().CompareTo(value) != 0);
- }
- }
-
- public void GreaterThan(T value) where T: IComparable
- {
- ApplyCustomFilter(value, XLFilterOperator.GreaterThan,
- v => v.CastTo().CompareTo(value) > 0);
- }
-
- public void LessThan(T value) where T: IComparable
- {
- ApplyCustomFilter(value, XLFilterOperator.LessThan, v => v.CastTo().CompareTo(value) < 0);
- }
-
- public void EqualOrGreaterThan(T value) where T: IComparable
- {
- ApplyCustomFilter(value, XLFilterOperator.EqualOrGreaterThan,
- v => v.CastTo().CompareTo(value) >= 0);
- }
-
- public void EqualOrLessThan(T value) where T: IComparable
- {
- ApplyCustomFilter(value, XLFilterOperator.EqualOrLessThan,
- v => v.CastTo().CompareTo(value) <= 0);
- }
-
- public void BeginsWith(String value)
- {
- ApplyCustomFilter(value + "*", XLFilterOperator.Equal,
- s => ((string)s).StartsWith(value, StringComparison.InvariantCultureIgnoreCase));
- }
-
- public void NotBeginsWith(String value)
- {
- ApplyCustomFilter(value + "*", XLFilterOperator.NotEqual,
- s =>
- !((string)s).StartsWith(value, StringComparison.InvariantCultureIgnoreCase));
- }
-
- public void EndsWith(String value)
- {
- ApplyCustomFilter("*" + value, XLFilterOperator.Equal,
- s => ((string)s).EndsWith(value, StringComparison.InvariantCultureIgnoreCase));
- }
-
- public void NotEndsWith(String value)
- {
- ApplyCustomFilter("*" + value, XLFilterOperator.NotEqual,
- s => !((string)s).EndsWith(value, StringComparison.InvariantCultureIgnoreCase));
- }
-
- public void Contains(String value)
- {
- ApplyCustomFilter("*" + value + "*", XLFilterOperator.Equal,
- s => ((string)s).ToLower().Contains(value.ToLower()));
- }
-
- public void NotContains(String value)
- {
- ApplyCustomFilter("*" + value + "*", XLFilterOperator.Equal,
- s => !((string)s).ToLower().Contains(value.ToLower()));
- }
-
- #endregion
-
- private void ApplyCustomFilter(T value, XLFilterOperator op, Func