| /******************************************************************************* | 
 |  * You may amend and distribute as you like, but don't remove this header! | 
 |  * | 
 |  * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets. | 
 |  * See http://www.codeplex.com/EPPlus for details. | 
 |  * | 
 |  * Copyright (C) 2011  Jan Källman | 
 |  * | 
 |  * This library is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU Lesser General Public | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   | 
 |  * See the GNU Lesser General Public License for more details. | 
 |  * | 
 |  * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php | 
 |  * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html | 
 |  * | 
 |  * All code and executables are provided "as is" with no warranty either express or implied.  | 
 |  * The author accepts no liability for any damage or loss of business that this product may cause. | 
 |  * | 
 |  * Code change notes: | 
 |  *  | 
 |  * Author					Change						                Date | 
 |  * ****************************************************************************** | 
 |  * Eyal Seagull		Conditional Formatting            2012-04-03 | 
 |  *******************************************************************************/ | 
 | using System; | 
 | using System.Collections.Generic; | 
 | using System.Linq; | 
 | using System.Text; | 
 | using System.Collections; | 
 | using OfficeOpenXml.Utils; | 
 | using System.Xml; | 
 | using OfficeOpenXml.ConditionalFormatting.Contracts; | 
 | using System.Text.RegularExpressions; | 
 | using System.Drawing; | 
 |  | 
 | namespace OfficeOpenXml.ConditionalFormatting | 
 | { | 
 |   /// <summary> | 
 |   /// Collection of <see cref="ExcelConditionalFormattingRule"/>. | 
 |   /// This class is providing the API for EPPlus conditional formatting. | 
 |   /// </summary> | 
 |   /// <remarks> | 
 |   /// <para> | 
 |   /// The public methods of this class (Add[...]ConditionalFormatting) will create a ConditionalFormatting/CfRule entry in the worksheet. When this | 
 |   /// Conditional Formatting has been created changes to the properties will affect the workbook immediately. | 
 |   /// </para> | 
 |   /// <para> | 
 |   /// Each type of Conditional Formatting Rule has diferente set of properties. | 
 |   /// </para> | 
 |   /// <code> | 
 |   /// // Add a Three Color Scale conditional formatting | 
 |   /// var cf = worksheet.ConditionalFormatting.AddThreeColorScale(new ExcelAddress("A1:C10")); | 
 |   /// // Set the conditional formatting properties | 
 |   /// cf.LowValue.Type = ExcelConditionalFormattingValueObjectType.Min; | 
 |   /// cf.LowValue.Color = Color.White; | 
 |   /// cf.MiddleValue.Type = ExcelConditionalFormattingValueObjectType.Percent; | 
 |   /// cf.MiddleValue.Value = 50; | 
 |   /// cf.MiddleValue.Color = Color.Blue; | 
 |   /// cf.HighValue.Type = ExcelConditionalFormattingValueObjectType.Max; | 
 |   /// cf.HighValue.Color = Color.Black; | 
 |   /// </code> | 
 |   /// </remarks> | 
 |   public class ExcelConditionalFormattingCollection | 
 |     : XmlHelper, | 
 |     IEnumerable<IExcelConditionalFormattingRule> | 
 |   { | 
 |     /****************************************************************************************/ | 
 |  | 
 |     #region Private Properties | 
 |     private List<IExcelConditionalFormattingRule> _rules = new List<IExcelConditionalFormattingRule>(); | 
 |     private ExcelWorksheet _worksheet = null; | 
 |     #endregion Private Properties | 
 |  | 
 |     /****************************************************************************************/ | 
 |  | 
 |     #region Constructors | 
 |     /// <summary> | 
 |     /// Initialize the <see cref="ExcelConditionalFormattingCollection"/> | 
 |     /// </summary> | 
 |     /// <param name="worksheet"></param> | 
 |     internal ExcelConditionalFormattingCollection( | 
 |       ExcelWorksheet worksheet) | 
 |       : base( | 
 |         worksheet.NameSpaceManager, | 
 |         worksheet.WorksheetXml.DocumentElement) | 
 |     { | 
 |       Require.Argument(worksheet).IsNotNull("worksheet"); | 
 |  | 
 |       _worksheet = worksheet; | 
 |       SchemaNodeOrder = _worksheet.SchemaNodeOrder; | 
 |  | 
 |       // Look for all the <conditionalFormatting> | 
 |       var conditionalFormattingNodes = TopNode.SelectNodes( | 
 |         "//" + ExcelConditionalFormattingConstants.Paths.ConditionalFormatting, | 
 |         _worksheet.NameSpaceManager); | 
 |  | 
 |       // Check if we found at least 1 node | 
 |       if ((conditionalFormattingNodes != null) | 
 |         && (conditionalFormattingNodes.Count > 0)) | 
 |       { | 
 |         // Foreach <conditionalFormatting> | 
 |         foreach (XmlNode conditionalFormattingNode in conditionalFormattingNodes) | 
 |         { | 
 |           // Check if @sqref attribute exists | 
 |           if (conditionalFormattingNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Sqref] == null) | 
 |           { | 
 |             throw new Exception( | 
 |               ExcelConditionalFormattingConstants.Errors.MissingSqrefAttribute); | 
 |           } | 
 |  | 
 |           // Get the @sqref attribute | 
 |           ExcelAddress address = new ExcelAddress( | 
 |             conditionalFormattingNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Sqref].Value); | 
 |  | 
 |           // Check for all the <cfRules> nodes and load them | 
 |           var cfRuleNodes = conditionalFormattingNode.SelectNodes( | 
 |             ExcelConditionalFormattingConstants.Paths.CfRule, | 
 |             _worksheet.NameSpaceManager); | 
 |  | 
 |           // Foreach <cfRule> inside the current <conditionalFormatting> | 
 |           foreach (XmlNode cfRuleNode in cfRuleNodes) | 
 |           { | 
 |             // Check if @type attribute exists | 
 |             if (cfRuleNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Type] == null) | 
 |             { | 
 |               throw new Exception( | 
 |                 ExcelConditionalFormattingConstants.Errors.MissingTypeAttribute); | 
 |             } | 
 |  | 
 |             // Check if @priority attribute exists | 
 |             if (cfRuleNode.Attributes[ExcelConditionalFormattingConstants.Attributes.Priority] == null) | 
 |             { | 
 |               throw new Exception( | 
 |                 ExcelConditionalFormattingConstants.Errors.MissingPriorityAttribute); | 
 |             } | 
 |  | 
 |             // Get the <cfRule> main attributes | 
 |             string typeAttribute = ExcelConditionalFormattingHelper.GetAttributeString( | 
 |               cfRuleNode, | 
 |               ExcelConditionalFormattingConstants.Attributes.Type); | 
 |  | 
 |             int priority = ExcelConditionalFormattingHelper.GetAttributeInt( | 
 |               cfRuleNode, | 
 |               ExcelConditionalFormattingConstants.Attributes.Priority); | 
 |  | 
 |             // Transform the @type attribute to EPPlus Rule Type (slighty diferente) | 
 |             var type = ExcelConditionalFormattingRuleType.GetTypeByAttrbiute( | 
 |               typeAttribute, | 
 |               cfRuleNode, | 
 |               _worksheet.NameSpaceManager); | 
 |  | 
 |             // Create the Rule according to the correct type, address and priority | 
 |             var cfRule = ExcelConditionalFormattingRuleFactory.Create( | 
 |               type, | 
 |               address, | 
 |               priority, | 
 |               _worksheet, | 
 |               cfRuleNode); | 
 |  | 
 |             // Add the new rule to the list | 
 |             if(cfRule!=null) | 
 |               _rules.Add(cfRule); | 
 |           } | 
 |         } | 
 |       } | 
 |     } | 
 |     #endregion Constructors | 
 |  | 
 |     /****************************************************************************************/ | 
 |  | 
 |     #region Methods | 
 |     /// <summary> | 
 |     ///  | 
 |     /// </summary> | 
 |     private void EnsureRootElementExists() | 
 |     { | 
 |       // Find the <worksheet> node | 
 |       if (_worksheet.WorksheetXml.DocumentElement == null) | 
 |       { | 
 |         throw new Exception( | 
 |           ExcelConditionalFormattingConstants.Errors.MissingWorksheetNode); | 
 |       } | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// GetRootNode | 
 |     /// </summary> | 
 |     /// <returns></returns> | 
 |     private XmlNode GetRootNode() | 
 |     { | 
 |       EnsureRootElementExists(); | 
 |       return _worksheet.WorksheetXml.DocumentElement; | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Validates address - not empty (collisions are allowded) | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     private ExcelAddress ValidateAddress( | 
 |       ExcelAddress address) | 
 |     { | 
 |       Require.Argument(address).IsNotNull("address"); | 
 |  | 
 |       //TODO: Are there any other validation we need to do? | 
 |       return address; | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Get the next priority sequencial number | 
 |     /// </summary> | 
 |     /// <returns></returns> | 
 |     private int GetNextPriority() | 
 |     { | 
 |       // Consider zero as the last priority when we have no CF rules | 
 |       int lastPriority = 0; | 
 |  | 
 |       // Search for the last priority | 
 |       foreach (var cfRule in _rules) | 
 |       { | 
 |         if (cfRule.Priority > lastPriority) | 
 |         { | 
 |           lastPriority = cfRule.Priority; | 
 |         } | 
 |       } | 
 |  | 
 |       // Our next priority is the last plus one | 
 |       return lastPriority + 1; | 
 |     } | 
 |     #endregion Methods | 
 |  | 
 |     /****************************************************************************************/ | 
 |  | 
 |     #region IEnumerable<IExcelConditionalFormatting> | 
 |     /// <summary> | 
 |     /// Number of validations | 
 |     /// </summary> | 
 |     public int Count | 
 |     { | 
 |       get { return _rules.Count; } | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Index operator, returns by 0-based index | 
 |     /// </summary> | 
 |     /// <param name="index"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingRule this[int index] | 
 |     { | 
 |       get { return _rules[index]; } | 
 |       set { _rules[index] = value; } | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Get the 'cfRule' enumerator | 
 |     /// </summary> | 
 |     /// <returns></returns> | 
 |     IEnumerator<IExcelConditionalFormattingRule> IEnumerable<IExcelConditionalFormattingRule>.GetEnumerator() | 
 |     { | 
 |       return _rules.GetEnumerator(); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Get the 'cfRule' enumerator | 
 |     /// </summary> | 
 |     /// <returns></returns> | 
 |     IEnumerator System.Collections.IEnumerable.GetEnumerator() | 
 |     { | 
 |       return _rules.GetEnumerator(); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Removes all 'cfRule' from the collection and from the XML. | 
 |     /// <remarks> | 
 |     /// This is the same as removing all the 'conditionalFormatting' nodes. | 
 |     /// </remarks> | 
 |     /// </summary> | 
 |     public void RemoveAll() | 
 |     { | 
 |       // Look for all the <conditionalFormatting> nodes | 
 |       var conditionalFormattingNodes = TopNode.SelectNodes( | 
 |         "//" + ExcelConditionalFormattingConstants.Paths.ConditionalFormatting, | 
 |         _worksheet.NameSpaceManager); | 
 |  | 
 |       // Remove all the <conditionalFormatting> nodes one by one | 
 |       foreach (XmlNode conditionalFormattingNode in conditionalFormattingNodes) | 
 |       { | 
 |         conditionalFormattingNode.ParentNode.RemoveChild(conditionalFormattingNode); | 
 |       } | 
 |  | 
 |       // Clear the <cfRule> item list | 
 |       _rules.Clear(); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Remove a Conditional Formatting Rule by its object | 
 |     /// </summary> | 
 |     /// <param name="item"></param> | 
 |     public void Remove( | 
 |       IExcelConditionalFormattingRule item) | 
 |     { | 
 |       Require.Argument(item).IsNotNull("item"); | 
 |  | 
 |       try | 
 |       { | 
 |         // Point to the parent node | 
 |         var oldParentNode = item.Node.ParentNode; | 
 |  | 
 |         // Remove the <cfRule> from the old <conditionalFormatting> parent node | 
 |         oldParentNode.RemoveChild(item.Node); | 
 |  | 
 |         // Check if the old <conditionalFormatting> parent node has <cfRule> node inside it | 
 |         if (!oldParentNode.HasChildNodes) | 
 |         { | 
 |           // Remove the old parent node | 
 |           oldParentNode.ParentNode.RemoveChild(oldParentNode); | 
 |         } | 
 |  | 
 |         _rules.Remove(item); | 
 |       } | 
 |       catch | 
 |       { | 
 |         throw new Exception( | 
 |           ExcelConditionalFormattingConstants.Errors.InvalidRemoveRuleOperation); | 
 |       } | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Remove a Conditional Formatting Rule by its 0-based index | 
 |     /// </summary> | 
 |     /// <param name="index"></param> | 
 |     public void RemoveAt( | 
 |       int index) | 
 |     { | 
 |       Require.Argument(index).IsInRange(0, this.Count - 1, "index"); | 
 |  | 
 |       Remove(this[index]); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Remove a Conditional Formatting Rule by its priority | 
 |     /// </summary> | 
 |     /// <param name="priority"></param> | 
 |     public void RemoveByPriority( | 
 |       int priority) | 
 |     { | 
 |       try | 
 |       { | 
 |         Remove(RulesByPriority(priority)); | 
 |       } | 
 |       catch | 
 |       { | 
 |       } | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Get a rule by its priority | 
 |     /// </summary> | 
 |     /// <param name="priority"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingRule RulesByPriority( | 
 |       int priority) | 
 |     { | 
 |       return _rules.Find(x => x.Priority == priority); | 
 |     } | 
 |     #endregion IEnumerable<IExcelConditionalFormatting> | 
 |  | 
 |     /****************************************************************************************/ | 
 |  | 
 |     #region Conditional Formatting Rules | 
 |     /// <summary> | 
 |     /// Add rule (internal) | 
 |     /// </summary> | 
 |     /// <param name="type"></param> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns>F | 
 |     internal IExcelConditionalFormattingRule AddRule( | 
 |       eExcelConditionalFormattingRuleType type, | 
 |       ExcelAddress address) | 
 |     { | 
 |       Require.Argument(address).IsNotNull("address"); | 
 |  | 
 |       address = ValidateAddress(address); | 
 |       EnsureRootElementExists(); | 
 |  | 
 |       // Create the Rule according to the correct type, address and priority | 
 |       IExcelConditionalFormattingRule cfRule = ExcelConditionalFormattingRuleFactory.Create( | 
 |         type, | 
 |         address, | 
 |         GetNextPriority(), | 
 |         _worksheet, | 
 |         null); | 
 |  | 
 |       // Add the newly created rule to the list | 
 |       _rules.Add(cfRule); | 
 |  | 
 |       // Return the newly created rule | 
 |       return cfRule; | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add AboveAverage Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingAverageGroup AddAboveAverage( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingAverageGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.AboveAverage, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add AboveOrEqualAverage Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingAverageGroup AddAboveOrEqualAverage( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingAverageGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.AboveOrEqualAverage, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add BelowAverage Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingAverageGroup AddBelowAverage( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingAverageGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.BelowAverage, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add BelowOrEqualAverage Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingAverageGroup AddBelowOrEqualAverage( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingAverageGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.BelowOrEqualAverage, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add AboveStdDev Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingStdDevGroup AddAboveStdDev( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingStdDevGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.AboveStdDev, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add BelowStdDev Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingStdDevGroup AddBelowStdDev( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingStdDevGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.BelowStdDev, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Bottom Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTopBottomGroup AddBottom( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTopBottomGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Bottom, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add BottomPercent Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTopBottomGroup AddBottomPercent( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTopBottomGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.BottomPercent, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Top Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTopBottomGroup AddTop( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTopBottomGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Top, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add TopPercent Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTopBottomGroup AddTopPercent( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTopBottomGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.TopPercent, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Last7Days Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddLast7Days( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Last7Days, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add LastMonth Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddLastMonth( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.LastMonth, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add LastWeek Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddLastWeek( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.LastWeek, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add NextMonth Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddNextMonth( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.NextMonth, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add NextWeek Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddNextWeek( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.NextWeek, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add ThisMonth Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddThisMonth( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.ThisMonth, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add ThisWeek Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddThisWeek( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.ThisWeek, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Today Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddToday( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Today, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Tomorrow Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddTomorrow( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Tomorrow, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Yesterday Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTimePeriodGroup AddYesterday( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTimePeriodGroup)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Yesterday, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add BeginsWith Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingBeginsWith AddBeginsWith( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingBeginsWith)AddRule( | 
 |         eExcelConditionalFormattingRuleType.BeginsWith, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Between Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingBetween AddBetween( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingBetween)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Between, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add ContainsBlanks Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingContainsBlanks AddContainsBlanks( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingContainsBlanks)AddRule( | 
 |         eExcelConditionalFormattingRuleType.ContainsBlanks, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add ContainsErrors Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingContainsErrors AddContainsErrors( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingContainsErrors)AddRule( | 
 |         eExcelConditionalFormattingRuleType.ContainsErrors, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add ContainsText Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingContainsText AddContainsText( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingContainsText)AddRule( | 
 |         eExcelConditionalFormattingRuleType.ContainsText, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add DuplicateValues Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingDuplicateValues AddDuplicateValues( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingDuplicateValues)AddRule( | 
 |         eExcelConditionalFormattingRuleType.DuplicateValues, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add EndsWith Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingEndsWith AddEndsWith( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingEndsWith)AddRule( | 
 |         eExcelConditionalFormattingRuleType.EndsWith, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Equal Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingEqual AddEqual( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingEqual)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Equal, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Expression Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingExpression AddExpression( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingExpression)AddRule( | 
 |         eExcelConditionalFormattingRuleType.Expression, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add GreaterThan Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingGreaterThan AddGreaterThan( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingGreaterThan)AddRule( | 
 |         eExcelConditionalFormattingRuleType.GreaterThan, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add GreaterThanOrEqual Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingGreaterThanOrEqual AddGreaterThanOrEqual( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingGreaterThanOrEqual)AddRule( | 
 |         eExcelConditionalFormattingRuleType.GreaterThanOrEqual, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add LessThan Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingLessThan AddLessThan( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingLessThan)AddRule( | 
 |         eExcelConditionalFormattingRuleType.LessThan, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add LessThanOrEqual Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingLessThanOrEqual AddLessThanOrEqual( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingLessThanOrEqual)AddRule( | 
 |         eExcelConditionalFormattingRuleType.LessThanOrEqual, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add NotBetween Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingNotBetween AddNotBetween( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingNotBetween)AddRule( | 
 |         eExcelConditionalFormattingRuleType.NotBetween, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add NotContainsBlanks Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingNotContainsBlanks AddNotContainsBlanks( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingNotContainsBlanks)AddRule( | 
 |         eExcelConditionalFormattingRuleType.NotContainsBlanks, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add NotContainsErrors Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingNotContainsErrors AddNotContainsErrors( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingNotContainsErrors)AddRule( | 
 |         eExcelConditionalFormattingRuleType.NotContainsErrors, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add NotContainsText Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingNotContainsText AddNotContainsText( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingNotContainsText)AddRule( | 
 |         eExcelConditionalFormattingRuleType.NotContainsText, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add NotEqual Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingNotEqual AddNotEqual( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingNotEqual)AddRule( | 
 |         eExcelConditionalFormattingRuleType.NotEqual, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add Unique Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingUniqueValues AddUniqueValues( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingUniqueValues)AddRule( | 
 |         eExcelConditionalFormattingRuleType.UniqueValues, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add ThreeColorScale Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingThreeColorScale AddThreeColorScale( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingThreeColorScale)AddRule( | 
 |         eExcelConditionalFormattingRuleType.ThreeColorScale, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add TwoColorScale Rule | 
 |     /// </summary> | 
 |     /// <param name="address"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingTwoColorScale AddTwoColorScale( | 
 |       ExcelAddress address) | 
 |     { | 
 |       return (IExcelConditionalFormattingTwoColorScale)AddRule( | 
 |         eExcelConditionalFormattingRuleType.TwoColorScale, | 
 |         address); | 
 |     } | 
 |  | 
 |     /// <summary> | 
 |     /// Add ThreeIconSet Rule | 
 |     /// </summary> | 
 |     /// <param name="Address">The address</param> | 
 |     /// <param name="IconSet">Type of iconset</param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingThreeIconSet<eExcelconditionalFormatting3IconsSetType> AddThreeIconSet(ExcelAddress Address, eExcelconditionalFormatting3IconsSetType IconSet) | 
 |     { | 
 |         var icon = (IExcelConditionalFormattingThreeIconSet<eExcelconditionalFormatting3IconsSetType>)AddRule( | 
 |             eExcelConditionalFormattingRuleType.ThreeIconSet, | 
 |             Address); | 
 |         icon.IconSet = IconSet; | 
 |         return icon; | 
 |     } | 
 |     /// <summary> | 
 |     /// Adds a FourIconSet rule | 
 |     /// </summary> | 
 |     /// <param name="Address"></param> | 
 |     /// <param name="IconSet"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingFourIconSet<eExcelconditionalFormatting4IconsSetType> AddFourIconSet(ExcelAddress Address, eExcelconditionalFormatting4IconsSetType IconSet) | 
 |     { | 
 |         var icon = (IExcelConditionalFormattingFourIconSet<eExcelconditionalFormatting4IconsSetType>)AddRule( | 
 |             eExcelConditionalFormattingRuleType.FourIconSet, | 
 |             Address); | 
 |         icon.IconSet = IconSet; | 
 |         return icon; | 
 |     } | 
 |     /// <summary> | 
 |     /// Adds a FiveIconSet rule | 
 |     /// </summary> | 
 |     /// <param name="Address"></param> | 
 |     /// <param name="IconSet"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingFiveIconSet AddFiveIconSet(ExcelAddress Address, eExcelconditionalFormatting5IconsSetType IconSet) | 
 |     { | 
 |         var icon = (IExcelConditionalFormattingFiveIconSet)AddRule( | 
 |             eExcelConditionalFormattingRuleType.FiveIconSet, | 
 |             Address); | 
 |         icon.IconSet = IconSet; | 
 |         return icon; | 
 |     } | 
 |     /// <summary> | 
 |     /// Adds a databar rule | 
 |     /// </summary> | 
 |     /// <param name="Address"></param> | 
 |     /// <param name="color"></param> | 
 |     /// <returns></returns> | 
 |     public IExcelConditionalFormattingDataBarGroup AddDatabar(ExcelAddress Address, Color color) | 
 |     { | 
 |         var dataBar = (IExcelConditionalFormattingDataBarGroup)AddRule( | 
 |             eExcelConditionalFormattingRuleType.DataBar, | 
 |             Address); | 
 |         dataBar.Color=color; | 
 |         return dataBar; | 
 |     } | 
 |     #endregion Conditional Formatting Rules | 
 |  | 
 |   } | 
 | } |