diff --git a/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj b/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj index c696db7..a59cf63 100644 --- a/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj +++ b/ClosedXML/ClosedXML/ClosedXML/ClosedXML.csproj @@ -48,19 +48,24 @@ + + + + + + + - + - - @@ -75,13 +80,12 @@ - - + - + @@ -93,7 +97,7 @@ - + diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/IXLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/IXLCell.cs new file mode 100644 index 0000000..0396c26 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/IXLCell.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + + +namespace ClosedXML.Excel +{ + public enum XLCellValues { Text, Number, Boolean, DateTime } + + public interface IXLCell: IXLStylized + { + String Value { get; set; } + IXLAddress Address { get; } + XLCellValues DataType { get; set; } + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs new file mode 100644 index 0000000..55e6dc3 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCell.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + + +namespace ClosedXML.Excel +{ + internal class XLCell : IXLCell + { + public XLCell(IXLAddress address, IXLStyle defaultStyle) + { + this.Address = address; + Style = defaultStyle; + if (Style == null) Style = XLWorkbook.DefaultStyle; + } + + public IXLAddress Address { get; private set; } + + private Boolean initialized = false; + private String cellValue = String.Empty; + public String Value + { + get + { + return cellValue; + } + set + { + String val = value; + Double dTest; + DateTime dtTest; + Boolean bTest; + if (initialized) + { + if (dataType == XLCellValues.Boolean) + { + if (Boolean.TryParse(val, out bTest)) + val = bTest ? "1" : "0"; + else if (!(val == "1" || val == "0")) + throw new ArgumentException("'" + val + "' is not a Boolean type."); + } + else if (dataType == XLCellValues.DateTime) + { + if (DateTime.TryParse(val, out dtTest)) + { + + val = dtTest.ToOADate().ToString(); + } + else if (!Double.TryParse(val, out dTest)) + { + throw new ArgumentException("'" + val + "' is not a DateTime type."); + } + + if (Style.NumberFormat.Format == String.Empty && Style.NumberFormat.NumberFormatId == 0) + Style.NumberFormat.NumberFormatId = 14; + } + else if (dataType == XLCellValues.Number) + { + if (!Double.TryParse(val, out dTest)) + throw new ArgumentException("'" + val + "' is not a Numeric type."); + + } + } + else + { + if (val.Length > 0 && val.Substring(0, 1) == "'") + { + val = val.Substring(1, val.Length - 1); + dataType = XLCellValues.Text; + } + else if (Double.TryParse(val, out dTest)) + { + dataType = XLCellValues.Number; + } + else if (DateTime.TryParse(val, out dtTest)) + { + dataType = XLCellValues.DateTime; + Style.NumberFormat.NumberFormatId = 14; + val = dtTest.ToOADate().ToString(); + } + else if (Boolean.TryParse(val, out bTest)) + { + dataType = XLCellValues.Boolean; + val = bTest ? "1" : "0"; + } + else + { + dataType = XLCellValues.Text; + } + } + cellValue = val; + } + } + + #region IXLStylized Members + + private IXLStyle style; + public IXLStyle Style + { + get + { + return style; + } + set + { + style = new XLStyle(null, value); + } + } + + public IEnumerable Styles + { + get + { + UpdatingStyle = true; + yield return style; + UpdatingStyle = false; + } + } + + public Boolean UpdatingStyle { get; set; } + + #endregion + + private XLCellValues dataType; + public XLCellValues DataType + { + get + { + return dataType; + } + set + { + initialized = true; + if (cellValue.Length > 0) + { + if (value == XLCellValues.Boolean) + { + Boolean bTest; + if (Boolean.TryParse(cellValue, out bTest)) + cellValue = Boolean.Parse(cellValue) ? "1" : "0"; + else + cellValue = value != 0 ? "1" : "0"; + } + else if (value == XLCellValues.DateTime) + { + DateTime dtTest; + Double dblTest; + if (DateTime.TryParse(cellValue, out dtTest)) + { + cellValue = dtTest.ToOADate().ToString(); + } + else if (Double.TryParse(cellValue, out dblTest)) + { + cellValue = dblTest.ToString(); + } + else + { + throw new ArgumentException("Cannot set data type to DateTime because '" + cellValue + "' is not recognized as a date."); + } + + if (Style.NumberFormat.Format == String.Empty && Style.NumberFormat.NumberFormatId == 0) + Style.NumberFormat.NumberFormatId = 14; + } + else if (value == XLCellValues.Number) + { + cellValue = Double.Parse(cellValue).ToString(); + //if (Style.NumberFormat.Format == String.Empty ) + // Style.NumberFormat.NumberFormatId = 0; + } + else + { + if (dataType == XLCellValues.Boolean) + { + cellValue = (cellValue == "0" ? false : true).ToString(); + } + else if (dataType == XLCellValues.Number) + { + cellValue = Double.Parse(cellValue).ToString(Style.NumberFormat.Format); + } + else if (dataType == XLCellValues.DateTime) + { + cellValue = DateTime.FromOADate(Double.Parse(cellValue)).ToString(Style.NumberFormat.Format); + } + } + } + dataType = value; + } + } + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCellCollection.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCellCollection.cs new file mode 100644 index 0000000..5b1afd0 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Cells/XLCellCollection.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + //internal delegate void RangeShiftedDelegate(XLRange range, Int32 cellsToShift, XLShiftDirection shiftDirection); + + internal class XLCellsCollection : IDictionary + { + //public event RangeShiftedDelegate RangeShifted; + + //public void ShiftRange(XLRange range, Int32 cellsToShift, XLShiftDirection shiftDirection) + //{ + + // foreach (var ro in dictionary.Keys.Where(k => k >= startingCell).OrderByDescending(k => k)) + // { + // var cellToMove = dictionary[ro]; + // var newCell = ro + cellsToShift; + // if (newCell <= XLWorksheet.MaxNumberOfCells) + // { + // var xlCellParameters = new XLCellParameters(cellToMove.Worksheet, cellToMove.Style, false); + // dictionary.Add(newCell, new XLCell(newCell, xlCellParameters)); + // } + // dictionary.Remove(ro); + + // if (RangeShifted != null) + // RangeShifted(ro, newCell); + // } + //} + + private Dictionary dictionary = new Dictionary(); + + public void Add(int key, XLCell value) + { + dictionary.Add(key, value); + } + + public bool ContainsKey(int key) + { + return dictionary.ContainsKey(key); + } + + public ICollection Keys + { + get { return dictionary.Keys; } + } + + public bool Remove(int key) + { + return dictionary.Remove(key); + } + + public bool TryGetValue(int key, out XLCell value) + { + return dictionary.TryGetValue(key, out value); + } + + public ICollection Values + { + get { return dictionary.Values; } + } + + public XLCell this[int key] + { + get + { + return dictionary[key]; + } + set + { + dictionary[key] = value; + } + } + + public void Add(KeyValuePair item) + { + dictionary.Add(item.Key, item.Value); + } + + public void Clear() + { + dictionary.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return dictionary.Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return dictionary.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove(KeyValuePair item) + { + return dictionary.Remove(item.Key); + } + + public IEnumerator> GetEnumerator() + { + return dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return dictionary.GetEnumerator(); + } + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs index e6f918b..00c5e4a 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumn.cs @@ -5,9 +5,14 @@ namespace ClosedXML.Excel { - public interface IXLColumn: IXLRange + public interface IXLColumn : IXLRangeBase { Double Width { get; set; } void Delete(); + Int32 ColumnNumber(); + String ColumnLetter(); + void InsertColumnsAfter(Int32 numberOfColumns); + void InsertColumnsBefore(Int32 numberOfColumns); + void Clear(); } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumns.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumns.cs index e313e45..4bb1d54 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumns.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/IXLColumns.cs @@ -9,7 +9,5 @@ { Double Width { set; } void Delete(); - void Add(IXLColumn column); - } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumn.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumn.cs index 70a15b7..caa6462 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumn.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumn.cs @@ -6,80 +6,187 @@ namespace ClosedXML.Excel { - public class XLColumn: IXLColumn + internal class XLColumn: XLRangeBase, IXLColumn { public XLColumn(Int32 column, XLColumnParameters xlColumnParameters) { - Internals = new XLRangeInternals(new XLAddress(1, column), new XLAddress(XLWorksheet.MaxNumberOfRows, column), xlColumnParameters.Worksheet); - RowNumber = 1; - ColumnNumber = column; - ColumnLetter = XLAddress.GetColumnLetterFromNumber(column); - this.style = new XLStyle(this, xlColumnParameters.DefaultStyle); - this.Width = XLWorkbook.DefaultColumnWidth; + SetColumnNumber(column); + Worksheet = xlColumnParameters.Worksheet; + + + this.IsReference = xlColumnParameters.IsReference; + if (IsReference) + { + Worksheet.RangeShiftedColumns += new RangeShiftedColumnsDelegate(Worksheet_RangeShiftedColumns); + } + else + { + this.style = new XLStyle(this, xlColumnParameters.DefaultStyle); + this.width = xlColumnParameters.Worksheet.DefaultColumnWidth; + } } - public Double Width { get; set; } - public Int32 RowNumber { get; private set; } - public Int32 ColumnNumber { get; private set; } - public String ColumnLetter { get; private set; } + + + void Worksheet_RangeShiftedColumns(XLRange range, int columnsShifted) + { + if (range.FirstAddressInSheet.ColumnNumber <= this.ColumnNumber()) + SetColumnNumber(this.ColumnNumber() + columnsShifted); + } + + private void SetColumnNumber(Int32 column) + { + FirstAddressInSheet = new XLAddress(1, column); + LastAddressInSheet = new XLAddress(XLWorksheet.MaxNumberOfRows, column); + } + + public Boolean IsReference { get; private set; } + + #region IXLColumn Members + + private Double width; + public Double Width + { + get + { + if (IsReference) + { + return Worksheet.Internals.ColumnsCollection[this.ColumnNumber()].Width; + } + else + { + return width; + } + } + set + { + if (IsReference) + { + Worksheet.Internals.ColumnsCollection[this.ColumnNumber()].Width = value; + } + else + { + width = value; + } + } + } + public void Delete() { - this.Column(ColumnNumber).Delete(XLShiftDeletedCells.ShiftCellsLeft); + var columnNumber = this.ColumnNumber(); + this.AsRange().Delete(XLShiftDeletedCells.ShiftCellsLeft); + Worksheet.Internals.ColumnsCollection.Remove(columnNumber); } + public void Clear() + { + var range = this.AsRange(); + range.Clear(); + this.Style = Worksheet.Style; + } + + #endregion + #region IXLStylized Members private IXLStyle style; - public IXLStyle Style + public override IXLStyle Style { get { - return style; + if (IsReference) + return Worksheet.Internals.ColumnsCollection[this.ColumnNumber()].Style; + else + return style; } set { - style = new XLStyle(this, value); + if (IsReference) + { + Worksheet.Internals.ColumnsCollection[this.ColumnNumber()].Style = value; + } + else + { + style = new XLStyle(this, value); + + foreach (var c in Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.ColumnNumber == this.ColumnNumber())) + { + c.Style = value; + } + + var maxRow = 0; + if (Worksheet.Internals.RowsCollection.Count > 0) + maxRow = Worksheet.Internals.RowsCollection.Keys.Max(); + + for (var ro = 1; ro <= maxRow; ro++) + { + Worksheet.Cell(ro, this.ColumnNumber()).Style = value; + } + } } } - public IEnumerable Styles + public override IEnumerable Styles { get { UpdatingStyle = true; - yield return style; - foreach (var c in Internals.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.Column == Internals.FirstCellAddress.Column)) + + yield return Style; + + var co = this.ColumnNumber(); + + foreach (var c in Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.ColumnNumber == co)) { yield return c.Style; } + + var maxRow = 0; + if (Worksheet.Internals.RowsCollection.Count > 0) + maxRow = Worksheet.Internals.RowsCollection.Keys.Max(); + + for (var ro = 1; ro <= maxRow; ro++) + { + yield return Worksheet.Cell(ro, co).Style; + } + UpdatingStyle = false; } } - public Boolean UpdatingStyle { get; set; } + public override Boolean UpdatingStyle { get; set; } #endregion - #region IXLRange Members - - public IXLRange Row(int row) + public Int32 ColumnNumber() { - var address = new XLAddress(row, 1); - return this.Range(address, address); + return this.FirstAddressInSheet.ColumnNumber; + } + public String ColumnLetter() + { + return this.FirstAddressInSheet.ColumnLetter; } - public IXLRange Column(int column) + public void InsertColumnsAfter( Int32 numberOfColumns) { - return this; + var columnNum = this.ColumnNumber(); + this.Worksheet.Internals.ColumnsCollection.ShiftColumnsRight(columnNum + 1, numberOfColumns); + XLRange range = (XLRange)this.Worksheet.Column(columnNum).AsRange(); + range.InsertColumnsAfter(numberOfColumns, true); + } + public void InsertColumnsBefore( Int32 numberOfColumns) + { + var columnNum = this.ColumnNumber(); + this.Worksheet.Internals.ColumnsCollection.ShiftColumnsRight(columnNum, numberOfColumns); + // We can't use this.AsRange() because we've shifted the columns + // and we want to use the old columnNum. + XLRange range = (XLRange)this.Worksheet.Column(columnNum).AsRange(); + range.InsertColumnsBefore(numberOfColumns, true); } - public IXLRange Column(string column) + public override IXLRange AsRange() { - return this; + return Range(1, 1, XLWorksheet.MaxNumberOfRows, 1); } - - #endregion - - public IXLRangeInternals Internals { get; private set; } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumnCollection.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumnCollection.cs new file mode 100644 index 0000000..e7e5bc8 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumnCollection.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + //internal delegate void ColumnDeletingDelegate(Int32 deletedColumn, Boolean beingShifted); + //internal delegate void ColumnShiftedDelegate(Int32 startingColumn, Int32 columnsShifted); + internal class XLColumnsCollection : IDictionary + { + //public event ColumnDeletingDelegate ColumnDeleting; + //public event ColumnShiftedDelegate ColumnShifted; + + //private Boolean beingShifted = false; + public void ShiftColumnsRight(Int32 startingColumn, Int32 columnsToShift) + { + //beingShifted = true; + foreach (var ro in dictionary.Keys.Where(k => k >= startingColumn).OrderByDescending(k => k)) + { + var columnToMove = dictionary[ro]; + var newColumn = ro + columnsToShift; + if (newColumn <= XLWorksheet.MaxNumberOfColumns) + { + var xlColumnParameters = new XLColumnParameters(columnToMove.Worksheet, columnToMove.Style, false); + dictionary.Add(newColumn, new XLColumn(newColumn, xlColumnParameters)); + } + dictionary.Remove(ro); + } + + //if (ColumnShifted != null) + // ColumnShifted(startingColumn, columnsToShift); + + //beingShifted = false; + } + + private Dictionary dictionary = new Dictionary(); + + public void Add(int key, XLColumn value) + { + dictionary.Add(key, value); + } + + public bool ContainsKey(int key) + { + return dictionary.ContainsKey(key); + } + + public ICollection Keys + { + get { return dictionary.Keys; } + } + + public bool Remove(int key) + { + //if (ColumnDeleting != null) + // ColumnDeleting(key, beingShifted); + + return dictionary.Remove(key); + } + + public bool TryGetValue(int key, out XLColumn value) + { + return dictionary.TryGetValue(key, out value); + } + + public ICollection Values + { + get { return dictionary.Values; } + } + + public XLColumn this[int key] + { + get + { + return dictionary[key]; + } + set + { + dictionary[key] = value; + } + } + + public void Add(KeyValuePair item) + { + dictionary.Add(item.Key, item.Value); + } + + public void Clear() + { + //if (ColumnDeleting != null) + // dictionary.ForEach(r => ColumnDeleting(r.Key, beingShifted)); + + dictionary.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return dictionary.Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return dictionary.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove(KeyValuePair item) + { + //if (ColumnDeleting != null) + // ColumnDeleting(item.Key, beingShifted); + + return dictionary.Remove(item.Key); + } + + public IEnumerator> GetEnumerator() + { + return dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return dictionary.GetEnumerator(); + } + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumnParameters.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumnParameters.cs index 967ad1a..cee2cc2 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumnParameters.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumnParameters.cs @@ -6,14 +6,16 @@ namespace ClosedXML.Excel { - public class XLColumnParameters + internal class XLColumnParameters { - public XLColumnParameters(IXLWorksheet worksheet, IXLStyle defaultStyle) + public XLColumnParameters(XLWorksheet worksheet, IXLStyle defaultStyle, Boolean isReference = true) { Worksheet = worksheet; DefaultStyle = defaultStyle; + IsReference = isReference; } public IXLStyle DefaultStyle { get; set; } - public IXLWorksheet Worksheet { get; private set; } + public XLWorksheet Worksheet { get; private set; } + public Boolean IsReference { get; private set; } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumns.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumns.cs index d3ef270..7282f6d 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumns.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Columns/XLColumns.cs @@ -5,17 +5,21 @@ namespace ClosedXML.Excel { - public class XLColumns: IXLColumns + internal class XLColumns: IXLColumns { - public XLColumns() + private Boolean entireWorksheet; + private XLWorksheet worksheet; + public XLColumns(XLWorksheet worksheet, Boolean entireWorksheet = false) { - Style = XLWorkbook.DefaultStyle; + this.worksheet = worksheet; + this.entireWorksheet = entireWorksheet; + Style = worksheet.Style; } - List columns = new List(); + List columns = new List(); public IEnumerator GetEnumerator() { - return columns.GetEnumerator(); + return columns.ToList().GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() @@ -35,7 +39,31 @@ set { style = new XLStyle(this, value); + //Styles.ForEach(s => s = new XLStyle(this, value)); + if (entireWorksheet) + { + worksheet.Style = value; + } + else + { + var maxRow = 0; + if (worksheet.Internals.RowsCollection.Count > 0) + maxRow = worksheet.Internals.RowsCollection.Keys.Max(); + foreach (var col in columns) + { + col.Style = value; + foreach (var c in col.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.ColumnNumber == col.FirstAddressInSheet.ColumnNumber)) + { + c.Style = value; + } + + for (var ro = 1; ro <= maxRow; ro++) + { + worksheet.Cell(ro, col.ColumnNumber()).Style = value; + } + } + } } } @@ -45,12 +73,27 @@ { UpdatingStyle = true; yield return style; - foreach (var col in columns) + if (entireWorksheet) { - yield return col.Style; - foreach (var c in col.Internals.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.Column == col.Internals.FirstCellAddress.Column)) + yield return worksheet.Style; + } + else + { + var maxRow = 0; + if (worksheet.Internals.RowsCollection.Count > 0) + maxRow = worksheet.Internals.RowsCollection.Keys.Max(); + foreach (var col in columns) { - yield return c.Style; + yield return col.Style; + foreach (var c in col.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.ColumnNumber == col.FirstAddressInSheet.ColumnNumber)) + { + yield return c.Style; + } + + for (var ro = 1; ro <= maxRow; ro++) + { + yield return worksheet.Cell(ro, col.ColumnNumber()).Style; + } } } UpdatingStyle = false; @@ -61,20 +104,39 @@ #endregion - public double Width + public Double Width { set { columns.ForEach(c => c.Width = value); + + if (entireWorksheet) + { + worksheet.DefaultColumnWidth = value; + worksheet.Internals.ColumnsCollection.ForEach(c => c.Value.Width = value); + } } } public void Delete() { - columns.ForEach(c => c.Delete(XLShiftDeletedCells.ShiftCellsLeft)); + if (entireWorksheet) + { + worksheet.Internals.ColumnsCollection.Clear(); + worksheet.Internals.CellsCollection.Clear(); + } + else + { + var toDelete = new List(); + foreach (var c in columns) + toDelete.Add(c.ColumnNumber()); + + foreach(var c in toDelete.OrderByDescending(c=>c)) + worksheet.Column(c).Delete(); + } } - public void Add(IXLColumn column) + public void Add(XLColumn column) { columns.Add(column); } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLAddress.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLAddress.cs index dd18368..ba6b523 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLAddress.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLAddress.cs @@ -5,10 +5,10 @@ namespace ClosedXML.Excel { - public interface IXLAddress : IEqualityComparer, IEquatable, IComparable, IComparable + public interface IXLAddress : IEqualityComparer, IEquatable, IComparable, IComparable { - Int32 Row { get; } - Int32 Column { get; } + Int32 RowNumber { get; } + Int32 ColumnNumber { get; } String ColumnLetter { get; } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLCell.cs deleted file mode 100644 index 0396c26..0000000 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLCell.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - - -namespace ClosedXML.Excel -{ - public enum XLCellValues { Text, Number, Boolean, DateTime } - - public interface IXLCell: IXLStylized - { - String Value { get; set; } - IXLAddress Address { get; } - XLCellValues DataType { get; set; } - } -} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorkbook.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorkbook.cs index 53cc4c2..b84e7a4 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorkbook.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorkbook.cs @@ -6,7 +6,7 @@ namespace ClosedXML.Excel { - public interface IXLWorkbook + public interface xIXLWorkbook { IXLWorksheets Worksheets { get; } String Name { get; } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs index 5aaa486..1351acb 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheet.cs @@ -5,21 +5,27 @@ namespace ClosedXML.Excel { - public interface IXLWorksheet: IXLRange + public interface IXLWorksheet: IXLRangeBase { - new IXLRow Row(Int32 row); - new IXLColumn Column(Int32 column); - new IXLColumn Column(String column); + Double DefaultColumnWidth { get; set; } + Double DefaultRowHeight { get; set; } + String Name { get; set; } + IXLPageOptions PageSetup { get; } + + IXLRow FirstRowUsed(); + IXLRow LastRowUsed(); + IXLColumn FirstColumnUsed(); + IXLColumn LastColumnUsed(); IXLColumns Columns(); IXLColumns Columns(String columns); IXLColumns Columns(String firstColumn, String lastColumn); IXLColumns Columns(Int32 firstColumn, Int32 lastColumn); IXLRows Rows(); IXLRows Rows(String rows); - IXLRows Rows(Int32 firstRow, Int32 lastRow); - - IXLPageSetup PageSetup { get; } - new IXLWorksheetInternals Internals { get; } + IXLRows Rows(Int32 firstRow, Int32 lastRow); + IXLRow Row(Int32 row); + IXLColumn Column(Int32 column); + IXLColumn Column(String column); } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheetInternals.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheetInternals.cs index f017348..2b4b3f5 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheetInternals.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/IXLWorksheetInternals.cs @@ -5,13 +5,11 @@ namespace ClosedXML.Excel { - public interface IXLWorksheetInternals + internal interface IXLWorksheetInternals { - IXLAddress FirstCellAddress { get; } - IXLAddress LastCellAddress { get; } Dictionary CellsCollection { get; } - Dictionary ColumnsCollection { get; } - Dictionary RowsCollection { get; } + XLColumnsCollection ColumnsCollection { get; } + XLRowsCollection RowsCollection { get; } List MergedCells { get; } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLMargins.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLMargins.cs new file mode 100644 index 0000000..68e28f6 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLMargins.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + public interface IXLMargins + { + Double Left { get; set; } + Double Right { get; set; } + Double Top { get; set; } + Double Bottom { get; set; } + Double Header { get; set; } + Double Footer { get; set; } + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLPageOptions.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLPageOptions.cs new file mode 100644 index 0000000..4526de7 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLPageOptions.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + public enum XLPageOrientation { Default, Portrait, Landscape } + public enum XLPaperSize + { + LetterPaper = 1, + LetterSmallPaper = 2, + TabloidPaper = 3, + LedgerPaper = 4, + LegalPaper = 5, + StatementPaper = 6, + ExecutivePaper = 7, + A3Paper = 8, + A4Paper = 9, + A4SmallPaper = 10, + A5Paper = 11, + B4Paper = 12, + B5Paper = 13, + FolioPaper = 14, + QuartoPaper = 15, + StandardPaper = 16, + StandardPaper1 = 17, + NotePaper = 18, + No9Envelope = 19, + No10Envelope = 20, + No11Envelope = 21, + No12Envelope = 22, + No14Envelope = 23, + CPaper = 24, + DPaper = 25, + EPaper = 26, + DlEnvelope = 27, + C5Envelope = 28, + C3Envelope = 29, + C4Envelope = 30, + C6Envelope = 31, + C65Envelope = 32, + B4Envelope = 33, + B5Envelope = 34, + B6Envelope = 35, + ItalyEnvelope = 36, + MonarchEnvelope = 37, + No634Envelope = 38, + UsStandardFanfold = 39, + GermanStandardFanfold = 40, + GermanLegalFanfold = 41, + IsoB4 = 42, + JapaneseDoublePostcard = 43, + StandardPaper2 = 44, + StandardPaper3 = 45, + StandardPaper4 = 46, + InviteEnvelope = 47, + LetterExtraPaper = 50, + LegalExtraPaper = 51, + TabloidExtraPaper = 52, + A4ExtraPaper = 53, + LetterTransversePaper = 54, + A4TransversePaper = 55, + LetterExtraTransversePaper = 56, + SuperaSuperaA4Paper = 57, + SuperbSuperbA3Paper = 58, + LetterPlusPaper = 59, + A4PlusPaper = 60, + A5TransversePaper = 61, + JisB5TransversePaper = 62, + A3ExtraPaper = 63, + A5ExtraPaper = 64, + IsoB5ExtraPaper = 65, + A2Paper = 66, + A3TransversePaper = 67, + A3ExtraTransversePaper = 68 + } + public enum XLPageOrderValues { DownThenOver, OverThenDown } + public enum XLShowCommentsValues { None, AtEnd, AsDisplayed } + public enum XLPrintErrorValues { Blank, Dash, Displayed, NA } + + public interface IXLPageOptions + { + IXLPrintAreas PrintAreas { get; } + Int32 FirstRowToRepeatAtTop { get; } + Int32 LastRowToRepeatAtTop { get; } + void SetRowsToRepeatAtTop(String range); + void SetRowsToRepeatAtTop(Int32 firstRowToRepeatAtTop, Int32 lastRowToRepeatAtTop); + Int32 FirstColumnToRepeatAtLeft { get; } + Int32 LastColumnToRepeatAtLeft { get; } + void SetColumnsToRepeatAtLeft(Int32 firstColumnToRepeatAtLeft, Int32 lastColumnToRepeatAtLeft); + void SetColumnsToRepeatAtLeft(String range); + XLPageOrientation PageOrientation { get; set; } + Int32 PagesWide { get; set; } + Int32 PagesTall { get; set; } + Int32 Scale { get; set; } + Int32 HorizontalDpi { get; set; } + Int32 VerticalDpi { get; set; } + Int32 FirstPageNumber { get; set; } + Boolean CenterHorizontally { get; set; } + Boolean CenterVertically { get; set; } + void AdjustTo(Int32 pctOfNormalSize); + void FitToPages(Int32 pagesWide, Int32 pagesTall); + XLPaperSize PaperSize { get; set; } + IXLMargins Margins { get; } + + IXLHeaderFooter Header { get; } + IXLHeaderFooter Footer { get; } + Boolean ScaleHFWithDocument { get; set; } + Boolean AlignHFWithMargins { get; set; } + + Boolean ShowGridlines { get; set; } + Boolean ShowRowAndColumnHeadings { get; set; } + Boolean BlackAndWhite { get; set; } + Boolean DraftQuality { get; set; } + XLPageOrderValues PageOrder { get; set; } + XLShowCommentsValues ShowComments { get; set; } + + + List RowBreaks { get; } + List ColumnBreaks { get; } + void AddHorizontalPageBreak(Int32 row); + void AddVerticalPageBreak(Int32 column); + + XLPrintErrorValues PrintErrorValue { get; set; } + + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLPageSetup.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLPageSetup.cs deleted file mode 100644 index e6dbc9a..0000000 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/IXLPageSetup.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace ClosedXML.Excel -{ - public enum XLPageOrientation { Default, Portrait, Landscape } - public enum XLPaperSize - { - LetterPaper = 1, - LetterSmallPaper = 2, - TabloidPaper = 3, - LedgerPaper = 4, - LegalPaper = 5, - StatementPaper = 6, - ExecutivePaper = 7, - A3Paper = 8, - A4Paper = 9, - A4SmallPaper = 10, - A5Paper = 11, - B4Paper = 12, - B5Paper = 13, - FolioPaper = 14, - QuartoPaper = 15, - StandardPaper = 16, - StandardPaper1 = 17, - NotePaper = 18, - No9Envelope = 19, - No10Envelope = 20, - No11Envelope = 21, - No12Envelope = 22, - No14Envelope = 23, - CPaper = 24, - DPaper = 25, - EPaper = 26, - DlEnvelope = 27, - C5Envelope = 28, - C3Envelope = 29, - C4Envelope = 30, - C6Envelope = 31, - C65Envelope = 32, - B4Envelope = 33, - B5Envelope = 34, - B6Envelope = 35, - ItalyEnvelope = 36, - MonarchEnvelope = 37, - No634Envelope = 38, - UsStandardFanfold = 39, - GermanStandardFanfold = 40, - GermanLegalFanfold = 41, - IsoB4 = 42, - JapaneseDoublePostcard = 43, - StandardPaper2 = 44, - StandardPaper3 = 45, - StandardPaper4 = 46, - InviteEnvelope = 47, - LetterExtraPaper = 50, - LegalExtraPaper = 51, - TabloidExtraPaper = 52, - A4ExtraPaper = 53, - LetterTransversePaper = 54, - A4TransversePaper = 55, - LetterExtraTransversePaper = 56, - SuperaSuperaA4Paper = 57, - SuperbSuperbA3Paper = 58, - LetterPlusPaper = 59, - A4PlusPaper = 60, - A5TransversePaper = 61, - JisB5TransversePaper = 62, - A3ExtraPaper = 63, - A5ExtraPaper = 64, - IsoB5ExtraPaper = 65, - A2Paper = 66, - A3TransversePaper = 67, - A3ExtraTransversePaper = 68 - } - public enum XLPageOrderValues { DownThenOver, OverThenDown } - public enum XLShowCommentsValues { None, AtEnd, AsDisplayed } - public enum XLPrintErrorValues { Blank, Dash, Displayed, NA } - - public interface IXLPageSetup - { - IXLPrintAreas PrintAreas { get; } - Int32 FirstRowToRepeatAtTop { get; } - Int32 LastRowToRepeatAtTop { get; } - void SetRowsToRepeatAtTop(String range); - void SetRowsToRepeatAtTop(Int32 firstRowToRepeatAtTop, Int32 lastRowToRepeatAtTop); - Int32 FirstColumnToRepeatAtLeft { get; } - Int32 LastColumnToRepeatAtLeft { get; } - void SetColumnsToRepeatAtLeft(Int32 firstColumnToRepeatAtLeft, Int32 lastColumnToRepeatAtLeft); - void SetColumnsToRepeatAtLeft(String range); - XLPageOrientation PageOrientation { get; set; } - Int32 PagesWide { get; set; } - Int32 PagesTall { get; set; } - Int32 Scale { get; set; } - Int32 HorizontalDpi { get; set; } - Int32 VerticalDpi { get; set; } - Int32 FirstPageNumber { get; set; } - Boolean CenterHorizontally { get; set; } - Boolean CenterVertically { get; set; } - void AdjustTo(Int32 pctOfNormalSize); - void FitToPages(Int32 pagesWide, Int32 pagesTall); - XLPaperSize PaperSize { get; set; } - XLMargins Margins { get; } - - IXLHeaderFooter Header { get; } - IXLHeaderFooter Footer { get; } - Boolean ScaleHFWithDocument { get; set; } - Boolean AlignHFWithMargins { get; set; } - - Boolean ShowGridlines { get; set; } - Boolean ShowRowAndColumnHeadings { get; set; } - Boolean BlackAndWhite { get; set; } - Boolean DraftQuality { get; set; } - XLPageOrderValues PageOrder { get; set; } - XLShowCommentsValues ShowComments { get; set; } - - - List RowBreaks { get; } - List ColumnBreaks { get; } - void AddHorizontalPageBreak(Int32 row); - void AddVerticalPageBreak(Int32 column); - - XLPrintErrorValues PrintErrorValue { get; set; } - - } -} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHFItem.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHFItem.cs index a592967..d5cc0bc 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHFItem.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHFItem.cs @@ -5,7 +5,7 @@ namespace ClosedXML.Excel { - public class XLHFItem: IXLHFItem + internal class XLHFItem : IXLHFItem { private Dictionary texts = new Dictionary(); public String GetText(XLHFOccurrence occurrence) diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHeaderFooter.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHeaderFooter.cs index d50ec98..1bef2b5 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHeaderFooter.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLHeaderFooter.cs @@ -5,7 +5,7 @@ namespace ClosedXML.Excel { - public class XLHeaderFooter: IXLHeaderFooter + internal class XLHeaderFooter: IXLHeaderFooter { public XLHeaderFooter() { diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLMargins.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLMargins.cs index 0a784c0..8ba86ad 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLMargins.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLMargins.cs @@ -5,7 +5,7 @@ namespace ClosedXML.Excel { - public class XLMargins + internal class XLMargins: IXLMargins { public Double Left { get; set; } public Double Right { get; set; } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPageOptions.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPageOptions.cs new file mode 100644 index 0000000..44bd8af --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPageOptions.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + internal class XLPageOptions : IXLPageOptions + { + public XLPageOptions(IXLPageOptions defaultPageOptions, XLWorksheet worksheet) + { + this.PrintAreas = new XLPrintAreas(worksheet); + if (defaultPageOptions != null) + { + this.CenterHorizontally = defaultPageOptions.CenterHorizontally; + this.CenterVertically = defaultPageOptions.CenterVertically; + this.FirstPageNumber = defaultPageOptions.FirstPageNumber; + this.HorizontalDpi = defaultPageOptions.HorizontalDpi; + this.PageOrientation = defaultPageOptions.PageOrientation; + this.VerticalDpi = defaultPageOptions.VerticalDpi; + + this.PaperSize = defaultPageOptions.PaperSize; + this.pagesTall = defaultPageOptions.PagesTall; + this.pagesWide = defaultPageOptions.PagesWide; + this.scale = defaultPageOptions.Scale; + + if (defaultPageOptions.Margins != null) + { + this.Margins = new XLMargins() + { + Top = defaultPageOptions.Margins.Top, + Bottom = defaultPageOptions.Margins.Bottom, + Left = defaultPageOptions.Margins.Left, + Right = defaultPageOptions.Margins.Right, + Header = defaultPageOptions.Margins.Header, + Footer = defaultPageOptions.Margins.Footer + }; + } + this.AlignHFWithMargins = defaultPageOptions.AlignHFWithMargins; + this.ScaleHFWithDocument = defaultPageOptions.ScaleHFWithDocument; + this.ShowGridlines = defaultPageOptions.ShowGridlines; + this.ShowRowAndColumnHeadings = defaultPageOptions.ShowRowAndColumnHeadings; + this.BlackAndWhite = defaultPageOptions.BlackAndWhite; + this.DraftQuality = defaultPageOptions.DraftQuality; + this.PageOrder = defaultPageOptions.PageOrder; + + this.ColumnBreaks = new List(); + this.RowBreaks = new List(); + this.PrintErrorValue = defaultPageOptions.PrintErrorValue; + } + Header = new XLHeaderFooter(); + Footer = new XLHeaderFooter(); + } + public IXLPrintAreas PrintAreas { get; private set; } + + + public Int32 FirstRowToRepeatAtTop { get; private set; } + public Int32 LastRowToRepeatAtTop { get; private set; } + public void SetRowsToRepeatAtTop(String range) + { + var arrRange = range.Replace("$", "").Split(':'); + SetRowsToRepeatAtTop(Int32.Parse(arrRange[0]), Int32.Parse(arrRange[1])); + } + public void SetRowsToRepeatAtTop(Int32 firstRowToRepeatAtTop, Int32 lastRowToRepeatAtTop) + { + if (firstRowToRepeatAtTop <= 0) throw new ArgumentOutOfRangeException("The first row has to be greater than zero."); + if (firstRowToRepeatAtTop > lastRowToRepeatAtTop) throw new ArgumentOutOfRangeException("The first row has to be less than the second row."); + + FirstRowToRepeatAtTop = firstRowToRepeatAtTop; + LastRowToRepeatAtTop = lastRowToRepeatAtTop; + } + public Int32 FirstColumnToRepeatAtLeft { get; private set; } + public Int32 LastColumnToRepeatAtLeft { get; private set; } + public void SetColumnsToRepeatAtLeft(String range) + { + var arrRange = range.Replace("$", "").Split(':'); + Int32 iTest; + if (Int32.TryParse(arrRange[0], out iTest)) + SetColumnsToRepeatAtLeft(Int32.Parse(arrRange[0]), Int32.Parse(arrRange[1])); + else + SetColumnsToRepeatAtLeft(arrRange[0], arrRange[1]); + } + public void SetColumnsToRepeatAtLeft(String firstColumnToRepeatAtLeft, String lastColumnToRepeatAtLeft) + { + SetColumnsToRepeatAtLeft(XLAddress.GetColumnNumberFromLetter(firstColumnToRepeatAtLeft), XLAddress.GetColumnNumberFromLetter(lastColumnToRepeatAtLeft)); + } + public void SetColumnsToRepeatAtLeft(Int32 firstColumnToRepeatAtLeft, Int32 lastColumnToRepeatAtLeft) + { + if (firstColumnToRepeatAtLeft <= 0) throw new ArgumentOutOfRangeException("The first column has to be greater than zero."); + if (firstColumnToRepeatAtLeft > lastColumnToRepeatAtLeft) throw new ArgumentOutOfRangeException("The first column has to be less than the second column."); + + FirstColumnToRepeatAtLeft = firstColumnToRepeatAtLeft; + LastColumnToRepeatAtLeft = lastColumnToRepeatAtLeft; + } + + public XLPageOrientation PageOrientation { get; set; } + public XLPaperSize PaperSize { get; set; } + public Int32 HorizontalDpi { get; set; } + public Int32 VerticalDpi { get; set; } + public Int32 FirstPageNumber { get; set; } + public Boolean CenterHorizontally { get; set; } + public Boolean CenterVertically { get; set; } + public XLPrintErrorValues PrintErrorValue { get; set; } + public IXLMargins Margins { get; set; } + + private Int32 pagesWide; + public Int32 PagesWide + { + get + { + return pagesWide; + } + set + { + pagesWide = value; + if (pagesWide >0) + scale = 0; + } + } + + private Int32 pagesTall; + public Int32 PagesTall + { + get + { + return pagesTall; + } + set + { + pagesTall = value; + if (pagesTall >0) + scale = 0; + } + } + + private Int32 scale; + public Int32 Scale + { + get + { + return scale; + } + set + { + scale = value; + if (scale > 0) + { + pagesTall = 0; + pagesWide = 0; + } + } + } + + public void AdjustTo(Int32 pctOfNormalSize) + { + Scale = pctOfNormalSize; + pagesWide = 0; + pagesTall = 0; + } + public void FitToPages(Int32 pagesWide, Int32 pagesTall) + { + this.pagesWide = pagesWide; + this.pagesTall = pagesTall; + scale = 0; + } + + + public IXLHeaderFooter Header { get; private set; } + public IXLHeaderFooter Footer { get; private set; } + + public Boolean ScaleHFWithDocument { get; set; } + public Boolean AlignHFWithMargins { get; set; } + + public Boolean ShowGridlines { get; set; } + public Boolean ShowRowAndColumnHeadings { get; set; } + public Boolean BlackAndWhite { get; set; } + public Boolean DraftQuality { get; set; } + + public XLPageOrderValues PageOrder { get; set; } + public XLShowCommentsValues ShowComments { get; set; } + + public List RowBreaks { get; private set; } + public List ColumnBreaks { get; private set; } + public void AddHorizontalPageBreak(Int32 row) + { + if (!RowBreaks.Contains(row)) + RowBreaks.Add(row); + } + public void AddVerticalPageBreak(Int32 column) + { + if (!ColumnBreaks.Contains(column)) + ColumnBreaks.Add(column); + } + + //public void SetPageBreak(IXLRange range, XLPageBreakLocations breakLocation) + //{ + // switch (breakLocation) + // { + // case XLPageBreakLocations.AboveRange: RowBreaks.Add(range.Internals.Worksheet.Row(range.RowNumber)); break; + // case XLPageBreakLocations.BelowRange: RowBreaks.Add(range.Internals.Worksheet.Row(range.RowCount())); break; + // case XLPageBreakLocations.LeftOfRange: ColumnBreaks.Add(range.Internals.Worksheet.Column(range.ColumnNumber)); break; + // case XLPageBreakLocations.RightOfRange: ColumnBreaks.Add(range.Internals.Worksheet.Column(range.ColumnCount())); break; + // default: throw new NotImplementedException(); + // } + //} + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPageSetup.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPageSetup.cs deleted file mode 100644 index 53dbbb4..0000000 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPageSetup.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace ClosedXML.Excel -{ - public class XLPageOptions : IXLPageSetup - { - public XLPageOptions(XLPageOptions defaultPageOptions, IXLWorksheet worksheet) - { - this.PrintAreas = new XLPrintAreas(worksheet); - if (defaultPageOptions != null) - { - this.CenterHorizontally = defaultPageOptions.CenterHorizontally; - this.CenterVertically = defaultPageOptions.CenterVertically; - this.FirstPageNumber = defaultPageOptions.FirstPageNumber; - this.HorizontalDpi = defaultPageOptions.HorizontalDpi; - this.PageOrientation = defaultPageOptions.PageOrientation; - this.VerticalDpi = defaultPageOptions.VerticalDpi; - - this.PaperSize = defaultPageOptions.PaperSize; - this.pagesTall = defaultPageOptions.pagesTall; - this.pagesWide = defaultPageOptions.pagesWide; - this.scale = defaultPageOptions.scale; - - if (defaultPageOptions.Margins != null) - { - this.Margins = new XLMargins() - { - Top = defaultPageOptions.Margins.Top, - Bottom = defaultPageOptions.Margins.Bottom, - Left = defaultPageOptions.Margins.Left, - Right = defaultPageOptions.Margins.Right, - Header = defaultPageOptions.Margins.Header, - Footer = defaultPageOptions.Margins.Footer - }; - } - this.AlignHFWithMargins = defaultPageOptions.AlignHFWithMargins; - this.ScaleHFWithDocument = defaultPageOptions.ScaleHFWithDocument; - this.ShowGridlines = defaultPageOptions.ShowGridlines; - this.ShowRowAndColumnHeadings = defaultPageOptions.ShowRowAndColumnHeadings; - this.BlackAndWhite = defaultPageOptions.BlackAndWhite; - this.DraftQuality = defaultPageOptions.DraftQuality; - this.PageOrder = defaultPageOptions.PageOrder; - - this.ColumnBreaks = new List(); - this.RowBreaks = new List(); - this.PrintErrorValue = defaultPageOptions.PrintErrorValue; - } - Header = new XLHeaderFooter(); - Footer = new XLHeaderFooter(); - } - public IXLPrintAreas PrintAreas { get; private set; } - - - public Int32 FirstRowToRepeatAtTop { get; private set; } - public Int32 LastRowToRepeatAtTop { get; private set; } - public void SetRowsToRepeatAtTop(String range) - { - var arrRange = range.Replace("$", "").Split(':'); - SetRowsToRepeatAtTop(Int32.Parse(arrRange[0]), Int32.Parse(arrRange[1])); - } - public void SetRowsToRepeatAtTop(Int32 firstRowToRepeatAtTop, Int32 lastRowToRepeatAtTop) - { - if (firstRowToRepeatAtTop <= 0) throw new ArgumentOutOfRangeException("The first row has to be greater than zero."); - if (firstRowToRepeatAtTop > lastRowToRepeatAtTop) throw new ArgumentOutOfRangeException("The first row has to be less than the second row."); - - FirstRowToRepeatAtTop = firstRowToRepeatAtTop; - LastRowToRepeatAtTop = lastRowToRepeatAtTop; - } - public Int32 FirstColumnToRepeatAtLeft { get; private set; } - public Int32 LastColumnToRepeatAtLeft { get; private set; } - public void SetColumnsToRepeatAtLeft(String range) - { - var arrRange = range.Replace("$", "").Split(':'); - Int32 iTest; - if (Int32.TryParse(arrRange[0], out iTest)) - SetColumnsToRepeatAtLeft(Int32.Parse(arrRange[0]), Int32.Parse(arrRange[1])); - else - SetColumnsToRepeatAtLeft(arrRange[0], arrRange[1]); - } - public void SetColumnsToRepeatAtLeft(String firstColumnToRepeatAtLeft, String lastColumnToRepeatAtLeft) - { - SetColumnsToRepeatAtLeft(XLAddress.GetColumnNumberFromLetter(firstColumnToRepeatAtLeft), XLAddress.GetColumnNumberFromLetter(lastColumnToRepeatAtLeft)); - } - public void SetColumnsToRepeatAtLeft(Int32 firstColumnToRepeatAtLeft, Int32 lastColumnToRepeatAtLeft) - { - if (firstColumnToRepeatAtLeft <= 0) throw new ArgumentOutOfRangeException("The first column has to be greater than zero."); - if (firstColumnToRepeatAtLeft > lastColumnToRepeatAtLeft) throw new ArgumentOutOfRangeException("The first column has to be less than the second column."); - - FirstColumnToRepeatAtLeft = firstColumnToRepeatAtLeft; - LastColumnToRepeatAtLeft = lastColumnToRepeatAtLeft; - } - - public XLPageOrientation PageOrientation { get; set; } - public XLPaperSize PaperSize { get; set; } - public Int32 HorizontalDpi { get; set; } - public Int32 VerticalDpi { get; set; } - public Int32 FirstPageNumber { get; set; } - public Boolean CenterHorizontally { get; set; } - public Boolean CenterVertically { get; set; } - public XLPrintErrorValues PrintErrorValue { get; set; } - public XLMargins Margins { get; set; } - - private Int32 pagesWide; - public Int32 PagesWide - { - get - { - return pagesWide; - } - set - { - pagesWide = value; - if (pagesWide >0) - scale = 0; - } - } - - private Int32 pagesTall; - public Int32 PagesTall - { - get - { - return pagesTall; - } - set - { - pagesTall = value; - if (pagesTall >0) - scale = 0; - } - } - - private Int32 scale; - public Int32 Scale - { - get - { - return scale; - } - set - { - scale = value; - if (scale > 0) - { - pagesTall = 0; - pagesWide = 0; - } - } - } - - public void AdjustTo(Int32 pctOfNormalSize) - { - Scale = pctOfNormalSize; - pagesWide = 0; - pagesTall = 0; - } - public void FitToPages(Int32 pagesWide, Int32 pagesTall) - { - this.pagesWide = pagesWide; - this.pagesTall = pagesTall; - scale = 0; - } - - - public IXLHeaderFooter Header { get; private set; } - public IXLHeaderFooter Footer { get; private set; } - - public Boolean ScaleHFWithDocument { get; set; } - public Boolean AlignHFWithMargins { get; set; } - - public Boolean ShowGridlines { get; set; } - public Boolean ShowRowAndColumnHeadings { get; set; } - public Boolean BlackAndWhite { get; set; } - public Boolean DraftQuality { get; set; } - - public XLPageOrderValues PageOrder { get; set; } - public XLShowCommentsValues ShowComments { get; set; } - - public List RowBreaks { get; private set; } - public List ColumnBreaks { get; private set; } - public void AddHorizontalPageBreak(Int32 row) - { - if (!RowBreaks.Contains(row)) - RowBreaks.Add(row); - } - public void AddVerticalPageBreak(Int32 column) - { - if (!ColumnBreaks.Contains(column)) - ColumnBreaks.Add(column); - } - - //public void SetPageBreak(IXLRange range, XLPageBreakLocations breakLocation) - //{ - // switch (breakLocation) - // { - // case XLPageBreakLocations.AboveRange: RowBreaks.Add(range.Internals.Worksheet.Row(range.RowNumber)); break; - // case XLPageBreakLocations.BelowRange: RowBreaks.Add(range.Internals.Worksheet.Row(range.RowCount())); break; - // case XLPageBreakLocations.LeftOfRange: ColumnBreaks.Add(range.Internals.Worksheet.Column(range.ColumnNumber)); break; - // case XLPageBreakLocations.RightOfRange: ColumnBreaks.Add(range.Internals.Worksheet.Column(range.ColumnCount())); break; - // default: throw new NotImplementedException(); - // } - //} - } -} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPrintAreas.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPrintAreas.cs index 5df4bbc..2a3481e 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPrintAreas.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/PrintOptions/XLPrintAreas.cs @@ -5,11 +5,11 @@ namespace ClosedXML.Excel { - public class XLPrintAreas: IXLPrintAreas + internal class XLPrintAreas : IXLPrintAreas { List ranges = new List(); - private IXLWorksheet worksheet; - public XLPrintAreas(IXLWorksheet worksheet) + private XLWorksheet worksheet; + public XLPrintAreas(XLWorksheet worksheet) { this.worksheet = worksheet; } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs index 077a0c1..c31761f 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRange.cs @@ -6,387 +6,33 @@ namespace ClosedXML.Excel { - public interface IXLRange: IXLStylized - { - IXLRange Row(Int32 row); - IXLRange Column(Int32 column); - IXLRange Column(String column); - Int32 RowNumber { get; } - Int32 ColumnNumber { get; } - String ColumnLetter { get; } - IXLRangeInternals Internals { get; } - } - public enum XLShiftDeletedCells { ShiftCellsUp, ShiftCellsLeft } - - public static class IXLRangeMethods + public interface IXLRange: IXLRangeBase { - public static IXLCell FirstCell(this IXLRange range) - { - return range.Cell(1, 1); - } - public static IXLCell LastCell(this IXLRange range) - { - return range.Cell(range.RowCount(), range.ColumnCount()); - } - - public static IXLCell Cell(this IXLRange range, IXLAddress cellAddressInRange) - { - IXLAddress absoluteAddress = (XLAddress)cellAddressInRange + (XLAddress)range.Internals.FirstCellAddress - 1; - if (range.Internals.Worksheet.Internals.CellsCollection.ContainsKey(absoluteAddress)) - { - return range.Internals.Worksheet.Internals.CellsCollection[absoluteAddress]; - } - else - { - var newCell = new XLCell(absoluteAddress, range.Style); - range.Internals.Worksheet.Internals.CellsCollection.Add(absoluteAddress, newCell); - return newCell; - } - } - public static IXLCell Cell(this IXLRange range, Int32 row, Int32 column) - { - return range.Cell(new XLAddress(row, column)); - } - public static IXLCell Cell(this IXLRange range, Int32 row, String column) - { - return range.Cell(new XLAddress(row, column)); - } - public static IXLCell Cell(this IXLRange range, String cellAddressInRange) - { - return range.Cell(new XLAddress(cellAddressInRange)); - } - - public static Int32 RowCount(this IXLRange range) - { - return range.Internals.LastCellAddress.Row - range.Internals.FirstCellAddress.Row + 1; - } - public static Int32 ColumnCount(this IXLRange range) - { - return range.Internals.LastCellAddress.Column - range.Internals.FirstCellAddress.Column + 1; - } - - public static IXLRange Range(this IXLRange range, Int32 firstCellRow, Int32 firstCellColumn, Int32 lastCellRow, Int32 lastCellColumn) - { - return range.Range(new XLAddress(firstCellRow, firstCellColumn), new XLAddress(lastCellRow, lastCellColumn)); - } - public static IXLRange Range(this IXLRange range, String rangeAddress) - { - if (rangeAddress.Contains(':')) - { - String[] arrRange = rangeAddress.Split(':'); - return range.Range(arrRange[0], arrRange[1]); - } - else - { - return range.Range(rangeAddress, rangeAddress); - } - } - public static IXLRange Range(this IXLRange range, String firstCellAddress, String lastCellAddress) - { - return range.Range(new XLAddress(firstCellAddress), new XLAddress(lastCellAddress)); - } - public static IXLRange Range(this IXLRange range, IXLAddress firstCellAddress, IXLAddress lastCellAddress) - { - var newFirstCellAddress = (XLAddress)firstCellAddress + (XLAddress)range.Internals.FirstCellAddress - 1; - var newLastCellAddress = (XLAddress)lastCellAddress + (XLAddress)range.Internals.FirstCellAddress - 1; - var xlRangeParameters = new XLRangeParameters(newFirstCellAddress, newLastCellAddress, range.Internals.Worksheet, range.Style); - if ( - newFirstCellAddress.Row < range.Internals.FirstCellAddress.Row - || newFirstCellAddress.Row > range.Internals.LastCellAddress.Row - || newLastCellAddress.Row > range.Internals.LastCellAddress.Row - || newFirstCellAddress.Column < range.Internals.FirstCellAddress.Column - || newFirstCellAddress.Column > range.Internals.LastCellAddress.Column - || newLastCellAddress.Column > range.Internals.LastCellAddress.Column - ) - throw new ArgumentOutOfRangeException(); - - return new XLRange(xlRangeParameters); - } - - public static IEnumerable Cells(this IXLRange range) - { - foreach(var row in Enumerable.Range(1, range.RowCount())) - { - foreach(var column in Enumerable.Range(1, range.ColumnCount())) - { - yield return range.Cell(row, column); - } - } - } - - public static void Merge(this IXLRange range) - { - var mergeRange = range.Internals.FirstCellAddress.ToString() + ":" + range.Internals.LastCellAddress.ToString(); - if (!range.Internals.Worksheet.Internals.MergedCells.Contains(mergeRange)) - range.Internals.Worksheet.Internals.MergedCells.Add(mergeRange); - } - public static void Unmerge(this IXLRange range) - { - range.Internals.Worksheet.Internals.MergedCells.Remove(range.Internals.FirstCellAddress.ToString() + ":" + range.Internals.LastCellAddress.ToString()); - } - - public static IXLRange FirstColumn(this IXLRange range) - { - return range.Column(1); - } - public static IXLRange LastColumn(this IXLRange range) - { - return range.Column(range.ColumnCount()); - } - public static IXLRange FirstRow(this IXLRange range) - { - return range.Row(1); - } - public static IXLRange LastRow(this IXLRange range) - { - return range.Row(range.RowCount()); - } - - public static void InsertRowsBelow(this IXLRange range, Int32 numberOfRows) - { - var cellsToInsert = new Dictionary(); - var cellsToDelete = new List(); - var lastRow = range.LastRow().RowNumber; - var firstColumn = range.FirstColumn().ColumnNumber; - var lastColumn = range.LastColumn().ColumnNumber; - foreach (var c in range.Internals.Worksheet.Internals.CellsCollection - .Where(c => - c.Key.Row > lastRow - && c.Key.Column >= firstColumn - && c.Key.Column <= lastColumn - )) - { - var newRow = c.Key.Row + numberOfRows; - var newKey = new XLAddress(newRow, c.Key.Column); - var newCell = new XLCell(newKey, c.Value.Style); - newCell.Value = c.Value.Value; - cellsToInsert.Add(newKey, newCell); - cellsToDelete.Add(c.Key); - } - cellsToDelete.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Remove(c)); - cellsToInsert.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); - } - public static void InsertRowsAbove(this IXLRange range, Int32 numberOfRows) - { - var cellsToInsert = new Dictionary(); - var cellsToDelete = new List(); - var firstRow = range.FirstRow().RowNumber; - var firstColumn = range.FirstColumn().ColumnNumber; - var lastColumn = range.LastColumn().ColumnNumber; - foreach (var c in range.Internals.Worksheet.Internals.CellsCollection - .Where(c => - c.Key.Row >= firstRow - && c.Key.Column >= firstColumn - && c.Key.Column <= lastColumn - )) - { - var newRow = c.Key.Row + numberOfRows; - var newKey = new XLAddress(newRow, c.Key.Column); - var newCell = new XLCell(newKey, c.Value.Style); - newCell.Value = c.Value.Value; - cellsToInsert.Add(newKey, newCell); - cellsToDelete.Add(c.Key); - } - cellsToDelete.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Remove(c)); - cellsToInsert.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); - } - - public static void InsertColumnsAfter(this IXLRange range, Int32 numberOfColumns) - { - var cellsToInsert = new Dictionary(); - var cellsToDelete = new List(); - var firstRow = range.FirstRow().RowNumber; - var lastRow = range.LastRow().RowNumber; - var lastColumn = range.LastColumn().ColumnNumber; - foreach (var c in range.Internals.Worksheet.Internals.CellsCollection - .Where(c => - c.Key.Column > lastColumn - && c.Key.Row >= firstRow - && c.Key.Row <= lastRow - )) - { - var newColumn = c.Key.Column + numberOfColumns; - var newKey = new XLAddress(c.Key.Row, newColumn); - var newCell = new XLCell(newKey, c.Value.Style); - newCell.Value = c.Value.Value; - cellsToInsert.Add(newKey, newCell); - cellsToDelete.Add(c.Key); - } - cellsToDelete.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Remove(c)); - cellsToInsert.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); - } - public static void InsertColumnsBefore(this IXLRange range, Int32 numberOfColumns) - { - var cellsToInsert = new Dictionary(); - var cellsToDelete = new List(); - var firstRow = range.FirstRow().RowNumber; - var lastRow = range.LastRow().RowNumber; - var firstColumn = range.FirstColumn().ColumnNumber; - foreach (var c in range.Internals.Worksheet.Internals.CellsCollection - .Where(c => - c.Key.Column >= firstColumn - && c.Key.Row >= firstRow - && c.Key.Row <= lastRow - )) - { - var newColumn = c.Key.Column + numberOfColumns; - var newKey = new XLAddress(c.Key.Row, newColumn); - var newCell = new XLCell(newKey, c.Value.Style); - newCell.Value = c.Value.Value; - cellsToInsert.Add(newKey, newCell); - cellsToDelete.Add(c.Key); - } - cellsToDelete.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Remove(c)); - cellsToInsert.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); - } - - public static IXLRanges Columns(this IXLRange range) - { - var retVal = new XLRanges(); - foreach (var c in Enumerable.Range(1, range.ColumnCount())) - { - retVal.Add(range.Column(c)); - } - return retVal; - } - public static IXLRanges Columns(this IXLRange range, String columns) - { - var retVal = new XLRanges(); - var columnPairs = columns.Split(','); - foreach (var pair in columnPairs) - { - String firstColumn; - String lastColumn; - if (pair.Contains(':')) - { - var columnRange = pair.Split(':'); - firstColumn = columnRange[0]; - lastColumn = columnRange[1]; - } - else - { - firstColumn = pair; - lastColumn = pair; - } - - Int32 tmp; - if (Int32.TryParse(firstColumn, out tmp)) - foreach (var col in range.Columns(Int32.Parse(firstColumn), Int32.Parse(lastColumn))) - { - retVal.Add(col); - } - else - foreach (var col in range.Columns(firstColumn, lastColumn)) - { - retVal.Add(col); - } - } - return retVal; - } - public static IXLRanges Columns(this IXLRange range, String firstColumn, String lastColumn) - { - return range.Columns(XLAddress.GetColumnNumberFromLetter(firstColumn), XLAddress.GetColumnNumberFromLetter(lastColumn)); - } - public static IXLRanges Columns(this IXLRange range, Int32 firstColumn, Int32 lastColumn) - { - var retVal = new XLRanges(); - - for (var co = firstColumn; co <= lastColumn; co++) - { - retVal.Add(range.Column(co)); - } - return retVal; - } - public static IXLRanges Rows(this IXLRange range) - { - var retVal = new XLRanges(); - foreach (var r in Enumerable.Range(1, range.RowCount())) - { - retVal.Add(range.Row(r)); - } - return retVal; - } - public static IXLRanges Rows(this IXLRange range, String rows) - { - var retVal = new XLRanges(); - var rowPairs = rows.Split(','); - foreach (var pair in rowPairs) - { - String firstRow; - String lastRow; - if (pair.Contains(':')) - { - var rowRange = pair.Split(':'); - firstRow = rowRange[0]; - lastRow = rowRange[1]; - } - else - { - firstRow = pair; - lastRow = pair; - } - foreach (var row in range.Rows(Int32.Parse(firstRow), Int32.Parse(lastRow))) - { - retVal.Add(row); - } - } - return retVal; - } - public static IXLRanges Rows(this IXLRange range, Int32 firstRow, Int32 lastRow) - { - var retVal = new XLRanges(); - - for(var ro = firstRow; ro <= lastRow; ro++) - { - retVal.Add(range.Row(ro)); - } - return retVal; - } - - public static void Clear(this IXLRange range) - { - // Remove cells inside range - range.Internals.Worksheet.Internals.CellsCollection.RemoveAll(c => - c.Address.Column >= range.ColumnNumber - && c.Address.Column <= range.LastColumn().ColumnNumber - && c.Address.Row >= range.RowNumber - && c.Address.Row <= range.LastRow().RowNumber - ); - } - public static void Delete(this IXLRange range, XLShiftDeletedCells shiftDeleteCells) - { - range.Clear(); - - // Range to shift... - var cellsToInsert = new Dictionary(); - var cellsToDelete = new List(); - var shiftLeft = range.Internals.Worksheet.Internals.CellsCollection - .Where(c => c.Key.Column > range.LastColumn().ColumnNumber - && c.Key.Row >= range.RowNumber - && c.Key.Row <= range.LastRow().RowNumber); - - var shiftUp = range.Internals.Worksheet.Internals.CellsCollection - .Where(c => - c.Key.Column >= range.ColumnNumber - && c.Key.Column <= range.LastColumn().ColumnNumber - && c.Key.Row > range.RowNumber); - - foreach (var c in shiftDeleteCells == XLShiftDeletedCells.ShiftCellsLeft ? shiftLeft : shiftUp) - { - var columnModifier = shiftDeleteCells == XLShiftDeletedCells.ShiftCellsLeft ? range.ColumnCount() : 0; - var rowModifier = shiftDeleteCells == XLShiftDeletedCells.ShiftCellsUp ? range.RowCount() : 0; - var newKey = new XLAddress(c.Key.Row - rowModifier, c.Key.Column - columnModifier); - var newCell = new XLCell(newKey, c.Value.Style); - newCell.Value = c.Value.Value; - cellsToInsert.Add(newKey, newCell); - cellsToDelete.Add(c.Key); - } - cellsToDelete.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Remove(c)); - cellsToInsert.ForEach(c => range.Internals.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); - - - } + IXLRange Column(int column); + IXLRange Column(string column); + IXLRanges Columns(); + IXLRanges Columns(int firstColumn, int lastColumn); + IXLRanges Columns(string columns); + IXLRanges Columns(string firstColumn, string lastColumn); + IXLRange FirstColumn(); + IXLRange FirstColumnUsed(); + IXLRange FirstRow(); + IXLRange FirstRowUsed(); + IXLRange LastColumn(); + IXLRange LastColumnUsed(); + IXLRange LastRow(); + IXLRange LastRowUsed(); + IXLRange Row(int row); + IXLRanges Rows(); + IXLRanges Rows(int firstRow, int lastRow); + IXLRanges Rows(string rows); + void InsertColumnsAfter(int numberOfColumns); + void InsertColumnsBefore(int numberOfColumns); + void InsertRowsAbove(int numberOfRows); + void InsertRowsBelow(int numberOfRows); + void Delete(XLShiftDeletedCells shiftDeleteCells); + void Clear(); } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeBase.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeBase.cs new file mode 100644 index 0000000..64d6685 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/IXLRangeBase.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + public interface IXLRangeBase: IXLStylized + { + IXLCell Cell(ClosedXML.Excel.IXLAddress cellAddressInRange); + IXLCell Cell(int row, int column); + IXLCell Cell(int row, string column); + IXLCell Cell(string cellAddressInRange); + IEnumerable Cells(); + IEnumerable CellsUsed(); + IXLAddress FirstAddressInSheet { get; } + IXLAddress LastAddressInSheet { get; } + IXLCell FirstCell(); + IXLCell LastCell(); + IXLRange Range(ClosedXML.Excel.IXLAddress firstCellAddress, ClosedXML.Excel.IXLAddress lastCellAddress); + IXLRange Range(int firstCellRow, int firstCellColumn, int lastCellRow, int lastCellColumn); + IXLRange Range(string firstCellAddress, string lastCellAddress); + IXLRange Range(string rangeAddress); + IXLRanges Ranges(params string[] ranges); + IXLRanges Ranges(string ranges); + int RowCount(); + int ColumnCount(); + void Unmerge(); + void Merge(); + IXLRange AsRange(); + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs index 9ad861a..1f220eb 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRange.cs @@ -6,21 +6,175 @@ namespace ClosedXML.Excel { - public class XLRange: IXLRange + internal class XLRange : XLRangeBase, IXLRange { - private IXLStyle defaultStyle; + public IXLStyle defaultStyle; public XLRange(XLRangeParameters xlRangeParameters) { - Internals = new XLRangeInternals(xlRangeParameters.FirstCellAddress, xlRangeParameters.LastCellAddress, xlRangeParameters.Worksheet); - RowNumber = xlRangeParameters.FirstCellAddress.Row; - ColumnNumber = xlRangeParameters.FirstCellAddress.Column; - ColumnLetter = xlRangeParameters.FirstCellAddress.ColumnLetter; + FirstAddressInSheet = xlRangeParameters.FirstCellAddress; + LastAddressInSheet = xlRangeParameters.LastCellAddress; + Worksheet = xlRangeParameters.Worksheet; + Worksheet.RangeShiftedRows += new RangeShiftedRowsDelegate(Worksheet_RangeShiftedRows); + Worksheet.RangeShiftedColumns += new RangeShiftedColumnsDelegate(Worksheet_RangeShiftedColumns); + //Worksheet.Internals.RowsCollection.RowShifted += new RowShiftedDelegate(RowsCollection_RowShifted); + //Worksheet.Internals.ColumnsCollection.ColumnShifted += new ColumnShiftedDelegate(ColumnsCollection_ColumnShifted); this.defaultStyle = new XLStyle(this, xlRangeParameters.DefaultStyle); } + void Worksheet_RangeShiftedColumns(XLRange range, int columnsShifted) + { + if (range.FirstAddressInSheet.RowNumber <= FirstAddressInSheet.RowNumber + && range.LastAddressInSheet.RowNumber >= LastAddressInSheet.RowNumber) + { + ColumnsCollection_ColumnShifted(range.FirstAddressInSheet.ColumnNumber, columnsShifted); + } + } + + void RowsCollection_RowShifted(int startingRow, int rowsShifted) + { + if (startingRow <= FirstAddressInSheet.RowNumber) + { + FirstAddressInSheet = new XLAddress(FirstAddressInSheet.RowNumber + rowsShifted, FirstAddressInSheet.ColumnNumber); + } + + if (startingRow <= LastAddressInSheet.RowNumber) + { + LastAddressInSheet = new XLAddress(LastAddressInSheet.RowNumber + rowsShifted, LastAddressInSheet.ColumnNumber); + } + } + + void ColumnsCollection_ColumnShifted(int startingColumn, int columnsShifted) + { + if (startingColumn <= FirstAddressInSheet.ColumnNumber) + { + FirstAddressInSheet = new XLAddress(FirstAddressInSheet.RowNumber, FirstAddressInSheet.ColumnNumber + columnsShifted); + } + + if (startingColumn <= LastAddressInSheet.ColumnNumber) + { + LastAddressInSheet = new XLAddress(LastAddressInSheet.RowNumber, LastAddressInSheet.ColumnNumber + columnsShifted); + } + } + + void Worksheet_RangeShiftedRows(XLRange range, int rowsShifted) + { + if (range.FirstAddressInSheet.ColumnNumber <= FirstAddressInSheet.ColumnNumber + && range.LastAddressInSheet.ColumnNumber >= LastAddressInSheet.ColumnNumber) + { + RowsCollection_RowShifted(range.FirstAddressInSheet.RowNumber, rowsShifted); + } + } + + #region IXLRange Members + public IXLRange FirstColumn() + { + return this.Column(1); + } + public IXLRange LastColumn() + { + return this.Column(this.ColumnCount()); + } + public IXLRange FirstColumnUsed() + { + var firstColumn = this.FirstAddressInSheet.ColumnNumber; + var columnCount = this.ColumnCount(); + Int32 minColumnUsed = Int32.MaxValue; + Int32 minColumnInCells = Int32.MaxValue; + if (this.Worksheet.Internals.CellsCollection.Any(c => c.Key.ColumnNumber >= firstColumn && c.Key.ColumnNumber <= columnCount)) + minColumnInCells = this.Worksheet.Internals.CellsCollection + .Where(c => c.Key.ColumnNumber >= firstColumn && c.Key.ColumnNumber <= columnCount).Select(c => c.Key.ColumnNumber).Min(); + + Int32 minCoInColumns = Int32.MaxValue; + if (this.Worksheet.Internals.ColumnsCollection.Any(c => c.Key >= firstColumn && c.Key <= columnCount)) + minCoInColumns = this.Worksheet.Internals.ColumnsCollection + .Where(c => c.Key >= firstColumn && c.Key <= columnCount).Select(c => c.Key).Min(); + + minColumnUsed = minColumnInCells < minCoInColumns ? minColumnInCells : minCoInColumns; + + if (minColumnUsed == Int32.MaxValue) + return null; + else + return this.Row(minColumnUsed); + } + public IXLRange LastColumnUsed() + { + var firstColumn = this.FirstAddressInSheet.ColumnNumber; + var columnCount = this.ColumnCount(); + Int32 maxColumnUsed = 0; + Int32 maxColumnInCells = 0; + if (this.Worksheet.Internals.CellsCollection.Any(c => c.Key.ColumnNumber >= firstColumn && c.Key.ColumnNumber <= columnCount)) + maxColumnInCells = this.Worksheet.Internals.CellsCollection + .Where(c => c.Key.ColumnNumber >= firstColumn && c.Key.ColumnNumber <= columnCount).Select(c => c.Key.ColumnNumber).Max(); + + Int32 maxCoInColumns = 0; + if (this.Worksheet.Internals.ColumnsCollection.Any(c => c.Key >= firstColumn && c.Key <= columnCount)) + maxCoInColumns = this.Worksheet.Internals.ColumnsCollection + .Where(c => c.Key >= firstColumn && c.Key <= columnCount).Select(c => c.Key).Max(); + + maxColumnUsed = maxColumnInCells > maxCoInColumns ? maxColumnInCells : maxCoInColumns; + + if (maxColumnUsed == 0) + return null; + else + return this.Column(maxColumnUsed); + } + + public IXLRange FirstRow() + { + return this.Row(1); + } + public IXLRange LastRow() + { + return this.Row(this.RowCount()); + } + public IXLRange FirstRowUsed() + { + var firstRow = this.FirstAddressInSheet.RowNumber; + var rowCount = this.RowCount(); + Int32 minRowUsed = Int32.MaxValue; + Int32 minRowInCells = Int32.MaxValue; + if (this.Worksheet.Internals.CellsCollection.Any(c => c.Key.RowNumber >= firstRow && c.Key.RowNumber <= rowCount)) + minRowInCells = this.Worksheet.Internals.CellsCollection + .Where(c => c.Key.RowNumber >= firstRow && c.Key.RowNumber <= rowCount).Select(c => c.Key.RowNumber).Min(); + + Int32 minRoInRows = Int32.MaxValue; + if (this.Worksheet.Internals.RowsCollection.Any(r => r.Key >= firstRow && r.Key <= rowCount)) + minRoInRows = this.Worksheet.Internals.RowsCollection + .Where(r => r.Key >= firstRow && r.Key <= rowCount).Select(r => r.Key).Min(); + + minRowUsed = minRowInCells < minRoInRows ? minRowInCells : minRoInRows; + + if (minRowUsed == Int32.MaxValue) + return null; + else + return this.Row(minRowUsed); + } + public IXLRange LastRowUsed() + { + var firstRow = this.FirstAddressInSheet.RowNumber; + var rowCount = this.RowCount(); + Int32 maxRowUsed = 0; + Int32 maxRowInCells = 0; + if (this.Worksheet.Internals.CellsCollection.Any(c => c.Key.RowNumber >= firstRow && c.Key.RowNumber <= rowCount)) + maxRowInCells = this.Worksheet.Internals.CellsCollection + .Where(c => c.Key.RowNumber >= firstRow && c.Key.RowNumber <= rowCount).Select(c => c.Key.RowNumber).Max(); + + Int32 maxRoInRows = 0; + if (this.Worksheet.Internals.RowsCollection.Any(r => r.Key >= firstRow && r.Key <= rowCount)) + maxRoInRows = this.Worksheet.Internals.RowsCollection + .Where(r => r.Key >= firstRow && r.Key <= rowCount).Select(r => r.Key).Max(); + + maxRowUsed = maxRowInCells > maxRoInRows ? maxRowInCells : maxRoInRows; + + if (maxRowUsed == 0) + return null; + else + return this.Row(maxRowUsed); + } + public IXLRange Row(Int32 row) { IXLAddress firstCellAddress = new XLAddress(row, 1); @@ -33,20 +187,368 @@ } public IXLRange Column(String column) { - return Column(XLAddress.GetColumnNumberFromLetter(column)); + return this.Column(XLAddress.GetColumnNumberFromLetter(column)); } - public Int32 RowNumber { get; private set; } - public Int32 ColumnNumber { get; private set; } - public String ColumnLetter { get; private set; } + public IXLRanges Columns() + { + var retVal = new XLRanges(); + foreach (var c in Enumerable.Range(1, this.ColumnCount())) + { + retVal.Add(this.Column(c)); + } + return retVal; + } + public IXLRanges Columns(String columns) + { + var retVal = new XLRanges(); + var columnPairs = columns.Split(','); + foreach (var pair in columnPairs) + { + String firstColumn; + String lastColumn; + if (pair.Contains(':')) + { + var columnRange = pair.Split(':'); + firstColumn = columnRange[0]; + lastColumn = columnRange[1]; + } + else + { + firstColumn = pair; + lastColumn = pair; + } - public IXLRangeInternals Internals { get; private set; } + Int32 tmp; + if (Int32.TryParse(firstColumn, out tmp)) + foreach (var col in this.Columns(Int32.Parse(firstColumn), Int32.Parse(lastColumn))) + { + retVal.Add(col); + } + else + foreach (var col in this.Columns(firstColumn, lastColumn)) + { + retVal.Add(col); + } + } + return retVal; + } + public IXLRanges Columns(String firstColumn, String lastColumn) + { + return this.Columns(XLAddress.GetColumnNumberFromLetter(firstColumn), XLAddress.GetColumnNumberFromLetter(lastColumn)); + } + public IXLRanges Columns(Int32 firstColumn, Int32 lastColumn) + { + var retVal = new XLRanges(); + + for (var co = firstColumn; co <= lastColumn; co++) + { + retVal.Add(this.Column(co)); + } + return retVal; + } + public IXLRanges Rows() + { + var retVal = new XLRanges(); + foreach (var r in Enumerable.Range(1, this.RowCount())) + { + retVal.Add(this.Row(r)); + } + return retVal; + } + public IXLRanges Rows(String rows) + { + var retVal = new XLRanges(); + var rowPairs = rows.Split(','); + foreach (var pair in rowPairs) + { + String firstRow; + String lastRow; + if (pair.Contains(':')) + { + var rowRange = pair.Split(':'); + firstRow = rowRange[0]; + lastRow = rowRange[1]; + } + else + { + firstRow = pair; + lastRow = pair; + } + foreach (var row in this.Rows(Int32.Parse(firstRow), Int32.Parse(lastRow))) + { + retVal.Add(row); + } + } + return retVal; + } + public IXLRanges Rows(Int32 firstRow, Int32 lastRow) + { + var retVal = new XLRanges(); + + for (var ro = firstRow; ro <= lastRow; ro++) + { + retVal.Add(this.Row(ro)); + } + return retVal; + } + + public void Clear() + { + // Remove cells inside range + this.Worksheet.Internals.CellsCollection.RemoveAll(c => + c.Address.ColumnNumber >= this.FirstAddressInSheet.ColumnNumber + && c.Address.ColumnNumber <= this.LastAddressInSheet.ColumnNumber + && c.Address.RowNumber >= this.FirstAddressInSheet.RowNumber + && c.Address.RowNumber <= this.LastAddressInSheet.RowNumber + ); + } + public void Delete(XLShiftDeletedCells shiftDeleteCells) + { + //this.Clear(); + + // Range to shift... + var cellsToInsert = new Dictionary(); + var cellsToDelete = new List(); + var shiftLeftQuery = this.Worksheet.Internals.CellsCollection + .Where(c => + c.Key.RowNumber >= this.FirstAddressInSheet.RowNumber + && c.Key.RowNumber <= this.LastAddressInSheet.RowNumber + && c.Key.ColumnNumber >= this.FirstAddressInSheet.ColumnNumber); + + var shiftUpQuery = this.Worksheet.Internals.CellsCollection + .Where(c => + c.Key.ColumnNumber >= this.FirstAddressInSheet.ColumnNumber + && c.Key.ColumnNumber <= this.LastAddressInSheet.ColumnNumber + && c.Key.RowNumber >= this.FirstAddressInSheet.RowNumber); + + var columnModifier = shiftDeleteCells == XLShiftDeletedCells.ShiftCellsLeft ? this.ColumnCount() : 0; + var rowModifier = shiftDeleteCells == XLShiftDeletedCells.ShiftCellsUp ? this.RowCount() : 0; + var cellsQuery = shiftDeleteCells == XLShiftDeletedCells.ShiftCellsLeft ? shiftLeftQuery : shiftUpQuery; + foreach (var c in cellsQuery) + { + var newKey = new XLAddress(c.Key.RowNumber - rowModifier, c.Key.ColumnNumber - columnModifier); + var newCell = new XLCell(newKey, c.Value.Style); + newCell.Value = c.Value.Value; + newCell.DataType = c.Value.DataType; + cellsToDelete.Add(c.Key); + + var canInsert = shiftDeleteCells == XLShiftDeletedCells.ShiftCellsLeft ? + c.Key.ColumnNumber > this.LastAddressInSheet.ColumnNumber : + c.Key.RowNumber > this.LastAddressInSheet.RowNumber; + + if (canInsert) + cellsToInsert.Add(newKey, newCell); + } + cellsToDelete.ForEach(c => this.Worksheet.Internals.CellsCollection.Remove(c)); + cellsToInsert.ForEach(c => this.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); + if (shiftDeleteCells == XLShiftDeletedCells.ShiftCellsUp) + { + Worksheet.NotifyRangeShiftedRows(this, rowModifier * -1); + } + else + { + Worksheet.NotifyRangeShiftedColumns(this, columnModifier * -1); + } + } + + public void InsertRowsBelow(Int32 numberOfRows) + { + this.InsertRowsBelow(numberOfRows, false); + } + internal void InsertRowsBelow(Int32 numberOfRows, Boolean onlyUsedCells) + { + var rowCount = this.RowCount(); + var firstRow = this.FirstAddressInSheet.RowNumber + rowCount; + if (firstRow > XLWorksheet.MaxNumberOfRows) firstRow = XLWorksheet.MaxNumberOfRows; + var lastRow = firstRow + this.RowCount() - 1; + if (lastRow > XLWorksheet.MaxNumberOfRows) lastRow = XLWorksheet.MaxNumberOfRows; + + var firstColumn = this.FirstAddressInSheet.ColumnNumber; + var lastColumn = firstColumn + this.ColumnCount() - 1; + if (lastColumn > XLWorksheet.MaxNumberOfColumns) lastColumn = XLWorksheet.MaxNumberOfColumns; + + var newRange = (XLRange)this.Worksheet.Range(firstRow, firstColumn, lastRow, lastColumn); + newRange.InsertRowsAbove(numberOfRows, onlyUsedCells); + } + public void InsertRowsAbove(Int32 numberOfRows) + { + this.InsertRowsAbove(numberOfRows, false); + } + internal void InsertRowsAbove(Int32 numberOfRows, Boolean onlyUsedCells) + { + var cellsToInsert = new Dictionary(); + var cellsToDelete = new List(); + var cellsToBlank = new List(); + var firstRow = this.FirstAddressInSheet.RowNumber; + var firstColumn = this.FirstAddressInSheet.ColumnNumber; + var lastColumn = this.FirstAddressInSheet.ColumnNumber + this.ColumnCount() - 1; + + if (!onlyUsedCells) + { + var lastRow = this.Worksheet.LastRowUsed().RowNumber(); + for (var ro = lastRow; ro >= firstRow; ro--) + { + for (var co = lastColumn; co >= firstColumn; co--) + { + var oldKey = new XLAddress(ro, co); + var newRow = ro + numberOfRows; + var newKey = new XLAddress(newRow, co); + IXLCell oldCell; + if (this.Worksheet.Internals.CellsCollection.ContainsKey(oldKey)) + { + oldCell = this.Worksheet.Internals.CellsCollection[oldKey]; + } + else + { + oldCell = this.Worksheet.Cell(oldKey); + } + var newCell = new XLCell(newKey, oldCell.Style); + newCell.Value = oldCell.Value; + newCell.DataType = oldCell.DataType; + cellsToInsert.Add(newKey, newCell); + cellsToDelete.Add(oldKey); + if (oldKey.RowNumber < firstRow + numberOfRows) + cellsToBlank.Add(oldKey); + } + } + } + else + { + foreach (var c in this.Worksheet.Internals.CellsCollection + .Where(c => + c.Key.RowNumber >= firstRow + && c.Key.ColumnNumber >= firstColumn + && c.Key.ColumnNumber <= lastColumn + )) + { + var newRow = c.Key.RowNumber + numberOfRows; + var newKey = new XLAddress(newRow, c.Key.ColumnNumber); + var newCell = new XLCell(newKey, c.Value.Style); + newCell.Value = c.Value.Value; + newCell.DataType = c.Value.DataType; + cellsToInsert.Add(newKey, newCell); + cellsToDelete.Add(c.Key); + if (c.Key.RowNumber < firstRow + numberOfRows) + cellsToBlank.Add(c.Key); + } + } + cellsToDelete.ForEach(c => this.Worksheet.Internals.CellsCollection.Remove(c)); + cellsToInsert.ForEach(c => this.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); + foreach (var c in cellsToBlank) + { + IXLStyle styleToUse; + if (this.Worksheet.Internals.ColumnsCollection.ContainsKey(c.ColumnNumber)) + styleToUse = this.Worksheet.Internals.ColumnsCollection[c.ColumnNumber].Style; + else + styleToUse = this.Worksheet.Style; + this.Worksheet.Cell(c).Style = styleToUse; + } + + Worksheet.NotifyRangeShiftedRows(this, numberOfRows); + } + + public void InsertColumnsAfter(Int32 numberOfColumns) + { + this.InsertColumnsAfter(numberOfColumns, false); + } + internal void InsertColumnsAfter(Int32 numberOfColumns, Boolean onlyUsedCells) + { + var columnCount = this.ColumnCount(); + var firstColumn = this.FirstAddressInSheet.ColumnNumber + columnCount; + if (firstColumn > XLWorksheet.MaxNumberOfColumns) firstColumn = XLWorksheet.MaxNumberOfColumns; + var lastColumn = firstColumn + this.ColumnCount() - 1; + if (lastColumn > XLWorksheet.MaxNumberOfColumns) lastColumn = XLWorksheet.MaxNumberOfColumns; + + var firstRow = this.FirstAddressInSheet.RowNumber; + var lastRow = firstRow + this.RowCount() - 1; + if (lastRow > XLWorksheet.MaxNumberOfRows) lastRow = XLWorksheet.MaxNumberOfRows; + + var newRange = (XLRange)this.Worksheet.Range(firstRow, firstColumn, lastRow, lastColumn); + newRange.InsertColumnsBefore(numberOfColumns, onlyUsedCells); + } + public void InsertColumnsBefore(Int32 numberOfColumns) + { + this.InsertColumnsBefore(numberOfColumns, false); + } + internal void InsertColumnsBefore(Int32 numberOfColumns, Boolean onlyUsedCells) + { + var cellsToInsert = new Dictionary(); + var cellsToDelete = new List(); + var cellsToBlank = new List(); + var firstColumn = this.FirstAddressInSheet.ColumnNumber; + var firstRow = this.FirstAddressInSheet.RowNumber; + var lastRow = this.FirstAddressInSheet.RowNumber + this.RowCount() - 1; + + if (!onlyUsedCells) + { + var lastColumn = this.Worksheet.LastColumnUsed().ColumnNumber(); + for (var co = lastColumn; co >= firstColumn; co--) + { + for (var ro = lastRow; ro >= firstRow; ro--) + { + var oldKey = new XLAddress(ro, co); + var newColumn = co + numberOfColumns; + var newKey = new XLAddress(ro, newColumn); + IXLCell oldCell; + if (this.Worksheet.Internals.CellsCollection.ContainsKey(oldKey)) + { + oldCell = this.Worksheet.Internals.CellsCollection[oldKey]; + } + else + { + oldCell = this.Worksheet.Cell(oldKey); + } + var newCell = new XLCell(newKey, oldCell.Style); + newCell.Value = oldCell.Value; + newCell.DataType = oldCell.DataType; + cellsToInsert.Add(newKey, newCell); + cellsToDelete.Add(oldKey); + if (oldKey.ColumnNumber < firstColumn + numberOfColumns) + cellsToBlank.Add(oldKey); + } + } + } + else + { + foreach (var c in this.Worksheet.Internals.CellsCollection + .Where(c => + c.Key.ColumnNumber >= firstColumn + && c.Key.RowNumber >= firstRow + && c.Key.RowNumber <= lastRow + )) + { + var newColumn = c.Key.ColumnNumber + numberOfColumns; + var newKey = new XLAddress(c.Key.RowNumber, newColumn); + var newCell = new XLCell(newKey, c.Value.Style); + newCell.Value = c.Value.Value; + newCell.DataType = c.Value.DataType; + cellsToInsert.Add(newKey, newCell); + cellsToDelete.Add(c.Key); + if (c.Key.ColumnNumber < firstColumn + numberOfColumns) + cellsToBlank.Add(c.Key); + } + } + cellsToDelete.ForEach(c => this.Worksheet.Internals.CellsCollection.Remove(c)); + cellsToInsert.ForEach(c => this.Worksheet.Internals.CellsCollection.Add(c.Key, c.Value)); + foreach (var c in cellsToBlank) + { + IXLStyle styleToUse; + if (this.Worksheet.Internals.RowsCollection.ContainsKey(c.RowNumber)) + styleToUse = this.Worksheet.Internals.RowsCollection[c.RowNumber].Style; + else + styleToUse = this.Worksheet.Style; + this.Worksheet.Cell(c).Style = styleToUse; + } + + Worksheet.NotifyRangeShiftedColumns(this, numberOfColumns); + } #endregion #region IXLStylized Members - public IXLStyle Style + public override IXLStyle Style { get { @@ -58,7 +560,7 @@ } } - public IEnumerable Styles + public override IEnumerable Styles { get { @@ -71,8 +573,19 @@ } } - public Boolean UpdatingStyle { get; set; } + public override Boolean UpdatingStyle { get; set; } #endregion + + public override IXLRange AsRange() + { + return this; + } + + public override string ToString() + { + return FirstAddressInSheet.ToString() + ":" + LastAddressInSheet.ToString(); + } + } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs new file mode 100644 index 0000000..e4fe333 --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeBase.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + internal abstract class XLRangeBase: IXLRangeBase + { + public IXLAddress FirstAddressInSheet { get; protected set; } + public IXLAddress LastAddressInSheet { get; protected set; } + internal XLWorksheet Worksheet { get; set; } + + public IXLCell FirstCell() + { + return this.Cell(1, 1); + } + public IXLCell LastCell() + { + return this.Cell(this.RowCount(), this.ColumnCount()); + } + + public IXLCell Cell( IXLAddress cellAddressInRange) + { + IXLAddress absoluteAddress = (XLAddress)cellAddressInRange + (XLAddress)this.FirstAddressInSheet - 1; + if (this.Worksheet.Internals.CellsCollection.ContainsKey(absoluteAddress)) + { + return this.Worksheet.Internals.CellsCollection[absoluteAddress]; + } + else + { + IXLStyle style = this.Style; + if (this.Style.ToString() == this.Worksheet.Style.ToString()) + { + if (this.Worksheet.Internals.RowsCollection.ContainsKey(absoluteAddress.RowNumber) + && this.Worksheet.Internals.RowsCollection[absoluteAddress.RowNumber].Style.ToString() != this.Worksheet.Style.ToString()) + style = this.Worksheet.Internals.RowsCollection[absoluteAddress.RowNumber].Style; + else if (this.Worksheet.Internals.ColumnsCollection.ContainsKey(absoluteAddress.ColumnNumber) + && this.Worksheet.Internals.ColumnsCollection[absoluteAddress.ColumnNumber].Style.ToString() != this.Worksheet.Style.ToString()) + style = this.Worksheet.Internals.ColumnsCollection[absoluteAddress.ColumnNumber].Style; + } + var newCell = new XLCell(absoluteAddress, style); + this.Worksheet.Internals.CellsCollection.Add(absoluteAddress, newCell); + return newCell; + } + } + public IXLCell Cell( Int32 row, Int32 column) + { + return this.Cell(new XLAddress(row, column)); + } + public IXLCell Cell( Int32 row, String column) + { + return this.Cell(new XLAddress(row, column)); + } + public IXLCell Cell( String cellAddressInRange) + { + return this.Cell(new XLAddress(cellAddressInRange)); + } + + public Int32 RowCount() + { + return this.LastAddressInSheet.RowNumber - this.FirstAddressInSheet.RowNumber + 1; + } + public Int32 ColumnCount() + { + return this.LastAddressInSheet.ColumnNumber - this.FirstAddressInSheet.ColumnNumber + 1; + } + + public IXLRange Range( Int32 firstCellRow, Int32 firstCellColumn, Int32 lastCellRow, Int32 lastCellColumn) + { + return this.Range(new XLAddress(firstCellRow, firstCellColumn), new XLAddress(lastCellRow, lastCellColumn)); + } + public IXLRange Range( String rangeAddress) + { + if (rangeAddress.Contains(':')) + { + String[] arrRange = rangeAddress.Split(':'); + return this.Range(arrRange[0], arrRange[1]); + } + else + { + return this.Range(rangeAddress, rangeAddress); + } + } + public IXLRange Range( String firstCellAddress, String lastCellAddress) + { + return this.Range(new XLAddress(firstCellAddress), new XLAddress(lastCellAddress)); + } + public IXLRange Range( IXLAddress firstCellAddress, IXLAddress lastCellAddress) + { + var newFirstCellAddress = (XLAddress)firstCellAddress + (XLAddress)this.FirstAddressInSheet - 1; + var newLastCellAddress = (XLAddress)lastCellAddress + (XLAddress)this.FirstAddressInSheet - 1; + var xlRangeParameters = new XLRangeParameters(newFirstCellAddress, newLastCellAddress, this.Worksheet, this.Style); + if ( + newFirstCellAddress.RowNumber < this.FirstAddressInSheet.RowNumber + || newFirstCellAddress.RowNumber > this.LastAddressInSheet.RowNumber + || newLastCellAddress.RowNumber > this.LastAddressInSheet.RowNumber + || newFirstCellAddress.ColumnNumber < this.FirstAddressInSheet.ColumnNumber + || newFirstCellAddress.ColumnNumber > this.LastAddressInSheet.ColumnNumber + || newLastCellAddress.ColumnNumber > this.LastAddressInSheet.ColumnNumber + ) + throw new ArgumentOutOfRangeException(String.Format("The cells {0} and {1} are outside the range '{2}'.", firstCellAddress.ToString(), lastCellAddress.ToString(), this.ToString())); + + return new XLRange(xlRangeParameters); + } + + public IXLRanges Ranges( String ranges) + { + var retVal = new XLRanges(); + var rangePairs = ranges.Split(','); + foreach (var pair in rangePairs) + { + retVal.Add(this.Range(pair)); + } + return retVal; + } + public IXLRanges Ranges( params String[] ranges) + { + var retVal = new XLRanges(); + foreach (var pair in ranges) + { + retVal.Add(this.Range(pair)); + } + return retVal; + } + + public IEnumerable Cells() + { + foreach (var row in Enumerable.Range(1, this.RowCount())) + { + foreach (var column in Enumerable.Range(1, this.ColumnCount())) + { + yield return this.Cell(row, column); + } + } + } + public IEnumerable CellsUsed() + { + return this.Worksheet.Internals.CellsCollection.Values.AsEnumerable(); + } + + public void Merge() + { + var mergeRange = this.FirstAddressInSheet.ToString() + ":" + this.LastAddressInSheet.ToString(); + if (!this.Worksheet.Internals.MergedCells.Contains(mergeRange)) + this.Worksheet.Internals.MergedCells.Add(mergeRange); + } + public void Unmerge() + { + this.Worksheet.Internals.MergedCells.Remove(this.FirstAddressInSheet.ToString() + ":" + this.LastAddressInSheet.ToString()); + } + + public abstract IXLStyle Style { get; set; } + + public abstract IEnumerable Styles { get; } + + public abstract Boolean UpdatingStyle { get; set; } + + public abstract IXLRange AsRange(); + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeParameters.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeParameters.cs index d399710..10e8940 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeParameters.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRangeParameters.cs @@ -6,9 +6,9 @@ namespace ClosedXML.Excel { - public class XLRangeParameters + internal class XLRangeParameters { - public XLRangeParameters(IXLAddress firstCellAddress, IXLAddress lastCellAddress, IXLWorksheet worksheet, IXLStyle defaultStyle) + public XLRangeParameters(IXLAddress firstCellAddress, IXLAddress lastCellAddress, XLWorksheet worksheet, IXLStyle defaultStyle) { FirstCellAddress = firstCellAddress; LastCellAddress = lastCellAddress; @@ -20,7 +20,7 @@ // Public public IXLAddress FirstCellAddress { get; private set; } public IXLAddress LastCellAddress { get; private set; } - public IXLWorksheet Worksheet { get; private set; } + public XLWorksheet Worksheet { get; private set; } public IXLStyle DefaultStyle { get; private set; } // Private diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs index 504951d..d50e3d1 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Ranges/XLRanges.cs @@ -5,14 +5,14 @@ namespace ClosedXML.Excel { - public class XLRanges: IXLRanges + internal class XLRanges : IXLRanges { public XLRanges() { Style = XLWorkbook.DefaultStyle; } - List ranges = new List(); + List ranges = new List(); public void Clear() { @@ -21,12 +21,12 @@ public void Add(IXLRange range) { - ranges.Add(range); + ranges.Add((XLRange)range); } public IEnumerator GetEnumerator() { - return ranges.GetEnumerator(); + return ranges.ToList().GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() @@ -59,11 +59,11 @@ foreach (var rng in ranges) { yield return rng.Style; - foreach (var r in rng.Internals.Worksheet.Internals.CellsCollection.Values.Where(c => - c.Address.Row >= rng.Internals.FirstCellAddress.Row - && c.Address.Row <= rng.Internals.LastCellAddress.Row - && c.Address.Column >= rng.Internals.FirstCellAddress.Column - && c.Address.Column <= rng.Internals.LastCellAddress.Column + foreach (var r in rng.Worksheet.Internals.CellsCollection.Values.Where(c => + c.Address.RowNumber >= rng.FirstAddressInSheet.RowNumber + && c.Address.RowNumber <= rng.LastAddressInSheet.RowNumber + && c.Address.ColumnNumber >= rng.FirstAddressInSheet.ColumnNumber + && c.Address.ColumnNumber <= rng.LastAddressInSheet.ColumnNumber )) { yield return r.Style; diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs index a62a0fd..e0794ec 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRow.cs @@ -5,15 +5,13 @@ namespace ClosedXML.Excel { - public interface IXLRow: IXLRange + public interface IXLRow : IXLRangeBase { Double Height { get; set; } void Delete(); - - } - - public static class IXLRowMethods - { - + Int32 RowNumber(); + void InsertRowsBelow(Int32 numberOfRows); + void InsertRowsAbove(Int32 numberOfRows); + void Clear(); } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRows.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRows.cs index 5ba82e6..487a718 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRows.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/IXLRows.cs @@ -9,7 +9,6 @@ { Double Height { set; } void Delete(); - void Add(IXLRow row); - + //void Add(IXLRow row); } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRow.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRow.cs index 28506a4..c23cbe7 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRow.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRow.cs @@ -6,83 +6,189 @@ namespace ClosedXML.Excel { - public class XLRow: IXLRow + internal class XLRow: XLRangeBase, IXLRow { public XLRow(Int32 row, XLRowParameters xlRowParameters) { - Internals = new XLRangeInternals(new XLAddress(row, 1), new XLAddress(row, XLWorksheet.MaxNumberOfColumns), xlRowParameters.Worksheet); - RowNumber = row; - ColumnNumber = 1; - ColumnLetter = "A"; - this.style = new XLStyle(this, xlRowParameters.DefaultStyle); - this.Height = XLWorkbook.DefaultRowHeight; + SetRowNumber(row); + Worksheet = xlRowParameters.Worksheet; + + this.IsReference = xlRowParameters.IsReference; + if (IsReference) + { + Worksheet.RangeShiftedRows += new RangeShiftedRowsDelegate(Worksheet_RangeShiftedRows); + } + else + { + this.style = new XLStyle(this, xlRowParameters.DefaultStyle); + this.height = xlRowParameters.Worksheet.DefaultRowHeight; + } } - public Double Height { get; set; } - public Int32 RowNumber { get; private set; } - public Int32 ColumnNumber { get; private set; } - public String ColumnLetter { get; private set; } + void Worksheet_RangeShiftedRows(XLRange range, int rowsShifted) + { + if (range.FirstAddressInSheet.RowNumber <= this.RowNumber()) + SetRowNumber(this.RowNumber() + rowsShifted); + } + + void RowsCollection_RowShifted(int startingRow, int rowsShifted) + { + if (startingRow <= this.RowNumber()) + SetRowNumber(this.RowNumber() + rowsShifted); + } + + private void SetRowNumber(Int32 row) + { + FirstAddressInSheet = new XLAddress(row, 1); + LastAddressInSheet = new XLAddress(row, XLWorksheet.MaxNumberOfColumns); + } + + + public Boolean IsReference { get; private set; } + + #region IXLRow Members + + private Double height; + public Double Height + { + get + { + if (IsReference) + { + return Worksheet.Internals.RowsCollection[this.RowNumber()].Height; + } + else + { + return height; + } + } + set + { + if (IsReference) + { + Worksheet.Internals.RowsCollection[this.RowNumber()].Height = value; + } + else + { + height = value; + } + } + } + public void Delete() { - this.Row(RowNumber).Delete(XLShiftDeletedCells.ShiftCellsUp); + var rowNumber = this.RowNumber(); + this.AsRange().Delete(XLShiftDeletedCells.ShiftCellsUp); + Worksheet.Internals.RowsCollection.Remove(rowNumber); } - - #region IXLRange Members + public Int32 RowNumber() + { + return this.FirstAddressInSheet.RowNumber; + } - public IXLRangeInternals Internals { get; private set; } + public void InsertRowsBelow(Int32 numberOfRows) + { + var rowNum = this.RowNumber(); + this.Worksheet.Internals.RowsCollection.ShiftRowsDown(rowNum + 1, numberOfRows); + XLRange range = (XLRange)this.Worksheet.Row(rowNum).AsRange(); + range.InsertRowsBelow(numberOfRows, true); + } + + public void InsertRowsAbove(Int32 numberOfRows) + { + var rowNum = this.RowNumber(); + this.Worksheet.Internals.RowsCollection.ShiftRowsDown(rowNum, numberOfRows); + // We can't use this.AsRange() because we've shifted the rows + // and we want to use the old rowNum. + XLRange range = (XLRange)this.Worksheet.Row(rowNum).AsRange(); + range.InsertRowsAbove(numberOfRows, true); + } + + public void Clear() + { + var range = this.AsRange(); + range.Clear(); + this.Style = Worksheet.Style; + } #endregion + #region IXLStylized Members private IXLStyle style; - public IXLStyle Style + public override IXLStyle Style { get { - return style; + if (IsReference) + return Worksheet.Internals.RowsCollection[this.RowNumber()].Style; + else + return style; } set { - style = new XLStyle(this, value); + if (IsReference) + { + Worksheet.Internals.RowsCollection[this.RowNumber()].Style = value; + } + else + { + style = new XLStyle(this, value); + + var row = this.RowNumber(); + foreach (var c in Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.RowNumber == row)) + { + c.Style = value; + } + + var maxColumn = 0; + if (Worksheet.Internals.ColumnsCollection.Count > 0) + maxColumn = Worksheet.Internals.ColumnsCollection.Keys.Max(); + + + for (var co = 1; co <= maxColumn; co++) + { + Worksheet.Cell(row, co).Style = value; + } + } } } - public IEnumerable Styles + public override IEnumerable Styles { get { UpdatingStyle = true; - yield return style; - foreach (var c in Internals.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.Row == Internals.FirstCellAddress.Row)) + + yield return Style; + + var row = this.RowNumber(); + + foreach (var c in Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.RowNumber == row)) { yield return c.Style; } + + var maxColumn = 0; + if (Worksheet.Internals.ColumnsCollection.Count > 0) + maxColumn = Worksheet.Internals.ColumnsCollection.Keys.Max(); + + for (var co = 1; co <= maxColumn; co++) + { + yield return Worksheet.Cell(row, co).Style; + } + UpdatingStyle = false; } } - public Boolean UpdatingStyle { get; set; } + public override Boolean UpdatingStyle { get; set; } - #endregion - - #region IXLRange Members - - public IXLRange Row(int row) + public override IXLRange AsRange() { - return this; - } - - public IXLRange Column(int column) - { - var address = new XLAddress(1, column); - return this.Range(address, address); - } - - public IXLRange Column(string column) - { - return Column(Int32.Parse(column)); + return Range(1, 1, 1, XLWorksheet.MaxNumberOfColumns); } #endregion diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRowCollection.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRowCollection.cs new file mode 100644 index 0000000..3db4abb --- /dev/null +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRowCollection.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace ClosedXML.Excel +{ + //internal delegate void RowDeletingDelegate(Int32 deletedRow, Boolean beingShifted); + //internal delegate void RowShiftedDelegate(Int32 startingRow, Int32 rowsShifted); + internal class XLRowsCollection: IDictionary + { + //public event RowDeletingDelegate RowDeleting; + //public event RowShiftedDelegate RowShifted; + + //private Boolean beingShifted = false; + public void ShiftRowsDown(Int32 startingRow, Int32 rowsToShift) + { + //beingShifted = true; + foreach (var ro in dictionary.Keys.Where(k => k >= startingRow).OrderByDescending(k => k)) + { + var rowToMove = dictionary[ro]; + var newRow = ro + rowsToShift; + if (newRow <= XLWorksheet.MaxNumberOfRows) + { + var xlRowParameters = new XLRowParameters(rowToMove.Worksheet, rowToMove.Style, false); + dictionary.Add(newRow, new XLRow(newRow, xlRowParameters)); + } + dictionary.Remove(ro); + } + + //if (RowShifted != null) + // RowShifted(startingRow, rowsToShift); + + //beingShifted = false; + } + + private Dictionary dictionary = new Dictionary(); + + public void Add(int key, XLRow value) + { + dictionary.Add(key, value); + } + + public bool ContainsKey(int key) + { + return dictionary.ContainsKey(key); + } + + public ICollection Keys + { + get { return dictionary.Keys; } + } + + public bool Remove(int key) + { + //if (RowDeleting != null) + // RowDeleting(key, beingShifted); + + return dictionary.Remove(key); + } + + public bool TryGetValue(int key, out XLRow value) + { + return dictionary.TryGetValue(key, out value); + } + + public ICollection Values + { + get { return dictionary.Values; } + } + + public XLRow this[int key] + { + get + { + return dictionary[key]; + } + set + { + dictionary[key] = value; + } + } + + public void Add(KeyValuePair item) + { + dictionary.Add(item.Key, item.Value); + } + + public void Clear() + { + //if (RowDeleting != null) + // dictionary.ForEach(r => RowDeleting(r.Key, beingShifted)); + + dictionary.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return dictionary.Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { return dictionary.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove(KeyValuePair item) + { + //if (RowDeleting != null) + // RowDeleting(item.Key, beingShifted); + + return dictionary.Remove(item.Key); + } + + public IEnumerator> GetEnumerator() + { + return dictionary.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return dictionary.GetEnumerator(); + } + } +} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRowParameters.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRowParameters.cs index 787ffb6..dd5da99 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRowParameters.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRowParameters.cs @@ -6,14 +6,16 @@ namespace ClosedXML.Excel { - public class XLRowParameters + internal class XLRowParameters { - public XLRowParameters(IXLWorksheet worksheet, IXLStyle defaultStyle) + public XLRowParameters(XLWorksheet worksheet, IXLStyle defaultStyle, Boolean isReference = true) { Worksheet = worksheet; DefaultStyle = defaultStyle; + IsReference = isReference; } public IXLStyle DefaultStyle { get; set; } - public IXLWorksheet Worksheet { get; private set; } + public XLWorksheet Worksheet { get; private set; } + public Boolean IsReference { get; private set; } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRows.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRows.cs index e2481e8..8c7e61d 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRows.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Rows/XLRows.cs @@ -5,17 +5,22 @@ namespace ClosedXML.Excel { - public class XLRows: IXLRows + internal class XLRows: IXLRows { - public XLRows() + private Boolean entireWorksheet; + private XLWorksheet worksheet; + public XLRows(XLWorksheet worksheet, Boolean entireWorksheet = false) { - Style = XLWorkbook.DefaultStyle; + this.worksheet = worksheet; + this.entireWorksheet = entireWorksheet; + Style = worksheet.Style; } - List rows = new List(); + List rows = new List(); + public IEnumerator GetEnumerator() { - return rows.GetEnumerator(); + return rows.ToList().GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() @@ -36,6 +41,31 @@ { style = new XLStyle(this, value); + if (entireWorksheet) + { + worksheet.Style = value; + } + else + { + var maxColumn = 0; + if (worksheet.Internals.ColumnsCollection.Count > 0) + maxColumn = worksheet.Internals.ColumnsCollection.Keys.Max(); + + foreach (var row in rows) + { + row.Style = value; + foreach (var c in row.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.RowNumber == row.FirstAddressInSheet.RowNumber)) + { + c.Style = value; + } + + for (var co = 1; co <= maxColumn; co++) + { + worksheet.Cell(row.RowNumber(), co).Style = value; + } + } + } + } } @@ -45,12 +75,28 @@ { UpdatingStyle = true; yield return style; - foreach (var col in rows) + if (entireWorksheet) { - yield return col.Style; - foreach (var c in col.Internals.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.Row == col.Internals.FirstCellAddress.Row)) + yield return worksheet.Style; + } + else + { + var maxColumn = 0; + if (worksheet.Internals.ColumnsCollection.Count > 0) + maxColumn = worksheet.Internals.ColumnsCollection.Keys.Max(); + + foreach (var row in rows) { - yield return c.Style; + yield return row.Style; + foreach (var c in row.Worksheet.Internals.CellsCollection.Values.Where(c => c.Address.RowNumber == row.FirstAddressInSheet.RowNumber)) + { + yield return c.Style; + } + + for (var co = 1; co <= maxColumn; co++) + { + yield return worksheet.Cell(row.RowNumber(), co).Style; + } } } UpdatingStyle = false; @@ -66,16 +112,28 @@ set { rows.ForEach(c => c.Height = value); + if (entireWorksheet) + { + worksheet.DefaultRowHeight = value; + worksheet.Internals.RowsCollection.ForEach(r => r.Value.Height = value); + } } } public void Delete() { - rows.ForEach(c => c.Delete(XLShiftDeletedCells.ShiftCellsUp)); + if (entireWorksheet) + { + worksheet.Internals.ColumnsCollection.Clear(); + worksheet.Internals.CellsCollection.Clear(); + } + else + { + rows.ForEach(r => r.Delete()); + } } - - public void Add(IXLRow row) + public void Add(XLRow row) { rows.Add(row); } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/IXLStyle.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/IXLStyle.cs index f00271c..525157d 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/IXLStyle.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/IXLStyle.cs @@ -12,6 +12,6 @@ IXLFill Fill { get; set; } IXLFont Font { get; set; } IXLNumberFormat NumberFormat { get; set; } - + IXLNumberFormat DateFormat { get; } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLAlignment.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLAlignment.cs index d02b690..d5a3e45 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLAlignment.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLAlignment.cs @@ -5,7 +5,7 @@ namespace ClosedXML.Excel { - public class XLAlignment: IXLAlignment + internal class XLAlignment : IXLAlignment { IXLStylized container; public XLAlignment(IXLStylized container, IXLAlignment d = null) diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLBorder.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLBorder.cs index ce58280..af96d16 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLBorder.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLBorder.cs @@ -5,7 +5,7 @@ using System.Drawing; namespace ClosedXML.Excel { - public class XLBorder: IXLBorder + internal class XLBorder : IXLBorder { IXLStylized container; public XLBorder(IXLStylized container, IXLBorder defaultBorder = null) diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFill.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFill.cs index 95df52b..a889d1f 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFill.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFill.cs @@ -6,7 +6,7 @@ namespace ClosedXML.Excel { - public class XLFill: IXLFill + internal class XLFill : IXLFill { #region Properties diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFont.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFont.cs index 96c90d7..a152589 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFont.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLFont.cs @@ -6,7 +6,7 @@ namespace ClosedXML.Excel { - public class XLFont: IXLFont + internal class XLFont : IXLFont { IXLStylized container; public XLFont() @@ -233,5 +233,6 @@ } #endregion + } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLNumberFormat.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLNumberFormat.cs index 711f0f5..883bda2 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLNumberFormat.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLNumberFormat.cs @@ -5,7 +5,7 @@ namespace ClosedXML.Excel { - public class XLNumberFormat: IXLNumberFormat + internal class XLNumberFormat : IXLNumberFormat { #region Properties @@ -56,10 +56,8 @@ this.container = container; if (defaultNumberFormat != null) { - if (defaultNumberFormat.NumberFormatId >= 0) - numberFormatId = defaultNumberFormat.NumberFormatId; - else - format = defaultNumberFormat.Format; + numberFormatId = defaultNumberFormat.NumberFormatId; + format = defaultNumberFormat.Format; } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLStyle.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLStyle.cs index 59564d7..aabe7e0 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLStyle.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/Style/XLStyle.cs @@ -5,7 +5,7 @@ namespace ClosedXML.Excel { - public class XLStyle: IXLStyle + internal class XLStyle : IXLStyle { public XLStyle(IXLStylized container, IXLStyle initialStyle = null) { @@ -25,6 +25,8 @@ Fill = new XLFill(container); NumberFormat = new XLNumberFormat(container); } + + DateFormat = NumberFormat; } public IXLFont Font { get; set; } @@ -35,7 +37,21 @@ public IXLFill Fill { get; set; } - public IXLNumberFormat NumberFormat { get; set; } + private IXLNumberFormat numberFormat; + public IXLNumberFormat NumberFormat + { + get + { + return numberFormat; + } + set + { + numberFormat = value; + DateFormat = numberFormat; + } + } + + public IXLNumberFormat DateFormat { get; private set; } public override string ToString() { @@ -46,5 +62,6 @@ + " NumberFormat: " + NumberFormat.ToString() + " Alignment: " + Alignment.ToString(); } + } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs index 5f25012..37ff377 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLAddress.cs @@ -6,30 +6,30 @@ namespace ClosedXML.Excel { - public struct XLAddress: IXLAddress + internal struct XLAddress: IXLAddress { #region Constructors /// /// Initializes a new struct using R1C1 notation. /// - /// The row number of the cell address. - /// The column number of the cell address. - public XLAddress(Int32 row, Int32 column) + /// The row number of the cell address. + /// The column number of the cell address. + public XLAddress(Int32 rowNumber, Int32 columnNumber) { - this.row = row; - this.column = column; - this.columnLetter = GetColumnLetterFromNumber(column); + this.rowNumber = rowNumber; + this.columnNumber = columnNumber; + this.columnLetter = GetColumnLetterFromNumber(columnNumber); } /// /// Initializes a new struct using a mixed notation. /// - /// The row number of the cell address. + /// The row number of the cell address. /// The column letter of the cell address. - public XLAddress(Int32 row, String columnLetter) + public XLAddress(Int32 rowNumber, String columnLetter) { - this.row = row; - this.column = GetColumnNumberFromLetter(columnLetter); + this.rowNumber = rowNumber; + this.columnNumber = GetColumnNumberFromLetter(columnLetter); this.columnLetter = columnLetter; } @@ -42,8 +42,8 @@ { Match m = Regex.Match(cellAddressString, @"^([a-zA-Z]+)(\d+)$"); columnLetter = m.Groups[1].Value; - this.row = Int32.Parse(m.Groups[2].Value); - this.column = GetColumnNumberFromLetter(columnLetter); + this.rowNumber = Int32.Parse(m.Groups[2].Value); + this.columnNumber = GetColumnNumberFromLetter(columnLetter); } #endregion @@ -53,31 +53,31 @@ /// /// Gets the column number of a given column letter. /// - /// The column letter to translate into a column number. - public static Int32 GetColumnNumberFromLetter(String column) + /// The column letter to translate into a column number. + public static Int32 GetColumnNumberFromLetter(String columnLetter) { Int32 iTest; - if (Int32.TryParse(column, out iTest)) return iTest; + if (Int32.TryParse(columnLetter, out iTest)) return iTest; - column = column.ToUpper(); + columnLetter = columnLetter.ToUpper(); - if (column.Length == 1) + if (columnLetter.Length == 1) { - return Convert.ToByte(Convert.ToChar(column)) - 64; + return Convert.ToByte(Convert.ToChar(columnLetter)) - 64; } - else if (column.Length == 2) + else if (columnLetter.Length == 2) { return - ((Convert.ToByte(column[0]) - 64) * 26) + - (Convert.ToByte(column[1]) - 64); + ((Convert.ToByte(columnLetter[0]) - 64) * 26) + + (Convert.ToByte(columnLetter[1]) - 64); } - else if (column.Length == 3) + else if (columnLetter.Length == 3) { return - ((Convert.ToByte(column[0]) - 64) * 26 * 26) + - ((Convert.ToByte(column[1]) - 64) * 26) + - (Convert.ToByte(column[2]) - 64); + ((Convert.ToByte(columnLetter[0]) - 64) * 26 * 26) + + ((Convert.ToByte(columnLetter[1]) - 64) * 26) + + (Convert.ToByte(columnLetter[2]) - 64); } else { @@ -88,8 +88,8 @@ /// /// Gets the column letter of a given column number. /// - /// The column number to translate into a column letter. - public static String GetColumnLetterFromNumber(Int32 column) + /// The column number to translate into a column letter. + public static String GetColumnLetterFromNumber(Int32 columnNumber) { String s = String.Empty; for ( @@ -97,7 +97,7 @@ Math.Log( Convert.ToDouble( 25 * ( - Convert.ToDouble(column) + Convert.ToDouble(columnNumber) + 1 ) ) @@ -108,9 +108,9 @@ ) { Int32 x = Convert.ToInt32(Math.Pow(26, i + 1) - 1) / 25 - 1; - if (column > x) + if (columnNumber > x) { - s += (Char)(((column - x - 1) / Convert.ToInt32(Math.Pow(26, i))) % 26 + 65); + s += (Char)(((columnNumber - x - 1) / Convert.ToInt32(Math.Pow(26, i))) % 26 + 65); } } return s; @@ -120,24 +120,24 @@ #region Properties - private Int32 row; + private Int32 rowNumber; /// /// Gets the row number of this address. /// - public Int32 Row + public Int32 RowNumber { - get { return row; } - private set { row = value; } + get { return rowNumber; } + private set { rowNumber = value; } } - private Int32 column; + private Int32 columnNumber; /// /// Gets the column number of this address. /// - public Int32 Column + public Int32 ColumnNumber { - get { return column; } - private set { column = value; } + get { return columnNumber; } + private set { columnNumber = value; } } private String columnLetter; @@ -155,7 +155,7 @@ #region Overrides public override string ToString() { - return this.columnLetter + this.row.ToString(); + return this.columnLetter + this.rowNumber.ToString(); } #endregion @@ -163,29 +163,29 @@ public static XLAddress operator +(XLAddress xlCellAddressLeft, XLAddress xlCellAddressRight) { - return new XLAddress(xlCellAddressLeft.Row + xlCellAddressRight.Row, xlCellAddressLeft.Column + xlCellAddressRight.Column); + return new XLAddress(xlCellAddressLeft.RowNumber + xlCellAddressRight.RowNumber, xlCellAddressLeft.ColumnNumber + xlCellAddressRight.ColumnNumber); } public static XLAddress operator -(XLAddress xlCellAddressLeft, XLAddress xlCellAddressRight) { - return new XLAddress(xlCellAddressLeft.Row - xlCellAddressRight.Row, xlCellAddressLeft.Column - xlCellAddressRight.Column); + return new XLAddress(xlCellAddressLeft.RowNumber - xlCellAddressRight.RowNumber, xlCellAddressLeft.ColumnNumber - xlCellAddressRight.ColumnNumber); } public static XLAddress operator +(XLAddress xlCellAddressLeft, Int32 right) { - return new XLAddress(xlCellAddressLeft.Row + right, xlCellAddressLeft.Column + right); + return new XLAddress(xlCellAddressLeft.RowNumber + right, xlCellAddressLeft.ColumnNumber + right); } public static XLAddress operator -(XLAddress xlCellAddressLeft, Int32 right) { - return new XLAddress(xlCellAddressLeft.Row - right, xlCellAddressLeft.Column - right); + return new XLAddress(xlCellAddressLeft.RowNumber - right, xlCellAddressLeft.ColumnNumber - right); } public static Boolean operator ==(XLAddress xlCellAddressLeft, XLAddress xlCellAddressRight) { return - xlCellAddressLeft.Row == xlCellAddressRight.Row - && xlCellAddressLeft.Column == xlCellAddressRight.Column; + xlCellAddressLeft.RowNumber == xlCellAddressRight.RowNumber + && xlCellAddressLeft.ColumnNumber == xlCellAddressRight.ColumnNumber; } public static Boolean operator !=(XLAddress xlCellAddressLeft, XLAddress xlCellAddressRight) @@ -196,13 +196,13 @@ public static Boolean operator >(XLAddress xlCellAddressLeft, XLAddress xlCellAddressRight) { return !(xlCellAddressLeft == xlCellAddressRight) - && (xlCellAddressLeft.Row > xlCellAddressRight.Row || xlCellAddressLeft.Column > xlCellAddressRight.Column); + && (xlCellAddressLeft.RowNumber > xlCellAddressRight.RowNumber || xlCellAddressLeft.ColumnNumber > xlCellAddressRight.ColumnNumber); } public static Boolean operator <(XLAddress xlCellAddressLeft, XLAddress xlCellAddressRight) { return !(xlCellAddressLeft == xlCellAddressRight) - && (xlCellAddressLeft.Row < xlCellAddressRight.Row || xlCellAddressLeft.Column < xlCellAddressRight.Column); + && (xlCellAddressLeft.RowNumber < xlCellAddressRight.RowNumber || xlCellAddressLeft.ColumnNumber < xlCellAddressRight.ColumnNumber); } public static Boolean operator >=(XLAddress xlCellAddressLeft, XLAddress xlCellAddressRight) @@ -221,12 +221,12 @@ #region IEqualityComparer Members - public Boolean Equals(XLAddress x, XLAddress y) + public Boolean Equals(IXLAddress x, IXLAddress y) { return x == y; } - public Int32 GetHashCode(XLAddress obj) + public Int32 GetHashCode(IXLAddress obj) { return obj.GetHashCode(); } @@ -250,9 +250,9 @@ #region IEquatable Members - public Boolean Equals(XLAddress other) + public Boolean Equals(IXLAddress other) { - return this == other; + return this == (XLAddress)other; } public override Boolean Equals(Object other) @@ -279,9 +279,9 @@ #region IComparable Members - public int CompareTo(XLAddress other) + public Int32 CompareTo(IXLAddress other) { - throw new NotImplementedException(); + return CompareTo((Object)other); } #endregion diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLCell.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLCell.cs deleted file mode 100644 index 0157c49..0000000 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLCell.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - - -namespace ClosedXML.Excel -{ - public class XLCell : IXLCell - { - public XLCell(IXLAddress address, IXLStyle defaultStyle) - { - this.Address = address; - Style = defaultStyle; - if (Style == null) Style = XLWorkbook.DefaultStyle; - } - - public IXLAddress Address { get; private set; } - - private Boolean initialized = false; - private String cellValue = String.Empty; - public String Value - { - get - { - return cellValue; - } - set - { - String val = value; - Double dTest; - DateTime dtTest; - Boolean bTest; - if (initialized) - { - if (dataType == XLCellValues.Boolean) - { - if (Boolean.TryParse(val, out bTest)) - val = bTest ? "1" : "0"; - else if (!(val == "1" || val == "0")) - throw new ArgumentException("'" + val + "' is not a Boolean type."); - } - else if (dataType == XLCellValues.DateTime) - { - if (DateTime.TryParse(val, out dtTest)) - { - - val = dtTest.ToOADate().ToString(); - } - else if (!Double.TryParse(val, out dTest)) - { - throw new ArgumentException("'" + val + "' is not a DateTime type."); - } - - if (Style.NumberFormat.Format == String.Empty) - Style.NumberFormat.NumberFormatId = 14; - } - else if (dataType == XLCellValues.Number) - { - if (!Double.TryParse(val, out dTest)) - throw new ArgumentException("'" + val + "' is not a Numeric type."); - - } - } - else - { - if (val.Length > 0 && val.Substring(0, 1) == "'") - { - val = val.Substring(1, val.Length - 1); - dataType = XLCellValues.Text; - } - else if (Double.TryParse(val, out dTest)) - { - dataType = XLCellValues.Number; - } - else if (DateTime.TryParse(val, out dtTest)) - { - dataType = XLCellValues.DateTime; - Style.NumberFormat.NumberFormatId = 14; - val = dtTest.ToOADate().ToString(); - } - else if (Boolean.TryParse(val, out bTest)) - { - dataType = XLCellValues.Boolean; - val = bTest ? "1" : "0"; - } - else - { - dataType = XLCellValues.Text; - } - } - cellValue = val; - } - } - - #region IXLStylized Members - - private IXLStyle style; - public IXLStyle Style - { - get - { - return style; - } - set - { - style = new XLStyle(null, value); - } - } - - public IEnumerable Styles - { - get - { - UpdatingStyle = true; - yield return style; - UpdatingStyle = false; - } - } - - public Boolean UpdatingStyle { get; set; } - - #endregion - - private XLCellValues dataType; - public XLCellValues DataType - { - get - { - return dataType; - } - set - { - initialized = true; - if (cellValue.Length > 0) - { - if (value == XLCellValues.Boolean) - { - cellValue = Boolean.Parse(cellValue) ? "1" : "0"; - } - else if (value == XLCellValues.DateTime) - { - DateTime dtTest; - Double dblTest; - if (DateTime.TryParse(cellValue, out dtTest)) - { - cellValue = dtTest.ToOADate().ToString(); - } - else if (Double.TryParse(cellValue, out dblTest)) - { - cellValue = dblTest.ToString(); - } - else - { - throw new ArgumentException("Cannot set data type to DateTime because '" + cellValue + "' is not recognized as a date."); - } - - if (Style.NumberFormat.Format == String.Empty) - Style.NumberFormat.NumberFormatId = 14; - } - else if (value == XLCellValues.Number) - { - cellValue = Double.Parse(cellValue).ToString(); - if (Style.NumberFormat.Format == String.Empty) - Style.NumberFormat.NumberFormatId = 0; - } - else - { - if (dataType == XLCellValues.Boolean) - { - cellValue = (cellValue == "0" ? false : true).ToString(); - } - else if (dataType == XLCellValues.Number) - { - cellValue = Double.Parse(cellValue).ToString(Style.NumberFormat.Format); - } - else if (dataType == XLCellValues.DateTime) - { - cellValue = DateTime.FromOADate(Double.Parse(cellValue)).ToString(Style.NumberFormat.Format); - } - } - } - dataType = value; - } - } - } -} diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs index f15bd13..4cfa971 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook.cs @@ -8,7 +8,7 @@ namespace ClosedXML.Excel { - public partial class XLWorkbook: IXLWorkbook + public partial class XLWorkbook { public XLWorkbook() { @@ -120,8 +120,8 @@ public static Double DefaultRowHeight { get; set; } public static Double DefaultColumnWidth { get; set; } - public static XLPageOptions defaultPageOptions; - public static XLPageOptions DefaultPageOptions + public static IXLPageOptions defaultPageOptions; + public static IXLPageOptions DefaultPageOptions { get { @@ -151,6 +151,11 @@ } } + public static IXLFont GetXLFont() + { + return new XLFont(); + } + #endregion } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs index 86925d2..7aa27fc 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Load.cs @@ -57,8 +57,11 @@ var sheetName = dSheet.Name; + var ws = (XLWorksheet)Worksheets.Add(sheetName); - var ws = Worksheets.Add(sheetName); + var sheetFormatProperties = (SheetFormatProperties)worksheetPart.Worksheet.Descendants().First(); + ws.DefaultRowHeight = sheetFormatProperties.DefaultRowHeight; + ws.DefaultColumnWidth = sheetFormatProperties.DefaultColumnWidth; foreach (var mCell in worksheetPart.Worksheet.Descendants()) { @@ -66,45 +69,79 @@ ws.Range(mergeCell.Reference).Merge(); } + + var wsDefaultColumn = worksheetPart.Worksheet.Descendants().Where( + c => c.Max == XLWorksheet.MaxNumberOfColumns).Single(); + + if (wsDefaultColumn.Width != null) ws.DefaultColumnWidth = wsDefaultColumn.Width; + + Int32 styleIndexDefault = wsDefaultColumn.Style != null ? Int32.Parse(wsDefaultColumn.Style.InnerText) : -1; + if (styleIndexDefault >= 0) + { + ApplyStyle(ws, styleIndexDefault, s, fills, borders, fonts, numberingFormats); + } + foreach (var col in worksheetPart.Worksheet.Descendants()) { - //var column = (Column)col; - var xlColumns = ws.Columns(col.Min, col.Max); - if (col.Width != null) xlColumns.Width = col.Width; - Int32 styleIndex = col.Style != null ? Int32.Parse(col.Style.InnerText) : -1; - if (styleIndex >= 0) + IXLStylized toApply; + if (col.Max != XLWorksheet.MaxNumberOfColumns) { - ApplyStyle(xlColumns, styleIndex, s, fills, borders, fonts, numberingFormats); + toApply = ws.Columns(col.Min, col.Max); + if (col.Width != null) + ((XLColumns)toApply).Width = col.Width; + else + ((XLColumns)toApply).Width = ws.DefaultColumnWidth; + + Int32 styleIndex = col.Style != null ? Int32.Parse(col.Style.InnerText) : -1; + if (styleIndex > 0) + { + ApplyStyle(toApply, styleIndex, s, fills, borders, fonts, numberingFormats); + } + else + { + toApply.Style = DefaultStyle; + } } } - foreach (var row in worksheetPart.Worksheet.Descendants()) + foreach (var row in worksheetPart.Worksheet.Descendants().Where(r=>r.CustomFormat != null && r.CustomFormat).Select(r=>r)) { //var dRow = (Column)col; var xlRow = ws.Row(Int32.Parse(row.RowIndex.ToString())); - if (row.Height != null) xlRow.Height = row.Height; + if (row.Height != null) + xlRow.Height = row.Height; + else + xlRow.Height = ws.DefaultRowHeight; + Int32 styleIndex = row.StyleIndex != null ? Int32.Parse(row.StyleIndex.InnerText) : -1; - if (styleIndex >= 0) + if (styleIndex > 0) { ApplyStyle(xlRow, styleIndex, s, fills, borders, fonts, numberingFormats); } + else + { + xlRow.Style = DefaultStyle; + } } + foreach (var cell in worksheetPart.Worksheet.Descendants()) { var dCell = (Cell)cell; Int32 styleIndex = dCell.StyleIndex != null ? Int32.Parse(dCell.StyleIndex.InnerText) : -1; var xlCell = ws.Cell(dCell.CellReference); - if (styleIndex >= 0) + if (styleIndex > 0) { styleIndex = Int32.Parse(dCell.StyleIndex.InnerText); ApplyStyle(xlCell, styleIndex, s, fills, borders, fonts, numberingFormats); } + else + { + xlCell.Style = DefaultStyle; + } if (dCell.DataType != null) { - - if (dCell.DataType == CellValues.SharedString) { xlCell.DataType = XLCellValues.Text; diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs index 62cc397..6eb253f 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorkbook_Save.cs @@ -230,7 +230,7 @@ { sheetId++; WorksheetPart worksheetPart = workbookPart.AddNewPart("rId" + sheetId.ToString()); - GenerateWorksheetPartContent(worksheetPart, worksheet); + GenerateWorksheetPartContent(worksheetPart, (XLWorksheet)worksheet); } ThemePart themePart1 = workbookPart.AddNewPart("rId" + (startId + 1)); @@ -345,7 +345,7 @@ UInt32 sheetId = 0; Sheets sheets = new Sheets(); DefinedNames definedNames = new DefinedNames(); - foreach (var worksheet in Worksheets) + foreach (var worksheet in Worksheets.Cast()) { sheetId++; Sheet sheet = new Sheet() { Name = worksheet.Name, SheetId = (UInt32Value)sheetId, Id = "rId" + sheetId.ToString() }; @@ -365,8 +365,8 @@ foreach (var printArea in worksheet.PageSetup.PrintAreas) { definedNameText += "'" + worksheet.Name + "'!" - + printArea.Internals.FirstCellAddress.ToString() - + ":" + printArea.Internals.LastCellAddress.ToString() + ","; + + printArea.FirstAddressInSheet.ToString() + + ":" + printArea.LastAddressInSheet.ToString() + ","; } definedName.Text = definedNameText.Substring(0, definedNameText.Length - 1); @@ -424,7 +424,7 @@ private void GenerateSharedStringTablePartContent(SharedStringTablePart sharedStringTablePart) { List combined = new List(); - Worksheets.ForEach(w => combined.AddRange(w.Internals.CellsCollection.Values.Where(c => c.DataType == XLCellValues.Text && c.Value != null).Select(c => c.Value).Distinct())); + Worksheets.Cast().ForEach(w => combined.AddRange(w.Internals.CellsCollection.Values.Where(c => c.DataType == XLCellValues.Text && c.Value != null).Select(c => c.Value).Distinct())); var distinctStrings = combined.Distinct(); UInt32 stringCount = (UInt32)distinctStrings.Count(); SharedStringTable sharedStringTable = new SharedStringTable() { Count = (UInt32Value)stringCount, UniqueCount = (UInt32Value)stringCount }; @@ -482,7 +482,7 @@ var xlStyles = new List(); - foreach (var worksheet in Worksheets) + foreach (var worksheet in Worksheets.Cast()) { xlStyles.AddRange(worksheet.Styles); worksheet.Internals.ColumnsCollection.Values.ForEach(c => xlStyles.Add(c.Style)); @@ -706,7 +706,7 @@ - private void GenerateWorksheetPartContent(WorksheetPart worksheetPart, IXLWorksheet xlWorksheet) + private void GenerateWorksheetPartContent(WorksheetPart worksheetPart, XLWorksheet xlWorksheet) { Worksheet worksheet = new Worksheet(); worksheet.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"); @@ -723,8 +723,8 @@ String sheetDimensionReference = "A1"; if (xlWorksheet.Internals.CellsCollection.Count > 0) { - maxColumn = (UInt32)xlWorksheet.Internals.CellsCollection.Select(c => c.Key.Column).Max(); - maxRow = (UInt32)xlWorksheet.Internals.CellsCollection.Select(c => c.Key.Row).Max(); + maxColumn = (UInt32)xlWorksheet.Internals.CellsCollection.Select(c => c.Key.ColumnNumber).Max(); + maxRow = (UInt32)xlWorksheet.Internals.CellsCollection.Select(c => c.Key.RowNumber).Max(); sheetDimensionReference = "A1:" + new XLAddress((Int32)maxRow, (Int32)maxColumn).ToString(); } @@ -748,47 +748,106 @@ SheetView sheetView = new SheetView() { TabSelected = tabSelected, WorkbookViewId = (UInt32Value)0U }; sheetViews.Append(sheetView); - SheetFormatProperties sheetFormatProperties3 = new SheetFormatProperties() { DefaultRowHeight = 15D }; + SheetFormatProperties sheetFormatProperties3 = new SheetFormatProperties() { DefaultRowHeight = xlWorksheet.DefaultRowHeight, DefaultColumnWidth = xlWorksheet.DefaultColumnWidth , CustomHeight = true }; - Columns columns = null; + Columns columns = new Columns(); + + + Int32 minInColumnsCollection; + Int32 maxInColumnsCollection; if (xlWorksheet.Internals.ColumnsCollection.Count > 0) { - columns = new Columns(); - foreach (var xlColumn in xlWorksheet.Internals.ColumnsCollection.Values) + minInColumnsCollection = xlWorksheet.Internals.ColumnsCollection.Keys.Min(); + maxInColumnsCollection = xlWorksheet.Internals.ColumnsCollection.Keys.Max(); + } + else + { + minInColumnsCollection = 1; + maxInColumnsCollection = 0; + } + + if (minInColumnsCollection > 1) + { + Column column = new Column() { - Column column = new Column() - { - Min = (UInt32Value)(UInt32)xlColumn.Internals.FirstCellAddress.Column, - Max = (UInt32Value)(UInt32)xlColumn.Internals.FirstCellAddress.Column, - Style = sharedStyles[xlColumn.Style.ToString()].StyleId, - Width = xlColumn.Width, - CustomWidth = true - }; + Min = 1, + Max = (UInt32Value)(UInt32)(minInColumnsCollection - 1), + Style = sharedStyles[xlWorksheet.Style.ToString()].StyleId, + Width = xlWorksheet.DefaultColumnWidth, + CustomWidth = true + }; + columns.Append(column); + } - columns.Append(column); + for(var co = minInColumnsCollection; co <= maxInColumnsCollection; co++) + { + UInt32 styleId; + Double columnWidth; + if (xlWorksheet.Internals.ColumnsCollection.ContainsKey(co)) + { + styleId = sharedStyles[xlWorksheet.Internals.ColumnsCollection[co].Style.ToString()].StyleId; + columnWidth = xlWorksheet.Internals.ColumnsCollection[co].Width; } + else + { + styleId = sharedStyles[xlWorksheet.Style.ToString()].StyleId; + columnWidth = xlWorksheet.DefaultColumnWidth; + } + + Column column = new Column() + { + Min = (UInt32Value)(UInt32)co, + Max = (UInt32Value)(UInt32)co, + Style = styleId, + Width = columnWidth, + CustomWidth = true + }; + columns.Append(column); + } + + if (maxInColumnsCollection < XLWorksheet.MaxNumberOfColumns) + { + Column column = new Column() + { + Min = (UInt32Value)(UInt32)(maxInColumnsCollection + 1), + Max = (UInt32Value)(UInt32)(XLWorksheet.MaxNumberOfColumns), + Style = sharedStyles[xlWorksheet.Style.ToString()].StyleId, + Width = xlWorksheet.DefaultColumnWidth, + CustomWidth = true + }; + columns.Append(column); } SheetData sheetData = new SheetData(); - var rowsFromCells = xlWorksheet.Internals.CellsCollection.Where(c => c.Key.Column > 0 && c.Key.Row > 0).Select(c => c.Key.Row).Distinct(); + var rowsFromCells = xlWorksheet.Internals.CellsCollection.Where(c => c.Key.ColumnNumber > 0 && c.Key.RowNumber > 0).Select(c => c.Key.RowNumber).Distinct(); var rowsFromCollection = xlWorksheet.Internals.RowsCollection.Keys; var allRows = rowsFromCells.ToList(); allRows.AddRange(rowsFromCollection); var distinctRows = allRows.Distinct(); foreach (var distinctRow in distinctRows.OrderBy(r => r)) { - Row row = new Row() { RowIndex = (UInt32Value)(UInt32)distinctRow, Spans = new ListValue() { InnerText = "1:" + maxRow.ToString() } }; + Row row = new Row() { RowIndex = (UInt32Value)(UInt32)distinctRow }; + if (maxColumn > 0) + row.Spans = new ListValue() { InnerText = "1:" + maxColumn.ToString() }; + if (xlWorksheet.Internals.RowsCollection.ContainsKey(distinctRow)) { var thisRow = xlWorksheet.Internals.RowsCollection[distinctRow]; + var thisRowStyleString = thisRow.Style.ToString(); row.Height = thisRow.Height; row.CustomHeight = true; - row.StyleIndex = sharedStyles[thisRow.Style.ToString()].StyleId; + row.StyleIndex = sharedStyles[thisRowStyleString].StyleId; row.CustomFormat = true; } + else + { + row.Height = xlWorksheet.DefaultRowHeight; + row.CustomHeight = true; + } + foreach (var opCell in xlWorksheet.Internals.CellsCollection - .Where(c => c.Key.Row == distinctRow) + .Where(c => c.Key.RowNumber == distinctRow) .OrderBy(c => c.Key) .Select(c => c)) { @@ -935,7 +994,7 @@ rowBreaks = new RowBreaks() { Count = (UInt32Value)(UInt32)rowBreakCount, ManualBreakCount = (UInt32)rowBreakCount }; foreach (var rb in xlWorksheet.PageSetup.RowBreaks) { - Break break1 = new Break() { Id = (UInt32Value)(UInt32)rb, Max = (UInt32Value)(UInt32)xlWorksheet.LastRow().RowNumber, ManualPageBreak = true }; + Break break1 = new Break() { Id = (UInt32Value)(UInt32)rb, Max = (UInt32Value)(UInt32)xlWorksheet.LastAddressInSheet.RowNumber, ManualPageBreak = true }; rowBreaks.Append(break1); } @@ -948,7 +1007,7 @@ columnBreaks = new ColumnBreaks() { Count = (UInt32Value)(UInt32)columnBreakCount, ManualBreakCount = (UInt32Value)(UInt32)columnBreakCount }; foreach (var cb in xlWorksheet.PageSetup.ColumnBreaks) { - Break break1 = new Break() { Id = (UInt32Value)(UInt32)cb, Max = (UInt32Value)(UInt32)xlWorksheet.LastColumn().ColumnNumber, ManualPageBreak = true }; + Break break1 = new Break() { Id = (UInt32Value)(UInt32)cb, Max = (UInt32Value)(UInt32)xlWorksheet.LastAddressInSheet.ColumnNumber, ManualPageBreak = true }; columnBreaks.Append(break1); } @@ -972,6 +1031,55 @@ worksheetPart.Worksheet = worksheet; } + //private void AppendColumns(Columns columns, Int32 startingColumn, IXLWorksheet xlWorksheet) + //{ + // var minUsable = xlWorksheet.Internals.ColumnsCollection.Keys.Where(i => i >= startingColumn).Select(i=>i).Min(); + // if (startingColumn < minUsable) + // { + // Column column = new Column() + // { + // Min = (UInt32Value)(UInt32)startingColumn, + // Max = (UInt32Value)(UInt32)(minUsable - 1), + // Style = sharedStyles[xlWorksheet.Style.ToString()].StyleId, + // Width = xlWorksheet.DefaultColumnWidth, + // CustomWidth = true + // }; + // columns.Append(column); + // } + // else + // { + // var maxInColumnsCollection = xlWorksheet.Internals.ColumnsCollection.Keys.Max(); + // var maxUsable = maxInColumnsCollection; + // for (var co = minUsable + 1; co <= maxInColumnsCollection; co++) + // { + // if (!xlWorksheet.Internals.ColumnsCollection.ContainsKey(co + 1)) + // { + // maxUsable = co; + // break; + // } + // } + + // Column column = new Column() + // { + // Min = (UInt32Value)(UInt32)minUsable, + // Max = (UInt32Value)(UInt32)maxUsable, + // Style = sharedStyles[xlWorksheet.Style.ToString()].StyleId, + // Width = xlWorksheet.DefaultColumnWidth, + // CustomWidth = true + // }; + // columns.Append(column); + // } + // for(var co = startingColumn; co < minUsable; co++) + // { + + // } + + // var maxTotalColumns = XLWorksheet.MaxNumberOfColumns; + + + // //var xlWorksheet.Internals.ColumnsCollection + //} + private void GenerateThemePartContent(ThemePart themePart) { A.Theme theme1 = new A.Theme() { Name = "Office Theme" }; diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs index e5a0e90..13b0691 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheet.cs @@ -6,8 +6,14 @@ namespace ClosedXML.Excel { - public class XLWorksheet: IXLWorksheet + + internal delegate void RangeShiftedRowsDelegate(XLRange range, Int32 rowsShifted); + internal delegate void RangeShiftedColumnsDelegate(XLRange range, Int32 columnsShifted); + internal class XLWorksheet : XLRangeBase, IXLWorksheet { + public event RangeShiftedRowsDelegate RangeShiftedRows; + public event RangeShiftedColumnsDelegate RangeShiftedColumns; + #region Constants public const Int32 MaxNumberOfRows = 1048576; @@ -17,45 +23,190 @@ public XLWorksheet(String sheetName) { + Worksheet = this; Style = XLWorkbook.DefaultStyle; - Internals = new XLWorksheetInternals(new Dictionary(), new Dictionary(), new Dictionary(), new List()); - RowNumber = 1; - ColumnNumber = 1; - ColumnLetter = "A"; + Internals = new XLWorksheetInternals(new Dictionary(), new XLColumnsCollection(), new XLRowsCollection(), new List()); + FirstAddressInSheet = new XLAddress(1, 1); + LastAddressInSheet = new XLAddress(MaxNumberOfRows, MaxNumberOfColumns); PageSetup = new XLPageOptions(XLWorkbook.DefaultPageOptions, this); + DefaultColumnWidth = XLWorkbook.DefaultColumnWidth; + DefaultRowHeight = XLWorkbook.DefaultRowHeight; this.Name = sheetName; + RangeShiftedRows += new RangeShiftedRowsDelegate(XLWorksheet_RangeShiftedRows); + RangeShiftedColumns += new RangeShiftedColumnsDelegate(XLWorksheet_RangeShiftedColumns); } + void XLWorksheet_RangeShiftedColumns(XLRange range, int columnsShifted) + { + var newMerge = new List(); + foreach (var merge in Internals.MergedCells) + { + var rng = Range(merge); + if (range.FirstAddressInSheet.ColumnNumber <= rng.FirstAddressInSheet.ColumnNumber) + { + var newRng = Range( + rng.FirstAddressInSheet.RowNumber, + rng.FirstAddressInSheet.ColumnNumber + columnsShifted, + rng.LastAddressInSheet.RowNumber, + rng.LastAddressInSheet.ColumnNumber + columnsShifted); + newMerge.Add(newRng.ToString()); + } + else + { + newMerge.Add(rng.ToString()); + } + } + Internals.MergedCells = newMerge; + } - public IXLWorksheetInternals Internals { get; private set; } + void XLWorksheet_RangeShiftedRows(XLRange range, int rowsShifted) + { + var newMerge = new List(); + foreach (var merge in Internals.MergedCells) + { + var rng = Range(merge); + if (range.FirstAddressInSheet.RowNumber <= rng.FirstAddressInSheet.RowNumber) + { + var newRng = Range( + rng.FirstAddressInSheet.RowNumber + rowsShifted, + rng.FirstAddressInSheet.ColumnNumber, + rng.LastAddressInSheet.RowNumber + rowsShifted, + rng.LastAddressInSheet.ColumnNumber); + newMerge.Add(newRng.ToString()); + } + else + { + newMerge.Add(rng.ToString()); + } + } + Internals.MergedCells = newMerge; + } - #region IXLRange Members + public void NotifyRangeShiftedRows(XLRange range, Int32 rowsShifted) + { + if (RangeShiftedRows != null) + RangeShiftedRows(range, rowsShifted); + } - public Int32 RowNumber { get; private set; } - public Int32 ColumnNumber { get; private set; } - public String ColumnLetter { get; private set; } + public void NotifyRangeShiftedColumns(XLRange range, Int32 columnsShifted) + { + if (RangeShiftedColumns != null) + RangeShiftedColumns(range, columnsShifted); + } + + + public XLWorksheetInternals Internals { get; private set; } + + #region IXLStylized Members + + private IXLStyle style; + public override IXLStyle Style + { + get + { + return style; + } + set + { + style = new XLStyle(this, value); + } + } + + public override IEnumerable Styles + { + get + { + UpdatingStyle = true; + yield return style; + foreach (var c in Internals.CellsCollection.Values) + { + yield return c.Style; + } + UpdatingStyle = false; + } + } + + public override Boolean UpdatingStyle { get; set; } + + #endregion + + public Double DefaultColumnWidth { get; set; } + public Double DefaultRowHeight { get; set; } + + public String Name { get; set; } + + public IXLPageOptions PageSetup { get; private set; } + + public IXLRow FirstRowUsed() + { + var rngRow = this.AsRange().FirstRowUsed(); + if (rngRow != null) + { + return this.Row(rngRow.FirstAddressInSheet.RowNumber); + } + else + { + return null; + } + } + public IXLRow LastRowUsed() + { + var rngRow = this.AsRange().LastRowUsed(); + if (rngRow != null) + { + return this.Row(rngRow.LastAddressInSheet.RowNumber); + } + else + { + return null; + } + } + public IXLColumn FirstColumnUsed() + { + var rngColumn = this.AsRange().FirstColumnUsed(); + if (rngColumn != null) + { + return this.Column(rngColumn.FirstAddressInSheet.ColumnNumber); + } + else + { + return null; + } + } + public IXLColumn LastColumnUsed() + { + var rngColumn = this.AsRange().LastColumnUsed(); + if (rngColumn != null) + { + return this.Column(rngColumn.LastAddressInSheet.ColumnNumber); + } + else + { + return null; + } + } public IXLColumns Columns() { - var retVal = new XLColumns(); + var retVal = new XLColumns(this, true); var columnList = new List(); - if (Internals.CellsCollection.Count > 0) - columnList.AddRange(Internals.CellsCollection.Keys.Select(k => k.Column).Distinct()); + if (this.Internals.CellsCollection.Count > 0) + columnList.AddRange(this.Internals.CellsCollection.Keys.Select(k => k.ColumnNumber).Distinct()); - if (Internals.ColumnsCollection.Count > 0) - columnList.AddRange(Internals.ColumnsCollection.Keys.Where(c => !columnList.Contains(c))); + if (this.Internals.ColumnsCollection.Count > 0) + columnList.AddRange(this.Internals.ColumnsCollection.Keys.Where(c => !columnList.Contains(c))); foreach (var c in columnList) { - retVal.Add(Column(c)); + retVal.Add((XLColumn)this.Column(c)); } return retVal; } - public IXLColumns Columns(String columns) + public IXLColumns Columns( String columns) { - var retVal = new XLColumns(); + var retVal = new XLColumns(this); var columnPairs = columns.Split(','); foreach (var pair in columnPairs) { @@ -72,57 +223,57 @@ firstColumn = pair; lastColumn = pair; } - + Int32 tmp; if (Int32.TryParse(firstColumn, out tmp)) - foreach (var col in Columns(Int32.Parse(firstColumn), Int32.Parse(lastColumn))) + foreach (var col in this.Columns(Int32.Parse(firstColumn), Int32.Parse(lastColumn))) { - retVal.Add(col); + retVal.Add((XLColumn)col); } else - foreach (var col in Columns(firstColumn, lastColumn)) + foreach (var col in this.Columns(firstColumn, lastColumn)) { - retVal.Add(col); + retVal.Add((XLColumn)col); } } return retVal; } - public IXLColumns Columns(String firstColumn, String lastColumn) + public IXLColumns Columns( String firstColumn, String lastColumn) { - return Columns(XLAddress.GetColumnNumberFromLetter(firstColumn), XLAddress.GetColumnNumberFromLetter(lastColumn)); + return this.Columns(XLAddress.GetColumnNumberFromLetter(firstColumn), XLAddress.GetColumnNumberFromLetter(lastColumn)); } - public IXLColumns Columns(Int32 firstColumn, Int32 lastColumn) + public IXLColumns Columns( Int32 firstColumn, Int32 lastColumn) { - var retVal = new XLColumns(); + var retVal = new XLColumns(this); for (var co = firstColumn; co <= lastColumn; co++) { - retVal.Add(Column(co)); + retVal.Add((XLColumn)this.Column(co)); } return retVal; } public IXLRows Rows() { - var retVal = new XLRows(); + var retVal = new XLRows(this, true); var rowList = new List(); - if (Internals.CellsCollection.Count > 0) - rowList.AddRange(Internals.CellsCollection.Keys.Select(k => k.Row).Distinct()); + if (this.Internals.CellsCollection.Count > 0) + rowList.AddRange(this.Internals.CellsCollection.Keys.Select(k => k.RowNumber).Distinct()); - if (Internals.ColumnsCollection.Count > 0) - rowList.AddRange(Internals.ColumnsCollection.Keys.Where(r => !rowList.Contains(r))); + if (this.Internals.ColumnsCollection.Count > 0) + rowList.AddRange(this.Internals.ColumnsCollection.Keys.Where(r => !rowList.Contains(r))); foreach (var r in rowList) { - retVal.Add(Row(r)); + retVal.Add((XLRow)this.Row(r)); } return retVal; } - public IXLRows Rows(String rows) + public IXLRows Rows( String rows) { - var retVal = new XLRows(); + var retVal = new XLRows(this); var rowPairs = rows.Split(','); foreach (var pair in rowPairs) { @@ -139,138 +290,63 @@ firstRow = pair; lastRow = pair; } - foreach (var row in Rows(Int32.Parse(firstRow), Int32.Parse(lastRow))) + foreach (var row in this.Rows(Int32.Parse(firstRow), Int32.Parse(lastRow))) { - retVal.Add(row); + retVal.Add((XLRow)row); } } return retVal; } - public IXLRows Rows(Int32 firstRow, Int32 lastRow) + public IXLRows Rows( Int32 firstRow, Int32 lastRow) { - var retVal = new XLRows(); + var retVal = new XLRows(this); for (var ro = firstRow; ro <= lastRow; ro++) { - retVal.Add(Row(ro)); + retVal.Add((XLRow)this.Row(ro)); } return retVal; } - - public IEnumerable Cells() + public IXLRow Row( Int32 row) { - return Internals.CellsCollection.Values.AsEnumerable(); - } - - #endregion - - #region IXLStylized Members - - private IXLStyle style; - public IXLStyle Style - { - get + IXLStyle styleToUse; + if (this.Internals.RowsCollection.ContainsKey(row)) { - return style; - } - set - { - style = new XLStyle(this, value); - } - } - - public IEnumerable Styles - { - get - { - UpdatingStyle = true; - foreach (var c in Internals.CellsCollection.Values) - { - yield return c.Style; - } - - UpdatingStyle = false; - } - } - - public Boolean UpdatingStyle { get; set; } - - #endregion - - public IXLRow Row(Int32 row) - { - IXLRow xlRow; - if (Internals.RowsCollection.ContainsKey(row)) - { - xlRow = Internals.RowsCollection[row]; + styleToUse = this.Internals.RowsCollection[row].Style; } else { - var xlRowParameters = new XLRowParameters(this, Style); - xlRow = new XLRow(row, xlRowParameters); - Internals.RowsCollection.Add(row, xlRow); + styleToUse = this.Style; + this.Internals.RowsCollection.Add(row, new XLRow(row, new XLRowParameters(this, styleToUse, false))); } - return xlRow; + return new XLRow(row, new XLRowParameters(this, styleToUse, true)); } - public IXLColumn Column(Int32 column) + public IXLColumn Column( Int32 column) { - IXLColumn xlColumn; - if (Internals.ColumnsCollection.ContainsKey(column)) + IXLStyle styleToUse; + if (this.Internals.ColumnsCollection.ContainsKey(column)) { - xlColumn = Internals.ColumnsCollection[column]; + styleToUse = this.Internals.ColumnsCollection[column].Style; } else { - var xlColumnParameters = new XLColumnParameters(this, Style); - xlColumn = new XLColumn(column, xlColumnParameters); - Internals.ColumnsCollection.Add(column, xlColumn); + styleToUse = this.Style; + this.Internals.ColumnsCollection.Add(column, new XLColumn(column, new XLColumnParameters(this, this.Style, false))); } - return xlColumn; + return new XLColumn(column, new XLColumnParameters(this, this.Style, true)); } - public IXLColumn Column(String column) + public IXLColumn Column( String column) { - return Column(XLAddress.GetColumnNumberFromLetter(column)); + return this.Column(XLAddress.GetColumnNumberFromLetter(column)); } - #region IXLRange Members - - IXLRange IXLRange.Row(Int32 row) + public override IXLRange AsRange() { - var firstCellAddress = new XLAddress(row, 1); - var lastCellAddress = new XLAddress(row, MaxNumberOfColumns); - return this.Range(firstCellAddress, lastCellAddress); - } - IXLRange IXLRange.Column(int column) - { - IXLAddress firstCellAddress = new XLAddress(1, column); - IXLAddress lastCellAddress = new XLAddress(MaxNumberOfRows, column); - return this.Range(firstCellAddress, lastCellAddress); - } - IXLRange IXLRange.Column(string column) - { - IXLAddress firstCellAddress = new XLAddress(1, column); - IXLAddress lastCellAddress = new XLAddress(MaxNumberOfRows, column); - return this.Range(firstCellAddress, lastCellAddress); + return Range(1, 1, XLWorksheet.MaxNumberOfRows, XLWorksheet.MaxNumberOfColumns); } - #endregion - - - public String Name { get; set; } - - - public IXLPageSetup PageSetup { get; private set; } - - - IXLRangeInternals IXLRange.Internals - { - get - { - return new XLRangeInternals(Internals.FirstCellAddress, Internals.LastCellAddress, this); - } - } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheetInternals.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheetInternals.cs index df6a651..8f85edd 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheetInternals.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheetInternals.cs @@ -5,12 +5,12 @@ namespace ClosedXML.Excel { - public class XLWorksheetInternals: IXLWorksheetInternals + internal class XLWorksheetInternals: IXLWorksheetInternals { public XLWorksheetInternals( Dictionary cellsCollection , - Dictionary columnsCollection, - Dictionary rowsCollection, + XLColumnsCollection columnsCollection, + XLRowsCollection rowsCollection, List mergedCells) { CellsCollection = cellsCollection; @@ -18,18 +18,10 @@ RowsCollection = rowsCollection; MergedCells = mergedCells; } - public IXLAddress FirstCellAddress - { - get { return new XLAddress(1, 1); } - } - public IXLAddress LastCellAddress - { - get { return new XLAddress(XLWorksheet.MaxNumberOfRows, XLWorksheet.MaxNumberOfColumns); } - } public Dictionary CellsCollection { get; private set; } - public Dictionary ColumnsCollection { get; private set; } - public Dictionary RowsCollection { get; private set; } - public List MergedCells { get; private set; } + public XLColumnsCollection ColumnsCollection { get; private set; } + public XLRowsCollection RowsCollection { get; private set; } + public List MergedCells { get; internal set; } } } diff --git a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheets.cs b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheets.cs index 5db3550..95d64a3 100644 --- a/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheets.cs +++ b/ClosedXML/ClosedXML/ClosedXML/Excel/XLWorksheets.cs @@ -5,7 +5,7 @@ namespace ClosedXML.Excel { - public class XLWorksheets: IXLWorksheets + internal class XLWorksheets : IXLWorksheets { Dictionary worksheets = new Dictionary();