diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs index 13a6420..0eb27b1 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs @@ -43,7 +43,9 @@ } public T GetValue() { - if (Value is TimeSpan) + if (!StringExtensions.IsNullOrWhiteSpace(FormulaA1)) + return (T)Convert.ChangeType(String.Empty, typeof(T)); + else if (Value is TimeSpan) if (typeof(T) == typeof(String)) return (T)Convert.ChangeType(Value.ToString(), typeof(T)); else @@ -73,43 +75,49 @@ } public String GetFormattedString() { + String cValue; + if (StringExtensions.IsNullOrWhiteSpace(FormulaA1)) + cValue = cellValue; + else + cValue = GetString(); + if (dataType == XLCellValues.Boolean) { - return (cellValue != "0").ToString(); + return (cValue != "0").ToString(); } else if (dataType == XLCellValues.TimeSpan) { - return cellValue; + return cValue; } else if (dataType == XLCellValues.DateTime || IsDateFormat()) { Double dTest; - if (Double.TryParse(cellValue, out dTest)) + if (Double.TryParse(cValue, out dTest)) { String format = GetFormat(); return DateTime.FromOADate(dTest).ToString(format); } else { - return cellValue; + return cValue; } } else if (dataType == XLCellValues.Number) { Double dTest; - if (Double.TryParse(cellValue, out dTest)) + if (Double.TryParse(cValue, out dTest)) { String format = GetFormat(); return dTest.ToString(format); } else { - return cellValue; + return cValue; } } else { - return cellValue; + return cValue; } } @@ -145,28 +153,57 @@ { var fA1 = FormulaA1; if (!StringExtensions.IsNullOrWhiteSpace(fA1)) - return fA1; + { + String sName; + String cAddress; + if (fA1.Contains('!')) + { + sName = fA1.Substring(0, fA1.IndexOf('!')); + cAddress = fA1.Substring(fA1.IndexOf('!') + 1); + } + else + { + sName = Worksheet.Name; + cAddress = fA1; + } - if (dataType == XLCellValues.Boolean) - { - return cellValue != "0"; - } - else if (dataType == XLCellValues.DateTime) - { - return DateTime.FromOADate(Double.Parse(cellValue)); - } - else if (dataType == XLCellValues.Number) - { - return Double.Parse(cellValue); - } - else if (dataType == XLCellValues.TimeSpan) - { - //return (DateTime.FromOADate(Double.Parse(cellValue)) - baseDate); - return TimeSpan.Parse(cellValue); + + if (worksheet.Internals.Workbook.Worksheets.Where(w => w.Name == sName).Any() + && XLAddress.IsValidA1Address(cAddress) + ) + { + return worksheet.Internals.Workbook.Worksheet(sName).Cell(cAddress).Value; + } + else + { + return fA1; + } + + } else { - return cellValue; + if (dataType == XLCellValues.Boolean) + { + return cellValue != "0"; + } + else if (dataType == XLCellValues.DateTime) + { + return DateTime.FromOADate(Double.Parse(cellValue)); + } + else if (dataType == XLCellValues.Number) + { + return Double.Parse(cellValue); + } + else if (dataType == XLCellValues.TimeSpan) + { + //return (DateTime.FromOADate(Double.Parse(cellValue)) - baseDate); + return TimeSpan.Parse(cellValue); + } + else + { + return cellValue; + } } } set @@ -289,7 +326,8 @@ { foreach (DataColumn column in (m as DataRow).Table.Columns) { - SetValue(column.ColumnName, fRo, co); + var fieldName = StringExtensions.IsNullOrWhiteSpace(column.Caption) ? column.ColumnName : column.Caption; + SetValue(fieldName, fRo, co); co++; } co = Address.ColumnNumber; diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCells.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCells.cs index 92dd533..6e21c2f 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCells.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCells.cs @@ -35,12 +35,12 @@ var cells = from c in worksheet.Internals.CellsCollection where ( !StringExtensions.IsNullOrWhiteSpace(c.Value.InnerText) || (includeStyles && !c.Value.Style.Equals(worksheet.Style))) - && rangeAddresses.Where(r=> + && rangeAddresses.FirstOrDefault(r=> r.FirstAddress.RowNumber <= c.Key.RowNumber && r.FirstAddress.ColumnNumber <= c.Key.ColumnNumber && r.LastAddress.RowNumber >= c.Key.RowNumber && r.LastAddress.ColumnNumber >= c.Key.ColumnNumber - ).Any() + ) != null select (IXLCell)c.Value; foreach (var cell in cells) { diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidation.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidation.cs index cb7e199..80ef4b1 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidation.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidation.cs @@ -10,7 +10,7 @@ public enum XLOperator { EqualTo, NotEqualTo, GreaterThan, LessThan, EqualOrGreaterThan, EqualOrLessThan, Between, NotBetween } public interface IXLDataValidation { - IXLRange Range { get; set; } + IXLRanges Ranges { get; set; } void Delete(); void CopyFrom(IXLDataValidation dataValidation); Boolean ShowInputMessage { get; set; } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidations.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidations.cs index 661984c..a5bc443 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidations.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/IXLDataValidations.cs @@ -8,6 +8,5 @@ public interface IXLDataValidations: IEnumerable { void Add(IXLDataValidation dataValidation); - void Delete(IXLDataValidation dataValidation); } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidation.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidation.cs index 84d72e8..15b4865 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidation.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidation.cs @@ -7,19 +7,25 @@ { internal class XLDataValidation: IXLDataValidation { - public XLDataValidation(IXLRange range) + private XLWorksheet worksheet; + public XLDataValidation(IXLRanges ranges, XLWorksheet worksheet) { - this.Range = range; + this.Ranges = ranges; this.AllowedValues = XLAllowedValues.AnyValue; this.IgnoreBlanks = true; ShowErrorMessage = true; ShowInputMessage = true; InCellDropdown = true; + this.worksheet = worksheet; } - public IXLRange Range { get; set; } + public IXLRanges Ranges { get; set; } + public void Delete() { - ((XLRange)Range).Worksheet.DataValidations.Delete(this); + foreach (var dv in worksheet.DataValidations) + { + + } } public void CopyFrom(IXLDataValidation dataValidation) { diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidations.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidations.cs index 3753945..05aba35 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidations.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/DataValidation/XLDataValidations.cs @@ -7,20 +7,20 @@ { internal class XLDataValidations: IXLDataValidations { - private Dictionary dataValidations = new Dictionary(); + private List dataValidations = new List(); public void Add(IXLDataValidation dataValidation) { - dataValidations.Add(dataValidation.Range.RangeAddress.ToString(), dataValidation); + dataValidations.Add(dataValidation); } public void Delete(IXLDataValidation dataValidation) { - dataValidations.Remove(dataValidation.Range.RangeAddress.ToString()); + dataValidations.RemoveAll(dv=>dv.Ranges.Equals(dataValidation.Ranges)); } public IEnumerator GetEnumerator() { - return dataValidations.Values.GetEnumerator(); + return dataValidations.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs index c4903b0..a8371fc 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs @@ -5,6 +5,7 @@ namespace ClosedXML.Excel { + public enum XLWorksheetVisibility { Visible, Hidden, VeryHidden } public interface IXLWorksheet: IXLRangeBase { /// @@ -189,40 +190,40 @@ /// /// Collapses all outlined rows. /// - void CollapseRows(); + IXLWorksheet CollapseRows(); /// /// Collapses all outlined columns. /// - void CollapseColumns(); + IXLWorksheet CollapseColumns(); /// /// Expands all outlined rows. /// - void ExpandRows(); + IXLWorksheet ExpandRows(); /// /// Expands all outlined columns. /// - void ExpandColumns(); + IXLWorksheet ExpandColumns(); /// /// Collapses the outlined rows of the specified level. /// /// The outline level. - void CollapseRows(Int32 outlineLevel); + IXLWorksheet CollapseRows(Int32 outlineLevel); /// /// Collapses the outlined columns of the specified level. /// /// The outline level. - void CollapseColumns(Int32 outlineLevel); + IXLWorksheet CollapseColumns(Int32 outlineLevel); /// /// Expands the outlined rows of the specified level. /// /// The outline level. - void ExpandRows(Int32 outlineLevel); + IXLWorksheet ExpandRows(Int32 outlineLevel); /// /// Expands the outlined columns of the specified level. /// /// The outline level. - void ExpandColumns(Int32 outlineLevel); + IXLWorksheet ExpandColumns(Int32 outlineLevel); /// /// Deletes this worksheet. @@ -251,5 +252,9 @@ IXLRange RangeUsed(); IXLDataValidations DataValidations { get; } + + XLWorksheetVisibility Visibility { get; set; } + IXLWorksheet Hide(); + IXLWorksheet Unhide(); } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeBase.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeBase.cs index 5ce7046..679a856 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeBase.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeBase.cs @@ -141,6 +141,41 @@ void ClearStyles(); /// + /// Sets the cells' value. + /// If the object is an IEnumerable ClosedXML will copy the collection's data into a table starting from each cell. + /// If the object is a range ClosedXML will copy the range starting from each cell. + /// Setting the value to an object (not IEnumerable/range) will call the object's ToString() method. + /// ClosedXML will try to translate it to the corresponding type, if it can't then the value will be left as a string. + /// + /// + /// The object containing the value(s) to set. + /// + Object Value { set; } + + /// + /// Sets the type of the cells' data. + /// Changing the data type will cause ClosedXML to covert the current value to the new data type. + /// An exception will be thrown if the current value cannot be converted to the new data type. + /// + /// + /// The type of the cell's data. + /// + /// + XLCellValues DataType { set; } + + /// + /// Sets the cells' formula with A1 references. + /// + /// The formula with A1 references. + String FormulaA1 { set; } + + /// + /// Sets the cells' formula with R1C1 references. + /// + /// The formula with R1C1 references. + String FormulaR1C1 { set; } + + /// /// Converts this object to a range. /// IXLRange AsRange(); @@ -158,5 +193,7 @@ IXLHyperlinks Hyperlinks { get; } IXLDataValidation DataValidation { get; } + + } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRanges.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRanges.cs index 262b6cb..58ca6c7 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRanges.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRanges.cs @@ -22,6 +22,10 @@ /// The range to remove from this group. void Remove(IXLRange range); + Boolean Contains(IXLRange range); + IXLStyle Style { get; set; } + + IXLDataValidation DataValidation { get; } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs index c9d225b..2157026 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs @@ -29,7 +29,6 @@ ShiftRows(this.RangeAddress, range, rowsShifted); } - #region IXLRange Members public IXLRangeColumn FirstColumn() @@ -441,5 +440,18 @@ return new XLTable(this, name, true); } #endregion + + public override bool Equals(object obj) + { + var other = (XLRange)obj; + return this.RangeAddress.Equals(other.RangeAddress) + && this.Worksheet.Equals(other.Worksheet); + } + + public override int GetHashCode() + { + return RangeAddress.GetHashCode() + ^ this.Worksheet.GetHashCode(); + } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeAddress.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeAddress.cs index 386d15f..2ae8ce6 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeAddress.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeAddress.cs @@ -86,5 +86,18 @@ { return firstAddress.ToString() + ":" + lastAddress.ToString(); } + + public override bool Equals(object obj) + { + var other = (XLRangeAddress)obj; + return this.FirstAddress.Equals(other.FirstAddress) + && this.LastAddress.Equals(other.LastAddress); + } + + public override int GetHashCode() + { + return FirstAddress.GetHashCode() + ^ LastAddress.GetHashCode(); + } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs index 5c6d45d..b1aeb6a 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs @@ -893,40 +893,56 @@ get { String address = this.RangeAddress.ToString(); - if (Worksheet.DataValidations.Where(dv => dv.Range.RangeAddress.ToString() == address).Any()) + if (Worksheet.DataValidations.Where(dv => + dv.Ranges.Count() == 1 + && dv.Ranges.Contains(this.AsRange()) + ).Any()) { - return Worksheet.DataValidations.Where(dv => dv.Range.RangeAddress.ToString() == address).Single(); + return Worksheet.DataValidations.Where(dv => dv.Ranges.Contains(this.AsRange())).Single(); } else { - var dv = DataValidationsIntersects(); - if (dv != null) + foreach (var dv in Worksheet.DataValidations) { - dv.Delete(); - foreach (var c in dv.Range.Cells()) + foreach (var dvRange in dv.Ranges) { - if (!this.Contains(c.Address.ToString())) + if (dvRange.Intersects(this)) { - c.DataValidation.CopyFrom(dv); + dv.Ranges.Remove(dvRange); + foreach (var c in dvRange.Cells()) + { + if (!this.Contains(c.Address.ToString())) + dv.Ranges.Add(c.AsRange()); + } } } } - var dataValidation = new XLDataValidation(this.AsRange()); + var newRanges = new XLRanges(Worksheet.Internals.Workbook, Style); + newRanges.Add(this.AsRange()); + var dataValidation = new XLDataValidation(newRanges, Worksheet); + Worksheet.DataValidations.Add(dataValidation); return dataValidation; } } } - private IXLDataValidation DataValidationsIntersects() + public Object Value { - foreach (var dv in Worksheet.DataValidations) + set { - if (dv.Range.Intersects(this)) - return dv; + Cells().ForEach(c => c.Value = value); } - return null; } + + public XLCellValues DataType + { + set + { + Cells().ForEach(c => c.DataType = value); + } + } + } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs index 2c85a9f..b7eeb39 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs @@ -109,6 +109,83 @@ return retVal; } + public override bool Equals(object obj) + { + var other = (XLRanges)obj; + if (this.ranges.Count != other.ranges.Count) + { + return false; + } + else + { + foreach (var thisRange in this.ranges) + { + Boolean foundOne = false; + foreach (var otherRange in other.ranges) + { + if (thisRange.Equals(otherRange)) + { + foundOne = true; + break; + } + } + + if (!foundOne) + return false; + } + + return true; + } + } + + public Boolean Contains(IXLRange range) + { + foreach (var r in this.ranges) + { + if (r.Equals(range)) return true; + } + return false; + } + + public override int GetHashCode() + { + Int32 hash = 0; + foreach (var r in this.ranges) + { + hash ^= r.GetHashCode(); + } + return hash; + } + + public IXLDataValidation DataValidation + { + get + { + foreach (var range in ranges) + { + String address = range.RangeAddress.ToString(); + foreach (var dv in range.Worksheet.DataValidations) + { + foreach (var dvRange in dv.Ranges) + { + if (dvRange.Intersects(range)) + { + dv.Ranges.Remove(dvRange); + foreach (var c in dvRange.Cells()) + { + if (!range.Contains(c.Address.ToString())) + dv.Ranges.Add(c.AsRange()); + } + } + } + } + } + var dataValidation = new XLDataValidation(this, ranges.First().Worksheet); + + ranges.First().Worksheet.DataValidations.Add(dataValidation); + return dataValidation; + } + } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs index aa266ec..03b31d0 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs @@ -122,9 +122,9 @@ { Boolean retVal = true; String theColumn = column.ToUpper(); - for (Int32 i = 1; i <= column.Length; i++) + for (Int32 i = 0; i < column.Length; i++) { - if (theColumn[i] < 'A' || theColumn[i] > 'Z' || (i == 3 && theColumn[i] > 'D')) + if (theColumn[i] < 'A' || theColumn[i] > 'Z' || (i == 2 && theColumn[i] > 'D')) { retVal = false; break; @@ -134,6 +134,29 @@ } } + public static Boolean IsValidRow(String rowString) + { + Int32 row; + if (Int32.TryParse(rowString, out row)) + return row > 0 && row <= XLWorksheet.MaxNumberOfRows; + else + return false; + } + + public static Boolean IsValidA1Address(String address) + { + address = address.Replace("$", ""); + Int32 rowPos = 0; + while (rowPos < address.Length && (address[rowPos] > '9' || address[rowPos] < '0')) + rowPos++; + + return + rowPos < address.Length + && IsValidRow(address.Substring(rowPos)) + && IsValidColumn(address.Substring(0, rowPos)); + } + + /// /// Gets the column letter of a given column number. /// diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs index 716d107..1013d87 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs @@ -109,6 +109,10 @@ var ws = (XLWorksheet)Worksheets.Add(sheetName); ws.RelId = dSheet.Id; + + if (dSheet.State != null) + ws.Visibility = sheetStateValues.Single(p => p.Value == dSheet.State).Key; + var sheetFormatProperties = (SheetFormatProperties)worksheetPart.Worksheet.Descendants().First(); if (sheetFormatProperties.DefaultRowHeight != null) ws.RowHeight = sheetFormatProperties.DefaultRowHeight; @@ -407,21 +411,23 @@ var dataValidations = (DataValidations)dataValidationList.First(); foreach (var dvs in dataValidations.Descendants()) { - var dvt = ws.Range(dvs.SequenceOfReferences.InnerText).DataValidation; - if (dvs.AllowBlank != null) dvt.IgnoreBlanks = dvs.AllowBlank; - if (dvs.ShowDropDown != null) dvt.InCellDropdown = !dvs.ShowDropDown.Value; - if (dvs.ShowErrorMessage != null) dvt.ShowErrorMessage = dvs.ShowErrorMessage; - if (dvs.ShowInputMessage != null) dvt.ShowInputMessage = dvs.ShowInputMessage; - if (dvs.PromptTitle != null) dvt.InputTitle = dvs.PromptTitle; - if (dvs.Prompt != null) dvt.InputMessage = dvs.Prompt; - if (dvs.ErrorTitle != null) dvt.ErrorTitle = dvs.ErrorTitle; - if (dvs.Error != null) dvt.ErrorMessage = dvs.Error; - if (dvs.ErrorStyle != null) dvt.ErrorStyle = dataValidationErrorStyleValues.Single(p => p.Value == dvs.ErrorStyle).Key; - if (dvs.Type != null) dvt.AllowedValues = dataValidationValues.Single(p => p.Value == dvs.Type).Key; - if (dvs.Operator != null) dvt.Operator = dataValidationOperatorValues.Single(p => p.Value == dvs.Operator).Key; - if (dvs.Formula1 != null) dvt.MinValue = dvs.Formula1.Text; - if (dvs.Formula2 != null) dvt.MaxValue = dvs.Formula2.Text; - + foreach (String rangeAddress in dvs.SequenceOfReferences.InnerText.Split(' ')) + { + var dvt = ws.Range(rangeAddress).DataValidation; + if (dvs.AllowBlank != null) dvt.IgnoreBlanks = dvs.AllowBlank; + if (dvs.ShowDropDown != null) dvt.InCellDropdown = !dvs.ShowDropDown.Value; + if (dvs.ShowErrorMessage != null) dvt.ShowErrorMessage = dvs.ShowErrorMessage; + if (dvs.ShowInputMessage != null) dvt.ShowInputMessage = dvs.ShowInputMessage; + if (dvs.PromptTitle != null) dvt.InputTitle = dvs.PromptTitle; + if (dvs.Prompt != null) dvt.InputMessage = dvs.Prompt; + if (dvs.ErrorTitle != null) dvt.ErrorTitle = dvs.ErrorTitle; + if (dvs.Error != null) dvt.ErrorMessage = dvs.Error; + if (dvs.ErrorStyle != null) dvt.ErrorStyle = dataValidationErrorStyleValues.Single(p => p.Value == dvs.ErrorStyle).Key; + if (dvs.Type != null) dvt.AllowedValues = dataValidationValues.Single(p => p.Value == dvs.Type).Key; + if (dvs.Operator != null) dvt.Operator = dataValidationOperatorValues.Single(p => p.Value == dvs.Operator).Key; + if (dvs.Formula1 != null) dvt.MinValue = dvs.Formula1.Text; + if (dvs.Formula2 != null) dvt.MaxValue = dvs.Formula2.Text; + } } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs index 88ad821..69b6b9e 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs @@ -37,6 +37,7 @@ private List> dataValidationValues = new List>(); private List> dataValidationErrorStyleValues = new List>(); private List> dataValidationOperatorValues = new List>(); + private List> sheetStateValues = new List>(); private Boolean populated = false; private void PopulateEnums() @@ -60,6 +61,7 @@ PopulateDataValidationValues(); PopulateDataValidationErrorStyleValues(); PopulateDataValidationOperatorValues(); + PopulateSheetStateValues(); populated = true; } } @@ -307,6 +309,13 @@ dataValidationOperatorValues.Add(new KeyValuePair(XLOperator.NotEqualTo, DataValidationOperatorValues.NotEqual)); } + private void PopulateSheetStateValues() + { + sheetStateValues.Add(new KeyValuePair(XLWorksheetVisibility.Visible, SheetStateValues.Visible)); + sheetStateValues.Add(new KeyValuePair(XLWorksheetVisibility.Hidden, SheetStateValues.Hidden)); + sheetStateValues.Add(new KeyValuePair(XLWorksheetVisibility.VeryHidden, SheetStateValues.VeryHidden)); + } + #endregion private void CreatePackage(String filePath) @@ -641,7 +650,17 @@ xlSheet.SheetId = Int32.Parse(rId.Substring(3)); xlSheet.RelId = rId; - workbook.Sheets.Append(new Sheet() { Name = xlSheet.Name, Id = rId, SheetId = (UInt32)xlSheet.SheetId }); + var newSheet = new Sheet() + { + Name = xlSheet.Name, + Id = rId, + SheetId = (UInt32)xlSheet.SheetId + }; + + if (xlSheet.Visibility != XLWorksheetVisibility.Visible) + newSheet.State = sheetStateValues.Single(p => p.Key == xlSheet.Visibility).Value; + + workbook.Sheets.Append(newSheet); } var sheetElements = from sheet in workbook.Sheets.Elements() @@ -1985,6 +2004,13 @@ dataValidations.RemoveAllChildren(); foreach (var dv in xlWorksheet.DataValidations) { + String sequence = String.Empty; + foreach (var r in dv.Ranges) + { + sequence += r.RangeAddress.ToString() + " "; + } + sequence = sequence.Substring(0, sequence.Length - 1); + DataValidation dataValidation = new DataValidation() { AllowBlank = dv.IgnoreBlanks, @@ -2000,7 +2026,7 @@ ShowInputMessage = dv.ShowInputMessage, ErrorStyle = dataValidationErrorStyleValues.Single(p => p.Key == dv.ErrorStyle).Value, Operator = dataValidationOperatorValues.Single(p => p.Key == dv.Operator).Value, - SequenceOfReferences = new ListValue() { InnerText = dv.Range.RangeAddress.ToString() } + SequenceOfReferences = new ListValue() { InnerText = sequence } }; dataValidations.Append(dataValidation); diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs index b96268f..676c0ae 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs @@ -443,50 +443,58 @@ return Range(1, 1, XLWorksheet.MaxNumberOfRows, XLWorksheet.MaxNumberOfColumns); } - public void CollapseRows() + public IXLWorksheet CollapseRows() { Enumerable.Range(1, 8).ForEach(i => CollapseRows(i)); + return this; } - public void CollapseColumns() + public IXLWorksheet CollapseColumns() { Enumerable.Range(1, 8).ForEach(i => CollapseColumns(i)); + return this; } - public void ExpandRows() + public IXLWorksheet ExpandRows() { Enumerable.Range(1, 8).ForEach(i => ExpandRows(i)); + return this; } - public void ExpandColumns() + public IXLWorksheet ExpandColumns() { Enumerable.Range(1, 8).ForEach(i => ExpandRows(i)); + return this; } - - public void CollapseRows(Int32 outlineLevel) + + public IXLWorksheet CollapseRows(Int32 outlineLevel) { if (outlineLevel < 1 || outlineLevel > 8) throw new ArgumentOutOfRangeException("Outline level must be between 1 and 8."); Internals.RowsCollection.Values.Where(r => r.OutlineLevel == outlineLevel).ForEach(r => r.Collapse()); + return this; } - public void CollapseColumns(Int32 outlineLevel) + public IXLWorksheet CollapseColumns(Int32 outlineLevel) { if (outlineLevel < 1 || outlineLevel > 8) throw new ArgumentOutOfRangeException("Outline level must be between 1 and 8."); Internals.ColumnsCollection.Values.Where(c => c.OutlineLevel == outlineLevel).ForEach(c => c.Collapse()); + return this; } - public void ExpandRows(Int32 outlineLevel) + public IXLWorksheet ExpandRows(Int32 outlineLevel) { if (outlineLevel < 1 || outlineLevel > 8) throw new ArgumentOutOfRangeException("Outline level must be between 1 and 8."); Internals.RowsCollection.Values.Where(r => r.OutlineLevel == outlineLevel).ForEach(r => r.Expand()); + return this; } - public void ExpandColumns(Int32 outlineLevel) + public IXLWorksheet ExpandColumns(Int32 outlineLevel) { if (outlineLevel < 1 || outlineLevel > 8) throw new ArgumentOutOfRangeException("Outline level must be between 1 and 8."); Internals.ColumnsCollection.Values.Where(c => c.OutlineLevel == outlineLevel).ForEach(c => c.Expand()); + return this; } public void Delete() @@ -602,5 +610,18 @@ public new IXLHyperlinks Hyperlinks { get; private set; } public IXLDataValidations DataValidations { get; private set; } + + public XLWorksheetVisibility Visibility { get; set; } + public IXLWorksheet Hide() + { + Visibility = XLWorksheetVisibility.Hidden; + return this; + } + public IXLWorksheet Unhide() + { + Visibility = XLWorksheetVisibility.Visible; + return this; + } + } } diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj b/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj index b62fc6d..fd152ab 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj +++ b/ClosedXML/ClosedXML/ClosedXML_Examples/ClosedXML_Examples.csproj @@ -89,6 +89,7 @@ + diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs b/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs index 61a8bfb..1032a19 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs +++ b/ClosedXML/ClosedXML/ClosedXML_Examples/Creating/CreateFiles.cs @@ -70,6 +70,7 @@ new InsertingData().Create(@"C:\Excel Files\Created\InsertingData.xlsx"); new Hyperlinks().Create(@"C:\Excel Files\Created\Hyperlinks.xlsx"); new DataValidation().Create(@"C:\Excel Files\Created\DataValidation.xlsx"); + new HideSheets().Create(@"C:\Excel Files\Created\HideSheets.xlsx"); } } } diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/DataValidation.cs b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/DataValidation.cs index 2bc0e93..4ecb1e0 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/DataValidation.cs +++ b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/DataValidation.cs @@ -76,6 +76,21 @@ ws.Range("B1:B4").DataValidation.WholeNumber.EqualTo(1); ws.Range("B3:B4").DataValidation.WholeNumber.EqualTo(2); + + // Validate with multiple ranges + var ws2 = wb.Worksheets.Add("Validate Ranges"); + var rng1Validation = ws2.Ranges("A1:B2,B4:D7,F4:G5").DataValidation; + rng1Validation.Decimal.EqualTo(1); + rng1Validation.IgnoreBlanks = false; + + var rng2Validation = ws2.Range("A11:E14").DataValidation; + rng2Validation.Decimal.EqualTo(2); + rng2Validation.IgnoreBlanks = false; + + var rng3Validation = ws2.Range("B2:B12").DataValidation; + rng3Validation.Decimal.EqualTo(3); + rng3Validation.IgnoreBlanks = true; + wb.SaveAs(filePath); } diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/HideSheets.cs b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/HideSheets.cs new file mode 100644 index 0000000..25c3bfd --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/HideSheets.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ClosedXML.Excel; + +using System.Drawing; + +namespace ClosedXML_Examples.Misc +{ + public class HideSheets + { + #region Variables + + // Public + + // Private + + + #endregion + + #region Properties + + // Public + + // Private + + // Override + + + #endregion + + #region Events + + // Public + + // Private + + // Override + + + #endregion + + #region Methods + + // Public + public void Create(String filePath) + { + var wb = new XLWorkbook(); + + wb.Worksheets.Add("Visible"); + wb.Worksheets.Add("Hidden").Hide(); + wb.Worksheets.Add("Unhidden").Hide().Unhide(); + wb.Worksheets.Add("VeryHidden").Visibility = XLWorksheetVisibility.VeryHidden; + + wb.SaveAs(filePath); + } + + // Private + + // Override + + + #endregion + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/HideUnhide.cs b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/HideUnhide.cs index 274aab3..a43a0b2 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/HideUnhide.cs +++ b/ClosedXML/ClosedXML/ClosedXML_Examples/Misc/HideUnhide.cs @@ -47,7 +47,7 @@ public void Create(String filePath) { var wb = new XLWorkbook(); - var ws = wb.Worksheets.Add("Hide Unhide"); + var ws = wb.Worksheets.Add("Hide Rows Columns"); ws.Columns(1, 3).Hide(); ws.Rows(1, 3).Hide(); diff --git a/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs b/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs index 6ae10c6..427b44a 100644 --- a/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs +++ b/ClosedXML/ClosedXML/ClosedXML_Sandbox/Program.cs @@ -16,9 +16,14 @@ static void Main(string[] args) { //var fileName = "Issue_6266"; - var fileName = "Issue_6257"; - var wb = new XLWorkbook(String.Format(@"c:\Excel Files\ForTesting\{0}.xlsx", fileName)); - + //var fileName = "Issue_6257"; + var fileName = "Sandbox"; + //var wb = new XLWorkbook(String.Format(@"c:\Excel Files\ForTesting\{0}.xlsx", fileName)); + var wb = new XLWorkbook(); + var ws = wb.Worksheets.Add("New"); + ws.Range("A1:B1").Value = "X"; + ws.Cell(1, 1).AsRange().InsertRowsAbove(1); + wb.SaveAs(String.Format(@"c:\Excel Files\ForTesting\{0}_Saved.xlsx", fileName)); } @@ -91,23 +96,42 @@ List runningLoad = new List(); List runningSavedBack = new List(); - foreach (Int32 r in Enumerable.Range(1, 5)) + foreach (Int32 r in Enumerable.Range(1, 1)) { var wb = new XLWorkbook(); var startTotal = DateTime.Now; foreach (var i in Enumerable.Range(1, 1)) { var ws = wb.Worksheets.Add("Sheet" + i); - foreach (var ro in Enumerable.Range(1, 2000)) + foreach (var ro in Enumerable.Range(1, 50)) { - foreach (var co in Enumerable.Range(1, 100)) + foreach (var co in Enumerable.Range(1, 50)) { ws.Cell(ro, co).Style = GetRandomStyle(); ws.Cell(ro, co).Value = GetRandomValue(); } //System.Threading.Thread.Sleep(10); } + ws.RangeUsed().Style.Border.BottomBorder = XLBorderStyleValues.DashDot; + ws.RangeUsed().Style.Border.BottomBorderColor = XLColor.AirForceBlue; + ws.RangeUsed().Style.Border.TopBorder = XLBorderStyleValues.DashDotDot; + ws.RangeUsed().Style.Border.TopBorderColor = XLColor.AliceBlue; + ws.RangeUsed().Style.Border.LeftBorder = XLBorderStyleValues.Dashed; + ws.RangeUsed().Style.Border.LeftBorderColor = XLColor.Alizarin; + ws.RangeUsed().Style.Border.RightBorder = XLBorderStyleValues.Dotted; + ws.RangeUsed().Style.Border.RightBorderColor = XLColor.Almond; + + ws.RangeUsed().Style.Font.Bold = true; + ws.RangeUsed().Style.Font.FontColor = XLColor.Amaranth; + ws.RangeUsed().Style.Font.FontSize = 10; + ws.RangeUsed().Style.Font.Italic = true; + + ws.RangeUsed().Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; + ws.RangeUsed().Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; + ws.RangeUsed().Style.Alignment.WrapText = true; } + + //var start3 = DateTime.Now; //foreach (var ws in wb.Worksheets) //{