/*******************************************************************************
* You may amend and distribute as you like, but don't remove this header!
*
* EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
* See http://www.codeplex.com/EPPlus for details.
*
* Copyright (C) 2011  Jan Källman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.

* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
* If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
*
* All code and executables are provided "as is" with no warranty either express or implied.
* The author accepts no liability for any damage or loss of business that this product may cause.
*
* Code change notes:
*
* Author							Change						Date
* ******************************************************************************
* Jan Källman		    Initial Release		        2011-11-02
* Jan Källman          Total rewrite               2010-03-01
* Jan Källman		    License changed GPL-->LGPL  2011-12-27
*******************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using OfficeOpenXml.ConditionalFormatting;
using OfficeOpenXml.DataValidation;
using OfficeOpenXml.Drawing.Vml;
using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
using OfficeOpenXml.Packaging;
using OfficeOpenXml.Style.XmlAccess;
using OfficeOpenXml.Table;
using OfficeOpenXml.Table.PivotTable;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml;

/// <summary>
/// Worksheet hidden enumeration
/// </summary>
public enum eWorkSheetHidden {
  /// <summary>
  /// The worksheet is visible
  /// </summary>
  Visible,

  /// <summary>
  /// The worksheet is hidden but can be shown by the user via the user interface
  /// </summary>
  Hidden,

  /// <summary>
  /// The worksheet is hidden and cannot be shown by the user via the user interface
  /// </summary>
  VeryHidden,
}

[Flags]
internal enum CellFlags {
  //Merged = 0x1,
  RichText = 0x2,
  SharedFormula = 0x4,
  ArrayFormula = 0x8,
}

/// <summary>
/// Represents an Excel Chartsheet and provides access to its properties and methods
/// </summary>
public class ExcelChartsheet : ExcelWorksheet {
  public ExcelChartsheet(
      XmlNamespaceManager ns,
      ExcelPackage pck,
      string relId,
      Uri uriWorksheet,
      string sheetName,
      int sheetId,
      int positionId,
      eWorkSheetHidden hidden)
      : base(ns, pck, relId, uriWorksheet, sheetName, sheetId, positionId, hidden) {}
}

/// <summary>
/// Represents an Excel worksheet and provides access to its properties and methods
/// </summary>
public class ExcelWorksheet : XmlHelper, IEqualityComparer<ExcelWorksheet> {
  internal class Formulas {
    public Formulas(ISourceCodeTokenizer tokenizer) {
      _tokenizer = tokenizer;
    }

    public static string RemoveDummyFunction(string formula) {
      const string dummyFunctionConcatenate = "\"&\"";
      const string dummyFunctionPrefix = "IFERROR(__xludf.DUMMYFUNCTION(\"";
      const string dummyFunctionSuffix = "\"),";

      if (string.IsNullOrEmpty(formula)) {
        return formula;
      }

      // Look for Prefix
      if (!formula.StartsWith(dummyFunctionPrefix)) {
        return formula;
      }

      // Look for Suffix
      int index = formula.LastIndexOf(dummyFunctionSuffix);
      if (index < 0) {
        return formula;
      }

      // Trim Suffix
      formula = formula.Substring(0, index);

      // Trim Prefix
      formula = formula.Replace(dummyFunctionPrefix, "");

      // Remove string concatentations from long formulas.
      // Google break the quoted string into 254 character segments which are concatenated.
      if (formula.Length >= 254) {
        formula = formula.Replace(dummyFunctionConcatenate, "");
      }

      // Replace doubled quotes with single quote
      formula = formula.Replace("\"\"", "\"");

      // Return formula
      return formula;
    }

    private ISourceCodeTokenizer _tokenizer;

    internal int Index { get; set; }

    internal string Address { get; set; }

    internal bool IsArray { get; set; }

    public string Formula { get; set; }

    public int StartRow { get; set; }

    public int StartCol { get; set; }

    private IEnumerable<Token> Tokens { get; set; }

    internal string GetFormula(int row, int column, string worksheet) {
      if ((StartRow == row && StartCol == column) || IsArray) {
        return RemoveDummyFunction(Formula);
      }

      if (Tokens == null) {
        Tokens = _tokenizer.Tokenize(RemoveDummyFunction(Formula), worksheet);
      }

      string f = "";
      foreach (var token in Tokens) {
        if (token.TokenType == TokenType.ExcelAddress) {
          var a = new ExcelFormulaAddress(token.Value);
          f += a.GetOffset(row - StartRow, column - StartCol);
        } else {
          f += token.Value;
        }
      }
      return f;
    }
  }

  /// <summary>
  /// Collection containing merged cell addresses
  /// </summary>
  public class MergeCellsCollection : IEnumerable<string> {
    internal MergeCellsCollection() {}

    internal CellStore<int> _cells = new();
    private List<string> _list = new();

    internal List<string> List => _list;

    public string this[int row, int column] {
      get {
        int ix = -1;
        if (_cells.Exists(row, column, ref ix)
            && ix >= 0
            && ix
                < List.Count) //Fixes issue 15075
        {
          return List[ix];
        }
        return null;
      }
    }

    public string this[int index] => _list[index];

    internal void Add(ExcelAddressBase address, bool doValidate) {
      int ix = 0;

      //Validate
      if (doValidate && Validate(address) == false) {
        throw (new ArgumentException("Can't merge and already merged range"));
      }
      lock (this) {
        ix = _list.Count;
        _list.Add(address.Address);
        SetIndex(address, ix);
      }
    }

    private bool Validate(ExcelAddressBase address) {
      int ix = 0;
      if (_cells.Exists(address._fromRow, address._fromCol, ref ix)) {
        if (ix >= 0 && ix < _list.Count && _list[ix] != null && address.Address == _list[ix]) {
          return true;
        }
        return false;
      }

      var cse = new CellsStoreEnumerator<int>(
          _cells,
          address._fromRow,
          address._fromCol,
          address._toRow,
          address._toCol);
      //cells
      while (cse.Next()) {
        return false;
      }
      //Entire column
      cse = new(_cells, 0, address._fromCol, 0, address._toCol);
      while (cse.Next()) {
        return false;
      }
      //Entire row
      cse = new(_cells, address._fromRow, 0, address._toRow, 0);
      while (cse.Next()) {
        return false;
      }
      return true;
    }

    internal void SetIndex(ExcelAddressBase address, int ix) {
      if (address._fromRow == 1
          && address._toRow
              == ExcelPackage.MaxRows) //Entire row
      {
        for (int col = address._fromCol; col <= address._toCol; col++) {
          _cells.SetValue(0, col, ix);
        }
      } else if (address._fromCol == 1
          && address._toCol
              == ExcelPackage.MaxColumns) //Entire row
      {
        for (int row = address._fromRow; row <= address._toRow; row++) {
          _cells.SetValue(row, 0, ix);
        }
      } else {
        for (int col = address._fromCol; col <= address._toCol; col++) {
          for (int row = address._fromRow; row <= address._toRow; row++) {
            _cells.SetValue(row, col, ix);
          }
        }
      }
    }

    public int Count => _list.Count;

    internal void Remove(string item) {
      _list.Remove(item);
    }

    public IEnumerator<string> GetEnumerator() {
      return _list.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
      return _list.GetEnumerator();
    }

    internal void Clear(ExcelAddressBase destination) {
      var cse = new CellsStoreEnumerator<int>(
          _cells,
          destination._fromRow,
          destination._fromCol,
          destination._toRow,
          destination._toCol);
      var used = new HashSet<int>();
      while (cse.Next()) {
        var v = cse.Value;
        if (!used.Contains(v) && _list[v] != null) {
          var adr = new ExcelAddressBase(_list[v]);
          if (!(destination.Collide(adr) == ExcelAddressBase.eAddressCollition.Inside
                      || destination.Collide(adr) == ExcelAddressBase.eAddressCollition.Equal)) {
            throw (new InvalidOperationException(
                    string.Format(
                        "Can't delete merged cells. A range is partly merged with the deleted range. {0}",
                        adr._address)));
          }
          used.Add(v);
        }
      }

      _cells.Clear(
          destination._fromRow,
          destination._fromCol,
          destination._toRow - destination._fromRow + 1,
          destination._toCol - destination._fromCol + 1);
      foreach (var i in used) {
        _list[i] = null;
      }
    }
  }

  internal CellStore<object> _values;
  internal CellStore<string> _types;
  internal CellStore<int> _styles;
  internal CellStore<object> _formulas;
  internal FlagCellStore _flags;
  internal CellStore<List<Token>> _formulaTokens;

  internal CellStore<Uri> _hyperLinks;
  internal CellStore<ExcelComment> _commentsStore;

  internal Dictionary<int, Formulas> _sharedFormulas = new();
  internal int _minCol = ExcelPackage.MaxColumns;
  internal int _maxCol = 0;

  internal ExcelPackage _package;
  private Uri _worksheetUri;
  private string _name;
  private int _sheetID;
  private int _positionID;
  private string _relationshipID;
  private XmlDocument _worksheetXml;
  internal ExcelWorksheetView _sheetView;
  internal ExcelHeaderFooter _headerFooter;

  /// <summary>
  /// A worksheet
  /// </summary>
  /// <param name="ns">Namespacemanager</param>
  /// <param name="excelPackage">Package</param>
  /// <param name="relId">Relationship ID</param>
  /// <param name="uriWorksheet">URI</param>
  /// <param name="sheetName">Name of the sheet</param>
  /// <param name="sheetId">Sheet id</param>
  /// <param name="positionId">Position</param>
  /// <param name="hide">hide</param>
  public ExcelWorksheet(
      XmlNamespaceManager ns,
      ExcelPackage excelPackage,
      string relId,
      Uri uriWorksheet,
      string sheetName,
      int sheetId,
      int positionId,
      eWorkSheetHidden hide)
      : base(ns, null) {
    SchemaNodeOrder = new[] {
      "sheetPr",
      "tabColor",
      "outlinePr",
      "pageSetUpPr",
      "dimension",
      "sheetViews",
      "sheetFormatPr",
      "cols",
      "sheetData",
      "sheetProtection",
      "protectedRanges",
      "scenarios",
      "autoFilter",
      "sortState",
      "dataConsolidate",
      "customSheetViews",
      "customSheetViews",
      "mergeCells",
      "phoneticPr",
      "conditionalFormatting",
      "dataValidations",
      "hyperlinks",
      "printOptions",
      "pageMargins",
      "pageSetup",
      "headerFooter",
      "linePrint",
      "rowBreaks",
      "colBreaks",
      "customProperties",
      "cellWatches",
      "ignoredErrors",
      "smartTags",
      "drawing",
      "legacyDrawing",
      "legacyDrawingHF",
      "picture",
      "oleObjects",
      "activeXControls",
      "webPublishItems",
      "tableParts",
      "extLst",
    };
    _package = excelPackage;
    _relationshipID = relId;
    _worksheetUri = uriWorksheet;
    _name = sheetName;
    _sheetID = sheetId;
    _positionID = positionId;
    Hidden = hide;

    /**** Cellstore ****/
    _values = new();
    _types = new();
    _styles = new();
    _formulas = new();
    _flags = new();
    _commentsStore = new();
    _hyperLinks = new();

    _names = new(Workbook, this);

    CreateXml();
    TopNode = _worksheetXml.DocumentElement;
  }

  /// <summary>
  /// The Uri to the worksheet within the package
  /// </summary>
  internal Uri WorksheetUri => (_worksheetUri);

  /// <summary>
  /// The Zip.ZipPackagePart for the worksheet within the package
  /// </summary>
  internal ZipPackagePart Part => (_package.Package.GetPart(WorksheetUri));

  /// <summary>
  /// The ID for the worksheet's relationship with the workbook in the package
  /// </summary>
  internal string RelationshipID => (_relationshipID);

  /// <summary>
  /// The unique identifier for the worksheet.
  /// </summary>
  internal int SheetID => (_sheetID);

  /// <summary>
  /// The position of the worksheet.
  /// </summary>
  internal int PositionID {
    get => (_positionID);
    set => _positionID = value;
  }

  /// <summary>
  /// The index in the worksheets collection
  /// </summary>
  public int Index => (_positionID);

  /// <summary>
  /// Address for autofilter
  /// <seealso cref="ExcelRangeBase.AutoFilter" />
  /// </summary>
  public ExcelAddressBase AutoFilterAddress {
    get {
      CheckSheetType();
      string address = GetXmlNodeString("d:autoFilter/@ref");
      if (address == "") {
        return null;
      }
      return new(address);
    }
    internal set {
      CheckSheetType();
      SetXmlNodeString("d:autoFilter/@ref", value.Address);
    }
  }

  internal void CheckSheetType() {
    if (this is ExcelChartsheet) {
      throw (new NotSupportedException(
              "This property or method is not supported for a Chartsheet"));
    }
  }

  /// <summary>
  /// Returns a ExcelWorksheetView object that allows you to set the view state properties of the worksheet
  /// </summary>
  public ExcelWorksheetView View {
    get {
      if (_sheetView == null) {
        XmlNode node = TopNode.SelectSingleNode("d:sheetViews/d:sheetView", NameSpaceManager);
        if (node == null) {
          CreateNode("d:sheetViews/d:sheetView"); //this one shouls always exist. but check anyway
          node = TopNode.SelectSingleNode("d:sheetViews/d:sheetView", NameSpaceManager);
        }
        _sheetView = new(NameSpaceManager, node, this);
      }
      return (_sheetView);
    }
  }

  /// <summary>
  /// The worksheet's display name as it appears on the tab
  /// </summary>
  public string Name {
    get => (_name);
    set {
      if (value == _name) {
        return;
      }
      value = _package.Workbook.Worksheets.ValidateFixSheetName(value);
      foreach (var ws in Workbook.Worksheets) {
        if (ws.PositionID != PositionID
            && ws.Name.Equals(value, StringComparison.InvariantCultureIgnoreCase)) {
          throw (new ArgumentException("Worksheet name must be unique"));
        }
      }
      _package.Workbook.SetXmlNodeString(
          string.Format("d:sheets/d:sheet[@sheetId={0}]/@name", _sheetID),
          value);
      ChangeNames(value);

      _name = value;
    }
  }

  private void ChangeNames(string value) {
    //Renames name in this Worksheet;
    foreach (var n in Workbook.Names) {
      if (string.IsNullOrEmpty(n.NameFormula) && n.NameValue == null) {
        n.ChangeWorksheet(_name, value);
      }
    }
    foreach (var ws in Workbook.Worksheets) {
      if (!(ws is ExcelChartsheet)) {
        foreach (var n in ws.Names) {
          if (string.IsNullOrEmpty(n.NameFormula) && n.NameValue == null) {
            n.ChangeWorksheet(_name, value);
          }
        }
      }
    }
  }

  internal ExcelNamedRangeCollection _names;

  /// <summary>
  /// Provides access to named ranges
  /// </summary>
  public ExcelNamedRangeCollection Names {
    get {
      CheckSheetType();
      return _names;
    }
  }

  /// <summary>
  /// Indicates if the worksheet is hidden in the workbook
  /// </summary>
  public eWorkSheetHidden Hidden {
    get {
      string state = _package.Workbook.GetXmlNodeString(
          string.Format("d:sheets/d:sheet[@sheetId={0}]/@state", _sheetID));
      if (state == "hidden") {
        return eWorkSheetHidden.Hidden;
      }
      if (state == "veryHidden") {
        return eWorkSheetHidden.VeryHidden;
      }
      return eWorkSheetHidden.Visible;
    }
    set {
      if (value == eWorkSheetHidden.Visible) {
        _package.Workbook.DeleteNode(
            string.Format("d:sheets/d:sheet[@sheetId={0}]/@state", _sheetID));
      } else {
        string v;
        v = value.ToString();
        v = v.Substring(0, 1).ToLower(CultureInfo.InvariantCulture) + v.Substring(1);
        _package.Workbook.SetXmlNodeString(
            string.Format("d:sheets/d:sheet[@sheetId={0}]/@state", _sheetID),
            v);
      }
    }
  }

  private double _defaultRowHeight = double.NaN;

  /// <summary>
  /// Get/set the default height of all rows in the worksheet
  /// </summary>
  public double DefaultRowHeight {
    get {
      CheckSheetType();
      if (double.IsNaN(_defaultRowHeight)) {
        _defaultRowHeight = GetXmlNodeDouble("d:sheetFormatPr/@defaultRowHeight");
        if (double.IsNaN(_defaultRowHeight)) {
          _defaultRowHeight = 15; // Excel default height
        }
      }
      return _defaultRowHeight;
    }
    set {
      CheckSheetType();
      _defaultRowHeight = value;
      SetXmlNodeString(
          "d:sheetFormatPr/@defaultRowHeight",
          value.ToString(CultureInfo.InvariantCulture));
      SetXmlNodeBool("d:sheetFormatPr/@customHeight", value != 15);

      if (double.IsNaN(GetXmlNodeDouble("d:sheetFormatPr/@defaultColWidth"))) {
        DefaultColWidth = 9.140625;
      }
    }
  }

  /// <summary>
  /// Get/set the default width of all rows in the worksheet
  /// </summary>
  public double DefaultColWidth {
    get {
      CheckSheetType();
      double ret = GetXmlNodeDouble("d:sheetFormatPr/@defaultColWidth");
      if (double.IsNaN(ret)) {
        ret = 9.140625; // Excel's default width
      }
      return ret;
    }
    set {
      CheckSheetType();
      SetXmlNodeString(
          "d:sheetFormatPr/@defaultColWidth",
          value.ToString(CultureInfo.InvariantCulture));

      if (double.IsNaN(GetXmlNodeDouble("d:sheetFormatPr/@defaultRowHeight"))) {
        DefaultRowHeight = 15;
      }
    }
  }

  /** <outlinePr applyStyles="1" summaryBelow="0" summaryRight="0" /> **/
  private const string _outLineSummaryBelowPath = "d:sheetPr/d:outlinePr/@summaryBelow";

  /// <summary>
  /// Summary rows below details
  /// </summary>
  public bool OutLineSummaryBelow {
    get {
      CheckSheetType();
      return GetXmlNodeBool(_outLineSummaryBelowPath);
    }
    set {
      CheckSheetType();
      SetXmlNodeString(_outLineSummaryBelowPath, value ? "1" : "0");
    }
  }

  private const string _outLineSummaryRightPath = "d:sheetPr/d:outlinePr/@summaryRight";

  /// <summary>
  /// Summary rows to right of details
  /// </summary>
  public bool OutLineSummaryRight {
    get {
      CheckSheetType();
      return GetXmlNodeBool(_outLineSummaryRightPath);
    }
    set {
      CheckSheetType();
      SetXmlNodeString(_outLineSummaryRightPath, value ? "1" : "0");
    }
  }

  private const string _outLineApplyStylePath = "d:sheetPr/d:outlinePr/@applyStyles";

  /// <summary>
  /// Automatic styles
  /// </summary>
  public bool OutLineApplyStyle {
    get {
      CheckSheetType();
      return GetXmlNodeBool(_outLineApplyStylePath);
    }
    set {
      CheckSheetType();
      SetXmlNodeString(_outLineApplyStylePath, value ? "1" : "0");
    }
  }

  private const string _tabColorPath = "d:sheetPr/d:tabColor/@rgb";
  private const string _codeModuleNamePath = "d:sheetPr/@codeName";

  internal string CodeModuleName {
    get => GetXmlNodeString(_codeModuleNamePath);
    set => SetXmlNodeString(_codeModuleNamePath, value);
  }

  internal void CodeNameChange(string value) {
    CodeModuleName = value;
  }

  /// <summary>
  /// The XML document holding the worksheet data.
  /// All column, row, cell, pagebreak, merged cell and hyperlink-data are loaded into memory and removed from the document when loading the document.
  /// </summary>
  public XmlDocument WorksheetXml => (_worksheetXml);

  internal ExcelVmlDrawingCommentCollection _vmlDrawings;

  /// <summary>
  /// Vml drawings. underlaying object for comments
  /// </summary>
  internal ExcelVmlDrawingCommentCollection VmlDrawingsComments {
    get {
      if (_vmlDrawings == null) {
        CreateVmlCollection();
      }
      return _vmlDrawings;
    }
  }

  internal ExcelCommentCollection _comments;

  /// <summary>
  /// Collection of comments
  /// </summary>
  public ExcelCommentCollection Comments {
    get {
      CheckSheetType();
      if (_comments == null) {
        CreateVmlCollection();
        _comments = new(_package, this, NameSpaceManager);
      }
      return _comments;
    }
  }

  private void CreateVmlCollection() {
    var vmlNode = _worksheetXml.DocumentElement.SelectSingleNode(
        "d:legacyDrawing/@r:id",
        NameSpaceManager);
    if (vmlNode == null) {
      _vmlDrawings = new(_package, this, null);
    } else {
      if (Part.RelationshipExists(vmlNode.Value)) {
        var rel = Part.GetRelationship(vmlNode.Value);
        var vmlUri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);

        _vmlDrawings = new(_package, this, vmlUri);
        _vmlDrawings.RelId = rel.Id;
      }
    }
  }

  private void CreateXml() {
    _worksheetXml = new();
    _worksheetXml.PreserveWhitespace = ExcelPackage._preserveWhitespace;
    ZipPackagePart packPart = _package.Package.GetPart(WorksheetUri);
    string xml = "";

    // First Columns, rows, cells, mergecells, hyperlinks and pagebreakes are loaded from a xmlstream to optimize speed...
    Stream stream = packPart.GetStream();

    XmlTextReader xr = new XmlTextReader(stream);
    xr.ProhibitDtd = true;
    xr.WhitespaceHandling = WhitespaceHandling.None;
    LoadColumns(xr); //columnXml
    long start = stream.Position;
    LoadCells(xr);
    var nextElementLength = GetAttributeLength(xr);
    long end = stream.Position - nextElementLength;
    LoadMergeCells(xr);
    LoadHyperLinks(xr);
    LoadRowPageBreakes(xr);
    LoadColPageBreakes(xr);
    //...then the rest of the Xml is extracted and loaded into the WorksheetXml document.
    stream.Seek(0, SeekOrigin.Begin);
    Encoding encoding;
    xml = GetWorkSheetXml(stream, start, end, out encoding);

    //first char is invalid sometimes??
    if (xml[0] != '<') {
      LoadXmlSafe(_worksheetXml, xml.Substring(1, xml.Length - 1), encoding);
    } else {
      LoadXmlSafe(_worksheetXml, xml, encoding);
    }

    ClearNodes();
  }

  /// <summary>
  /// Get the lenth of the attributes
  /// Conditional formatting attributes can be extremly long som get length of the attributes to finetune position.
  /// </summary>
  /// <param name="xr"></param>
  /// <returns></returns>
  private int GetAttributeLength(XmlTextReader xr) {
    if (xr.NodeType != XmlNodeType.Element) {
      return 0;
    }
    var length = 0;

    for (int i = 0; i < xr.AttributeCount; i++) {
      var a = xr.GetAttribute(i);
      length += string.IsNullOrEmpty(a) ? 0 : a.Length;
    }
    return length;
  }

  private void LoadRowPageBreakes(XmlTextReader xr) {
    if (!ReadUntil(xr, "rowBreaks", "colBreaks")) {
      return;
    }
    while (xr.Read()) {
      if (xr.LocalName == "brk") {
        if (xr.NodeType == XmlNodeType.Element) {
          int id;
          if (int.TryParse(xr.GetAttribute("id"), out id)) {
            Row(id).PageBreak = true;
          }
        }
      } else {
        break;
      }
    }
  }

  private void LoadColPageBreakes(XmlTextReader xr) {
    if (!ReadUntil(xr, "colBreaks")) {
      return;
    }
    while (xr.Read()) {
      if (xr.LocalName == "brk") {
        if (xr.NodeType == XmlNodeType.Element) {
          int id;
          if (int.TryParse(xr.GetAttribute("id"), out id)) {
            Column(id).PageBreak = true;
          }
        }
      } else {
        break;
      }
    }
  }

  private void ClearNodes() {
    if (_worksheetXml.SelectSingleNode("//d:cols", NameSpaceManager) != null) {
      _worksheetXml.SelectSingleNode("//d:cols", NameSpaceManager).RemoveAll();
    }
    if (_worksheetXml.SelectSingleNode("//d:mergeCells", NameSpaceManager) != null) {
      _worksheetXml.SelectSingleNode("//d:mergeCells", NameSpaceManager).RemoveAll();
    }
    if (_worksheetXml.SelectSingleNode("//d:hyperlinks", NameSpaceManager) != null) {
      _worksheetXml.SelectSingleNode("//d:hyperlinks", NameSpaceManager).RemoveAll();
    }
    if (_worksheetXml.SelectSingleNode("//d:rowBreaks", NameSpaceManager) != null) {
      _worksheetXml.SelectSingleNode("//d:rowBreaks", NameSpaceManager).RemoveAll();
    }
    if (_worksheetXml.SelectSingleNode("//d:colBreaks", NameSpaceManager) != null) {
      _worksheetXml.SelectSingleNode("//d:colBreaks", NameSpaceManager).RemoveAll();
    }
  }

  private const int _blocksize = 8192;

  private string GetWorkSheetXml(Stream stream, long start, long end, out Encoding encoding) {
    StreamReader sr = new StreamReader(stream);
    int length = 0;
    char[] block;
    int pos;
    StringBuilder sb = new StringBuilder();
    Match startmMatch,
        endMatch;
    do {
      int size = stream.Length < _blocksize ? (int)stream.Length : _blocksize;
      block = new char[size];
      pos = sr.ReadBlock(block, 0, size);
      sb.Append(block, 0, pos);
      length += size;
    } while (length < start + 20 && length < end);
    startmMatch = Regex.Match(sb.ToString(), string.Format("(<[^>]*{0}[^>]*>)", "sheetData"));
    if (!startmMatch.Success) //Not found
    {
      encoding = sr.CurrentEncoding;
      return sb.ToString();
    }
    string s = sb.ToString();
    string xml = s.Substring(0, startmMatch.Index);
    if (startmMatch.Value.EndsWith("/>")) {
      xml += s.Substring(startmMatch.Index, s.Length - startmMatch.Index);
    } else {
      if (sr.Peek() != -1) {
        /**** Fixes issue 14788. Fix by Philip Garrett ****/
        long endSeekStart = end;

        while (endSeekStart >= 0) {
          endSeekStart = Math.Max(endSeekStart - _blocksize, 0);
          int size = (int)(end - endSeekStart);
          stream.Seek(endSeekStart, SeekOrigin.Begin);
          block = new char[size];
          sr = new(stream);
          pos = sr.ReadBlock(block, 0, size);
          sb = new();
          sb.Append(block, 0, pos);
          s = sb.ToString();
          endMatch = Regex.Match(s, string.Format("(</[^>]*{0}[^>]*>)", "sheetData"));
          if (endMatch.Success) {
            break;
          }
        }
      }
      endMatch = Regex.Match(s, string.Format("(</[^>]*{0}[^>]*>)", "sheetData"));
      xml +=
          "<sheetData/>"
              + s.Substring(
                  endMatch.Index + endMatch.Length,
                  s.Length - (endMatch.Index + endMatch.Length));
    }
    if (sr.Peek() > -1) {
      xml += sr.ReadToEnd();
    }

    encoding = sr.CurrentEncoding;
    return xml;
  }

  private void GetBlockPos(string xml, string tag, ref int start, ref int end) {
    Match startmMatch,
        endMatch;
    startmMatch = Regex.Match(xml.Substring(start), string.Format("(<[^>]*{0}[^>]*>)", tag)); //"<[a-zA-Z:]*" + tag + "[?]*>");

    if (!startmMatch.Success) //Not found
    {
      start = -1;
      end = -1;
      return;
    }
    var startPos = startmMatch.Index + start;
    if (startmMatch.Value.Substring(startmMatch.Value.Length - 2, 1) == "/") {
      end = startPos + startmMatch.Length;
    } else {
      endMatch = Regex.Match(xml.Substring(start), string.Format("(</[^>]*{0}[^>]*>)", tag));
      if (endMatch.Success) {
        end = endMatch.Index + endMatch.Length + start;
      }
    }
    start = startPos;
  }

  private bool ReadUntil(XmlTextReader xr, params string[] tagName) {
    if (xr.EOF) {
      return false;
    }
    while (!Array.Exists(tagName, tag => xr.LocalName.EndsWith(tag))) {
      xr.Read();
      if (xr.EOF) {
        return false;
      }
    }
    return (xr.LocalName.EndsWith(tagName[0]));
  }

  private void LoadColumns(
      XmlTextReader xr) //(string xml)
  {
    var colList = new List<IRangeId>();
    if (ReadUntil(xr, "cols", "sheetData")) {
      //if (xml != "")
      //{
      //var xr=new XmlTextReader(new StringReader(xml));
      while (xr.Read()) {
        if (xr.NodeType == XmlNodeType.Whitespace) {
          continue;
        }
        if (xr.LocalName != "col") {
          break;
        }
        if (xr.NodeType == XmlNodeType.Element) {
          int min = int.Parse(xr.GetAttribute("min"));

          ExcelColumn col = new ExcelColumn(this, min);

          col.ColumnMax = int.Parse(xr.GetAttribute("max"));
          col.Width =
              xr.GetAttribute("width") == null
                  ? 0
                  : double.Parse(xr.GetAttribute("width"), CultureInfo.InvariantCulture);
          col.BestFit =
              xr.GetAttribute("bestFit") != null && xr.GetAttribute("bestFit") == "1"
                  ? true
                  : false;
          col.Collapsed =
              xr.GetAttribute("collapsed") != null && xr.GetAttribute("collapsed") == "1"
                  ? true
                  : false;
          col.Phonetic =
              xr.GetAttribute("phonetic") != null && xr.GetAttribute("phonetic") == "1"
                  ? true
                  : false;
          col.OutlineLevel = (short)(xr.GetAttribute("outlineLevel") == null
              ? 0
              : int.Parse(xr.GetAttribute("outlineLevel"), CultureInfo.InvariantCulture));
          col.Hidden =
              xr.GetAttribute("hidden") != null && xr.GetAttribute("hidden") == "1" ? true : false;
          _values.SetValue(0, min, col);

          int style;
          if (!(xr.GetAttribute("style") == null
                      || !int.TryParse(xr.GetAttribute("style"), out style))) {
            _styles.SetValue(0, min, style);
          }
        }
      }
    }
  }

  /// <summary>
  /// Read until the node is found. If not found the xmlreader is reseted.
  /// </summary>
  /// <param name="xr">The reader</param>
  /// <param name="nodeText">Text to search for</param>
  /// <param name="altNode">Alternative text to search for</param>
  /// <returns></returns>
  private static bool ReadXmlReaderUntil(XmlTextReader xr, string nodeText, string altNode) {
    do {
      if (xr.LocalName == nodeText || xr.LocalName == altNode) {
        return true;
      }
    } while (xr.Read());
    xr.Close();
    return false;
  }

  /// <summary>
  /// Load Hyperlinks
  /// </summary>
  /// <param name="xr">The reader</param>
  private void LoadHyperLinks(XmlTextReader xr) {
    if (!ReadUntil(xr, "hyperlinks", "rowBreaks", "colBreaks")) {
      return;
    }
    while (xr.Read()) {
      if (xr.LocalName == "hyperlink") {
        int fromRow,
            fromCol,
            toRow,
            toCol;
        ExcelCellBase.GetRowColFromAddress(
            xr.GetAttribute("ref"),
            out fromRow,
            out fromCol,
            out toRow,
            out toCol);
        ExcelHyperLink hl = null;
        if (xr.GetAttribute("id", ExcelPackage._schemaRelationships) != null) {
          var rId = xr.GetAttribute("id", ExcelPackage._schemaRelationships);
          var uri = Part.GetRelationship(rId).TargetUri;

          // Get Location, if any.  EPPlus Bug 15517
          var location = xr.GetAttribute("location");
          location = (string.IsNullOrEmpty(location)) ? "" : "#" + location;

          if (uri.IsAbsoluteUri) {
            try {
              hl = new(uri.AbsoluteUri + location);
            } catch {
              hl = new(uri.OriginalString + location, UriKind.Absolute);
            }
          } else {
            hl = new(uri.OriginalString + location, UriKind.Relative);
          }

          hl.RId = rId;
          Part.DeleteRelationship(rId); //Delete the relationship, it is recreated when we save the package.
        } else if (xr.GetAttribute("location") != null) {
          hl = new(xr.GetAttribute("location"), xr.GetAttribute("display"));
          hl.RowSpann = toRow - fromRow;
          hl.ColSpann = toCol - fromCol;
        }

        string tt = xr.GetAttribute("tooltip");
        if (!string.IsNullOrEmpty(tt)) {
          hl.ToolTip = tt;
        }
        _hyperLinks.SetValue(fromRow, fromCol, hl);
      } else {
        break;
      }
    }
  }

  /// <summary>
  /// Load cells
  /// </summary>
  /// <param name="xr">The reader</param>
  private void LoadCells(XmlTextReader xr) {
    //var cellList=new List<IRangeID>();
    //var rowList = new List<IRangeID>();
    //var formulaList = new List<IRangeID>();
    ReadUntil(xr, "sheetData", "mergeCells", "hyperlinks", "rowBreaks", "colBreaks");
    ExcelAddressBase address = null;
    string type = "";
    int style = 0;
    int row = 0;
    int col = 0;
    xr.Read();

    while (!xr.EOF) {
      while (xr.NodeType == XmlNodeType.EndElement) {
        xr.Read();
      }
      if (xr.LocalName == "row") {
        var r = xr.GetAttribute("r");
        if (r == null) {
          row++;
        } else {
          row = Convert.ToInt32(r);
        }

        if (DoAddRow(xr)) {
          _values.SetValue(row, 0, AddRow(xr, row));
          if (xr.GetAttribute("s") != null) {
            _styles.SetValue(row, 0, int.Parse(xr.GetAttribute("s"), CultureInfo.InvariantCulture));
          }
        }
        xr.Read();
      } else if (xr.LocalName == "c") {
        //if (cell != null) cellList.Add(cell);
        //cell = new ExcelCell(this, xr.GetAttribute("r"));
        var r = xr.GetAttribute("r");
        if (r == null) {
          //Handle cells with no reference
          col++;
          address = new(row, col, row, col);
        } else {
          address = new(r);
          col = address._fromCol;
        }

        //Datetype
        if (xr.GetAttribute("t") != null) {
          type = xr.GetAttribute("t");
          _types.SetValue(address._fromRow, address._fromCol, type);
        } else {
          type = "";
        }
        //Style
        if (xr.GetAttribute("s") != null) {
          style = int.Parse(xr.GetAttribute("s"));
          _styles.SetValue(address._fromRow, address._fromCol, style);
          _values.SetValue(address._fromRow, address._fromCol, null); //TODO:Better Performance ??
        } else {
          style = 0;
        }
        xr.Read();
      } else if (xr.LocalName == "v") {
        SetValueFromXml(xr, type, style, address._fromRow, address._fromCol);

        xr.Read();
      } else if (xr.LocalName == "f") {
        string t = xr.GetAttribute("t");
        if (t == null) {
          _formulas.SetValue(address._fromRow, address._fromCol, xr.ReadElementContentAsString());
          _values.SetValue(address._fromRow, address._fromCol, null);
          //formulaList.Add(cell);
        } else if (t == "shared") {
          string si = xr.GetAttribute("si");
          if (si != null) {
            var sfIndex = int.Parse(si);
            _formulas.SetValue(address._fromRow, address._fromCol, sfIndex);
            _values.SetValue(address._fromRow, address._fromCol, null);
            string fAddress = xr.GetAttribute("ref");
            string formula = ConvertUtil.ExcelDecodeString(xr.ReadElementContentAsString());
            if (formula != "") {
              _sharedFormulas.Add(
                  sfIndex,
                  new(SourceCodeTokenizer.Default) {
                    Index = sfIndex,
                    Formula = formula,
                    Address = fAddress,
                    StartRow = address._fromRow,
                    StartCol = address._fromCol,
                  });
            }
          } else {
            xr.Read(); //Something is wrong in the sheet, read next
          }
        } else if (t
            == "array") //TODO: Array functions are not support yet. Read the formula for the start cell only.
        {
          string aAddress = xr.GetAttribute("ref");
          ExcelRange addressRange = new ExcelRange(this, aAddress);
          string formula = xr.ReadElementContentAsString();
          bool isIndexMatchFormula =
              Regex.IsMatch(formula, @"INDEX\(", RegexOptions.IgnoreCase)
                  && Regex.IsMatch(formula, @"MATCH\(", RegexOptions.IgnoreCase)
                  && !aAddress.Contains(":");
          if (isIndexMatchFormula) {
            addressRange.IsArrayFormula = false;
            for (int colIndex = addressRange.Start.Column;
                colIndex <= addressRange.End.Column;
                colIndex++) {
              for (int rowIndex = addressRange.Start.Row;
                  rowIndex <= addressRange.End.Row;
                  rowIndex++) {
                var afIndex = GetMaxShareFunctionIndex(true);
                _formulas.SetValue(rowIndex, colIndex, afIndex);
                _values.SetValue(rowIndex, colIndex, null);
                _sharedFormulas.Add(
                    afIndex,
                    new(SourceCodeTokenizer.Default) {
                      Index = afIndex,
                      Formula = formula,
                      Address = aAddress,
                      StartRow = address._fromRow,
                      StartCol = address._fromCol,
                      IsArray = false,
                    });
              }
            }
          } else {
            addressRange.IsArrayFormula = true;
            var afIndex = GetMaxShareFunctionIndex(true);
            for (int colIndex = addressRange.Start.Column;
                colIndex <= addressRange.End.Column;
                colIndex++) {
              for (int rowIndex = addressRange.Start.Row;
                  rowIndex <= addressRange.End.Row;
                  rowIndex++) {
                _formulas.SetValue(rowIndex, colIndex, afIndex);
                _values.SetValue(rowIndex, colIndex, null);
              }
            }
            _sharedFormulas.Add(
                afIndex,
                new(SourceCodeTokenizer.Default) {
                  Index = afIndex,
                  Formula = formula,
                  Address = aAddress,
                  StartRow = address._fromRow,
                  StartCol = address._fromCol,
                  IsArray = true,
                });
          }
        } else // ??? some other type
        {
          xr.Read(); //Something is wrong in the sheet, read next
        }
      } else if (xr.LocalName
          == "is") //Inline string
      {
        xr.Read();
        if (xr.LocalName == "t") {
          _values.SetValue(
              address._fromRow,
              address._fromCol,
              ConvertUtil.ExcelDecodeString(xr.ReadElementContentAsString()));
          //cell._value = xr.ReadInnerXml();
        } else {
          _values.SetValue(address._fromRow, address._fromCol, xr.ReadOuterXml());
          _types.SetValue(address._fromRow, address._fromCol, "rt");
          _flags.SetFlagValue(address._fromRow, address._fromCol, true, CellFlags.RichText);
          //cell.IsRichText = true;
        }
      } else {
        break;
      }
    }
    //if (cell != null) cellList.Add(cell);

    //_cells = new RangeCollection(cellList);
    //_rows = new RangeCollection(rowList);
    //_formulaCells = new RangeCollection(formulaList);
  }

  private bool DoAddRow(XmlTextReader xr) {
    var c = xr.GetAttribute("r") == null ? 0 : 1;
    if (xr.GetAttribute("spans") != null) {
      c++;
    }
    return xr.AttributeCount > c;
  }

  /// <summary>
  /// Load merged cells
  /// </summary>
  /// <param name="xr"></param>
  private void LoadMergeCells(XmlTextReader xr) {
    if (ReadUntil(xr, "mergeCells", "hyperlinks", "rowBreaks", "colBreaks") && !xr.EOF) {
      while (xr.Read()) {
        if (xr.LocalName != "mergeCell") {
          break;
        }
        if (xr.NodeType == XmlNodeType.Element) {
          string address = xr.GetAttribute("ref");
          //int fromRow, fromCol, toRow, toCol;
          //ExcelCellBase.GetRowColFromAddress(address, out fromRow, out fromCol, out toRow, out toCol);
          //for (int row = fromRow; row <= toRow; row++)
          //{
          //    for (int col = fromCol; col <= toCol; col++)
          //    {
          //        _flags.SetFlagValue(row, col, true,CellFlags.Merged);
          //    }
          //}
          //_mergedCells.List.Add(address);
          _mergedCells.Add(new ExcelAddress(address), false);
        }
      }
    }
  }

  /// <summary>
  /// Update merged cells
  /// </summary>
  /// <param name="sw">The writer</param>
  private void UpdateMergedCells(StreamWriter sw) {
    sw.Write("<mergeCells>");
    foreach (string address in _mergedCells) {
      sw.Write("<mergeCell ref=\"{0}\" />", address);
    }
    sw.Write("</mergeCells>");
  }

  /// <summary>
  /// Reads a row from the XML reader
  /// </summary>
  /// <param name="xr">The reader</param>
  /// <param name="row">The row number</param>
  /// <returns></returns>
  private RowInternal AddRow(XmlTextReader xr, int row) {
    return new() {
      Collapsed =
          (xr.GetAttribute("collapsed") != null && xr.GetAttribute("collapsed") == "1"
              ? true
              : false),
      OutlineLevel =
          (xr.GetAttribute("outlineLevel") == null
              ? (short)0
              : short.Parse(xr.GetAttribute("outlineLevel"), CultureInfo.InvariantCulture)),
      Height =
          (xr.GetAttribute("ht") == null
              ? -1
              : double.Parse(xr.GetAttribute("ht"), CultureInfo.InvariantCulture)),
      Hidden =
          (xr.GetAttribute("hidden") != null && xr.GetAttribute("hidden") == "1" ? true : false),
      Phonetic = xr.GetAttribute("ph") != null && xr.GetAttribute("ph") == "1" ? true : false,
      CustomHeight =
          xr.GetAttribute("customHeight") == null ? false : xr.GetAttribute("customHeight") == "1",
    };
  }

  private static readonly DateTime _excelEpoch = new(1899, 12, 30);

  public static DateTime IncorrectDurationFromOaDate(double value) {
    // This behavior is wrong. Real OADate values have a discontinuity on 30 December 1899.
    // For real OADate values, the negative sign applies only to the integer portion of
    // the float, *not* to the decimal portion. For example, -0.5 and 0.5 both refer to the
    // same date, and -1.5 is actually 1899-12-29 12:00 (1 day before 1899-12-30 00:00
    // plus 0.5 days), *not* 1899-12-28 12:00 (1.5 days before 1899-12-30 00:00).
    //
    // Unfortunately, AppSheet's duration-handling code gets this very wrong, and treats the
    // duration as the offset from 1899-12-30 00:00. This is correct for positive durations,
    // but it's wrong for negative durations. This code tries to fix the bug that exists in
    // AppSheet's duration-handling code here, and it succeeds in some cases and fails in
    // others.
    //
    // This code also breaks date/time handling for dates before 1899-12-30 00:00 in some
    // cases. Specifically, dates end up being offset by one day.
    //
    // Regardless, changing this behavior is risky, so this code simply replicates the
    // existing behavior for
    if (value >= 0) {
      return DateTime.FromOADate(value);
    }
    // This looks like a very complicated way to call TimeSpan.FromDays(value), but
    // TimeSpan.FromDays actually only guarantees millisecond precision, and critically
    // rounding is different on .NET Core, resulting in values like (e.g.) 3:15:00 being
    // incorrectly rounded.
    var offset = DateTime.FromOADate(-value) - _excelEpoch;
    return _excelEpoch - offset;
  }

  private void SetValueFromXml(XmlTextReader xr, string type, int styleId, int row, int col) {
    //XmlNode vnode = colNode.SelectSingleNode("d:v", NameSpaceManager);
    //if (vnode == null) return null;
    if (type == "s") {
      int ix = xr.ReadElementContentAsInt();

      // Temporary debugging code to locate intermittent 'Index was out of range' exception.
      if (ix < 0) {
        throw new(
            string.Format(
                "ReadElementContentAsInt returned value '{0}' which is less than zero.",
                ix));
      }
      if (ix >= _package.Workbook._sharedStringsList.Count) {
        throw new(
            string.Format(
                "ReadElementContentAsInt returned index value '{0}' which is greater than _sharedStringsList count of {1}.",
                ix,
                _package.Workbook._sharedStringsList.Count));
      }

      _values.SetValue(row, col, _package.Workbook._sharedStringsList[ix].Text);
      if (_package.Workbook._sharedStringsList[ix].isRichText) {
        _flags.SetFlagValue(row, col, true, CellFlags.RichText);
      }
    } else if (type == "str") {
      _values.SetValue(row, col, ConvertUtil.ExcelDecodeString(xr.ReadElementContentAsString()));
    } else if (type == "b") {
      _values.SetValue(row, col, (xr.ReadElementContentAsString() != "0"));
    } else if (type == "e") {
      _values.SetValue(row, col, GetErrorType(xr.ReadElementContentAsString()));
    } else {
      string v = xr.ReadElementContentAsString();
      var nf = Workbook.Styles.CellXfs[styleId].NumberFormatId;
      if ((nf >= 20 && nf <= 21)
          || (nf >= 45
                  && nf
                      <= 47)) // Duration
      {
        double res;
        if (double.TryParse(v, NumberStyles.Any, CultureInfo.InvariantCulture, out res)) {
          if (Workbook.Date1904) {
            res += ExcelWorkbook._date1904Offset;
          }
          if (res >= -657435.0 && res < 2958465.9999999) {
            // Get the Duration value expressed as a DateTime.
            _values.SetValue(row, col, IncorrectDurationFromOaDate(res));
          } else {
            // Cope with Google Sheets export of cells having a formula.
            // Rather than exporting the native value, they export the formatted value.
            _values.SetValue(row, col, v);
          }
        } else {
          // Cope with Google Sheets export of cells having a formula.
          // Rather than exporting the native value, they export the formatted value.
          _values.SetValue(row, col, v);
        }
      } else if ((nf >= 14 && nf <= 19)
          || (nf
                  == 22)) // DateTime
      {
        double res;
        if (double.TryParse(v, NumberStyles.Any, CultureInfo.InvariantCulture, out res)) {
          if (Workbook.Date1904) {
            res += ExcelWorkbook._date1904Offset;
          }
          if (res >= -657435.0 && res < 2958465.9999999) {
            _values.SetValue(row, col, DateTime.FromOADate(res));
          } else {
            // Cope with Google Sheets export of cells having a formula.
            // Rather than exporting the native value, they export the formatted value.
            _values.SetValue(row, col, v);
          }
        } else {
          // Cope with Google Sheets export of cells having a formula.
          // Rather than exporting the native value, they export the formatted value.
          _values.SetValue(row, col, v);
        }
      } else {
        double d;
        if (double.TryParse(v, NumberStyles.Any, CultureInfo.InvariantCulture, out d)) {
          _values.SetValue(row, col, d);
        } else {
          // Cope with Google Sheets export of cells having a formula.
          // Rather than exporting the native value, they export the formatted value.
          _values.SetValue(row, col, v);

          //_values.SetValue(row, col, double.NaN);
        }
      }
    }
  }

  private object GetErrorType(string v) {
    return ExcelErrorValue.Parse(v.ToUpper(CultureInfo.InvariantCulture));
    //switch(v.ToUpper())
    //{
    //    case "#DIV/0!":
    //        return new ExcelErrorValue.cre(eErrorType.Div0);
    //    case "#REF!":
    //        return new ExcelErrorValue(eErrorType.Ref);
    //    case "#N/A":
    //        return new ExcelErrorValue(eErrorType.NA);
    //    case "#NAME?":
    //        return new ExcelErrorValue(eErrorType.Name);
    //    case "#NULL!":
    //        return new ExcelErrorValue(eErrorType.Null);
    //    case "#NUM!":
    //        return new ExcelErrorValue(eErrorType.Num);
    //    default:
    //        return new ExcelErrorValue(eErrorType.Value);
    //}
  }

  //private string GetSharedString(int stringID)
  //{
  //    string retValue = null;
  //    XmlNodeList stringNodes = xlPackage.Workbook.SharedStringsXml.SelectNodes(string.Format("//d:si", stringID), NameSpaceManager);
  //    XmlNode stringNode = stringNodes[stringID];
  //    if (stringNode != null)
  //        retValue = stringNode.InnerText;
  //    return (retValue);
  //}



  /// <summary>
  /// A reference to the header and footer class which allows you to
  /// set the header and footer for all odd, even and first pages of the worksheet
  /// </summary>
  /// <remarks>
  /// To format the text you can use the following format
  /// <list type="table">
  /// <listheader><term>Prefix</term><description>Description</description></listheader>
  /// <item><term>&amp;U</term><description>Underlined</description></item>
  /// <item><term>&amp;E</term><description>Double Underline</description></item>
  /// <item><term>&amp;K:xxxxxx</term><description>Color. ex &amp;K:FF0000 for red</description></item>
  /// <item><term>&amp;"Font,Regular Bold Italic"</term><description>Changes the font. Regular or Bold or Italic or Bold Italic can be used. ex &amp;"Arial,Bold Italic"</description></item>
  /// <item><term>&amp;nn</term><description>Change font size. nn is an integer. ex &amp;24</description></item>
  /// <item><term>&amp;G</term><description>Placeholder for images. Images can not be added by the library, but its possible to use in a template.</description></item>
  /// </list>
  /// </remarks>
  public ExcelHeaderFooter HeaderFooter {
    get {
      if (_headerFooter == null) {
        XmlNode headerFooterNode = TopNode.SelectSingleNode("d:headerFooter", NameSpaceManager);
        if (headerFooterNode == null) {
          headerFooterNode = CreateNode("d:headerFooter");
        }
        _headerFooter = new(NameSpaceManager, headerFooterNode, this);
      }
      return (_headerFooter);
    }
  }

  /// <summary>
  /// Printer settings
  /// </summary>
  public ExcelPrinterSettings PrinterSettings {
    get {
      var ps = new ExcelPrinterSettings(NameSpaceManager, TopNode, this);
      ps.SchemaNodeOrder = SchemaNodeOrder;
      return ps;
    }
  }

  ///// <summary>
  ///// Provides access to an individual cell within the worksheet.
  ///// </summary>
  ///// <param name="row">The row number in the worksheet</param>
  ///// <param name="col">The column number in the worksheet</param>
  ///// <returns></returns>
  //internal ExcelCell Cell(int row, int col)
  //{
  //    return new ExcelCell(_values, row, col);
  //}
  /// <summary>
  /// Provides access to a range of cells
  /// </summary>
  public ExcelRange Cells {
    get {
      CheckSheetType();
      return new(this, 1, 1, ExcelPackage.MaxRows, ExcelPackage.MaxColumns);
    }
  }

  /// <summary>
  /// Provides access to the selected range of cells
  /// </summary>
  public ExcelRange SelectedRange {
    get {
      CheckSheetType();
      return new(this, View.SelectedRange);
    }
  }

  private MergeCellsCollection _mergedCells = new();

  /// <summary>
  /// Addresses to merged ranges
  /// </summary>
  public MergeCellsCollection MergedCells {
    get {
      CheckSheetType();
      return _mergedCells;
    }
  }

  /// <summary>
  /// Provides access to an individual row within the worksheet so you can set its properties.
  /// </summary>
  /// <param name="row">The row number in the worksheet</param>
  /// <returns></returns>
  public ExcelRow Row(int row) {
    //ExcelRow r;
    //ulong id = ExcelRow.GetRowID(_sheetID, row);
    //TODO: Fixa.
    //var v = _values.GetValue(row, 0);
    //if (v!=null)
    //{
    //    var ri=(RowInternal)v;
    //    r = new ExcelRow(this, row)
    //}
    //else
    //{
    //r = new ExcelRow(this, row);
    //_values.SetValue(row, 0, r);
    //_rows.Add(r);
    //}
    CheckSheetType();
    if (row < 1 || row > ExcelPackage.MaxRows) {
      throw (new ArgumentException("Row number out of bounds"));
    }
    return new(this, row);
    //return r;
  }

  /// <summary>
  /// Provides access to an individual column within the worksheet so you can set its properties.
  /// </summary>
  /// <param name="col">The column number in the worksheet</param>
  /// <returns></returns>
  public ExcelColumn Column(int col) {
    CheckSheetType();
    if (col < 1 || col > ExcelPackage.MaxColumns) {
      throw (new ArgumentException("Column number out of bounds"));
    }
    var column = _values.GetValue(0, col) as ExcelColumn;
    if (column != null) {
      if (column.ColumnMin != column.ColumnMax) {
        int maxCol = column.ColumnMax;
        column.ColumnMax = col;
        ExcelColumn copy = CopyColumn(column, col + 1, maxCol);
      }
    } else {
      int r = 0,
          c = col;
      if (_values.PrevCell(ref r, ref c)) {
        column = _values.GetValue(0, c) as ExcelColumn;
        int maxCol = column.ColumnMax;
        if (maxCol >= col) {
          column.ColumnMax = col - 1;
          if (maxCol > col) {
            ExcelColumn newC = CopyColumn(column, col + 1, maxCol);
          }
          return CopyColumn(column, col, col);
        }
      }
      //foreach (ExcelColumn checkColumn in _columns)
      //{
      //    if (col > checkColumn.ColumnMin && col <= checkColumn.ColumnMax)
      //    {
      //        int maxCol = checkColumn.ColumnMax;
      //        checkColumn.ColumnMax = col - 1;
      //        if (maxCol > col)
      //        {
      //            ExcelColumn newC = CopyColumn(checkColumn, col + 1, maxCol);
      //        }
      //        return CopyColumn(checkColumn, col,col);
      //    }
      //}
      column = new(this, col);
      _values.SetValue(0, col, column);
      //_columns.Add(column);
    }
    return column;
  }

  /// <summary>
  /// Returns the name of the worksheet
  /// </summary>
  /// <returns>The name of the worksheet</returns>
  public override string ToString() {
    return Name;
  }

  internal ExcelColumn CopyColumn(ExcelColumn c, int col, int maxCol) {
    ExcelColumn newC = new ExcelColumn(this, col);
    newC.ColumnMax = maxCol < ExcelPackage.MaxColumns ? maxCol : ExcelPackage.MaxColumns;
    if (c.StyleName != "") {
      newC.StyleName = c.StyleName;
    } else {
      newC.StyleID = c.StyleID;
    }

    newC.OutlineLevel = c.OutlineLevel;
    newC.Phonetic = c.Phonetic;
    newC.BestFit = c.BestFit;
    //_columns.Add(newC);
    _values.SetValue(0, col, newC);
    newC._width = c._width;
    newC._hidden = c._hidden;
    return newC;
  }

  /// <summary>
  /// Make the current worksheet active.
  /// </summary>
  public void Select() {
    View.TabSelected = true;
    //Select(Address, true);
  }

  /// <summary>
  /// Selects a range in the worksheet. The active cell is the topmost cell.
  /// Make the current worksheet active.
  /// </summary>
  /// <param name="address">An address range</param>
  public void Select(string address) {
    Select(address, true);
  }

  /// <summary>
  /// Selects a range in the worksheet. The actice cell is the topmost cell.
  /// </summary>
  /// <param name="address">A range of cells</param>
  /// <param name="selectSheet">Make the sheet active</param>
  public void Select(string address, bool selectSheet) {
    CheckSheetType();
    int fromCol,
        fromRow,
        toCol,
        toRow;
    //Get rows and columns and validate as well
    ExcelCellBase.GetRowColFromAddress(address, out fromRow, out fromCol, out toRow, out toCol);

    if (selectSheet) {
      View.TabSelected = true;
    }
    View.SelectedRange = address;
    View.ActiveCell = ExcelCellBase.GetAddress(fromRow, fromCol);
  }

  /// <summary>
  /// Selects a range in the worksheet. The active cell is the topmost cell of the first address.
  /// Make the current worksheet active.
  /// </summary>
  /// <param name="address">An address range</param>
  public void Select(ExcelAddress address) {
    CheckSheetType();
    Select(address, true);
  }

  /// <summary>
  /// Selects a range in the worksheet. The active cell is the topmost cell of the first address.
  /// </summary>
  /// <param name="address">A range of cells</param>
  /// <param name="selectSheet">Make the sheet active</param>
  public void Select(ExcelAddress address, bool selectSheet) {
    CheckSheetType();
    if (selectSheet) {
      View.TabSelected = true;
    }
    string selAddress =
        ExcelCellBase.GetAddress(address.Start.Row, address.Start.Column)
            + ":"
            + ExcelCellBase.GetAddress(address.End.Row, address.End.Column);
    if (address.Addresses != null) {
      foreach (var a in address.Addresses) {
        selAddress +=
            " "
                + ExcelCellBase.GetAddress(a.Start.Row, a.Start.Column)
                + ":"
                + ExcelCellBase.GetAddress(a.End.Row, a.End.Column);
      }
    }
    View.SelectedRange = selAddress;
    View.ActiveCell = ExcelCellBase.GetAddress(address.Start.Row, address.Start.Column);
  }

  /// <summary>
  /// Inserts a new row into the spreadsheet.  Existing rows below the position are
  /// shifted down.  All formula are updated to take account of the new row.
  /// </summary>
  /// <param name="rowFrom">The position of the new row</param>
  /// <param name="rows">Number of rows to insert</param>
  public void InsertRow(int rowFrom, int rows) {
    InsertRow(rowFrom, rows, 0);
  }

  /// <summary>
  /// Inserts a new row into the spreadsheet.  Existing rows below the position are
  /// shifted down.  All formula are updated to take account of the new row.
  /// </summary>
  /// <param name="rowFrom">The position of the new row</param>
  /// <param name="rows">Number of rows to insert.</param>
  /// <param name="copyStylesFromRow">Copy Styles from this row. Applied to all inserted rows</param>
  public void InsertRow(int rowFrom, int rows, int copyStylesFromRow) {
    CheckSheetType();
    var d = Dimension;

    if (rowFrom < 1) {
      throw (new ArgumentOutOfRangeException("rowFrom can't be lesser that 1"));
    }

    //Check that cells aren't shifted outside the boundries
    if (d != null && d.End.Row > rowFrom && d.End.Row + rows > ExcelPackage.MaxRows) {
      throw (new ArgumentOutOfRangeException(
              "Can't insert. Rows will be shifted outside the boundries of the worksheet."));
    }

    lock (this) {
      _values.Insert(rowFrom, 0, rows, 0);
      _formulas.Insert(rowFrom, 0, rows, 0);
      _styles.Insert(rowFrom, 0, rows, 0);
      _types.Insert(rowFrom, 0, rows, 0);
      _commentsStore.Insert(rowFrom, 0, rows, 0);
      _hyperLinks.Insert(rowFrom, 0, rows, 0);
      _flags.Insert(rowFrom, 0, rows, 0);

      foreach (var f in _sharedFormulas.Values) {
        if (f.StartRow >= rowFrom) {
          f.StartRow += rows;
        }
        var a = new ExcelAddressBase(f.Address);
        if (a._fromRow >= rowFrom) {
          a._fromRow += rows;
          a._toRow += rows;
        } else if (a._toRow >= rowFrom) {
          a._toRow += rows;
        }
        f.Address = ExcelCellBase.GetAddress(a._fromRow, a._fromCol, a._toRow, a._toCol);
        f.Formula = ExcelCellBase.UpdateFormulaReferences(f.Formula, rows, 0, rowFrom, 0);
      }
      var cse = new CellsStoreEnumerator<object>(_formulas);
      while (cse.Next()) {
        if (cse.Value is string) {
          cse.Value = ExcelCellBase.UpdateFormulaReferences(
              cse.Value.ToString(),
              rows,
              0,
              rowFrom,
              0);
        }
      }

      FixMergedCellsRow(rowFrom, rows, false);
      if (copyStylesFromRow > 0) {
        var cseS = new CellsStoreEnumerator<int>(
            _styles,
            copyStylesFromRow,
            0,
            copyStylesFromRow,
            ExcelPackage.MaxColumns); //Fixes issue 15068 , 15090
        while (cseS.Next()) {
          for (var r = 0; r < rows; r++) {
            _styles.SetValue(rowFrom + r, cseS.Column, cseS.Value);
          }
        }
      }
      foreach (var tbl in Tables) {
        tbl.Address = tbl.Address.AddRow(rowFrom, rows);
      }
    }
  }

  /// <summary>
  /// Inserts a new column into the spreadsheet.  Existing columns below the position are
  /// shifted down.  All formula are updated to take account of the new column.
  /// </summary>
  /// <param name="columnFrom">The position of the new column</param>
  /// <param name="columns">Number of columns to insert</param>
  public void InsertColumn(int columnFrom, int columns) {
    InsertColumn(columnFrom, columns, 0);
  }

  ///<summary>
  /// Inserts a new column into the spreadsheet.  Existing column to the left are
  /// shifted.  All formula are updated to take account of the new column.
  /// </summary>
  /// <param name="columnFrom">The position of the new column</param>
  /// <param name="columns">Number of columns to insert.</param>
  /// <param name="copyStylesFromColumn">Copy Styles from this column. Applied to all inserted columns</param>
  public void InsertColumn(int columnFrom, int columns, int copyStylesFromColumn) {
    CheckSheetType();
    var d = Dimension;

    if (columnFrom < 1) {
      throw (new ArgumentOutOfRangeException("columnFrom can't be lesser that 1"));
    }
    //Check that cells aren't shifted outside the boundries
    if (d != null
        && d.End.Column > columnFrom
        && d.End.Column + columns > ExcelPackage.MaxColumns) {
      throw (new ArgumentOutOfRangeException(
              "Can't insert. Columns will be shifted outside the boundries of the worksheet."));
    }

    lock (this) {
      _values.Insert(0, columnFrom, 0, columns);
      _formulas.Insert(0, columnFrom, 0, columns);
      _styles.Insert(0, columnFrom, 0, columns);
      _types.Insert(0, columnFrom, 0, columns);
      _commentsStore.Insert(0, columnFrom, 0, columns);
      _hyperLinks.Insert(0, columnFrom, 0, columns);
      _flags.Insert(0, columnFrom, 0, columns);

      foreach (var f in _sharedFormulas.Values) {
        if (f.StartCol >= columnFrom) {
          f.StartCol += columns;
        }
        var a = new ExcelAddressBase(f.Address);
        if (a._fromCol >= columnFrom) {
          a._fromCol += columns;
          a._toCol += columns;
        } else if (a._toCol >= columnFrom) {
          a._toCol += columns;
        }
        f.Address = ExcelCellBase.GetAddress(a._fromRow, a._fromCol, a._toRow, a._toCol);
        f.Formula = ExcelCellBase.UpdateFormulaReferences(f.Formula, 0, columns, 0, columnFrom);
      }

      var cse = new CellsStoreEnumerator<object>(_formulas);
      while (cse.Next()) {
        if (cse.Value is string) {
          cse.Value = ExcelCellBase.UpdateFormulaReferences(
              cse.Value.ToString(),
              0,
              columns,
              0,
              columnFrom);
        }
      }

      FixMergedCellsColumn(columnFrom, columns, false);

      var csec = new CellsStoreEnumerator<object>(_values, 0, 1, 0, ExcelPackage.MaxColumns);
      var lst = new List<ExcelColumn>();
      foreach (var col in csec) {
        if (col is ExcelColumn) {
          lst.Add((ExcelColumn)col);
        }
      }

      for (int i = lst.Count - 1; i >= 0; i--) {
        var c = lst[i];
        if (c._columnMin >= columnFrom) {
          if (c._columnMin + columns <= ExcelPackage.MaxColumns) {
            c._columnMin += columns;
          } else {
            c._columnMin = ExcelPackage.MaxColumns;
          }

          if (c._columnMax + columns <= ExcelPackage.MaxColumns) {
            c._columnMax += columns;
          } else {
            c._columnMax = ExcelPackage.MaxColumns;
          }
        } else if (c._columnMax >= columnFrom) {
          var cc = c._columnMax - columnFrom;
          c._columnMax = columnFrom - 1;
          CopyColumn(c, columnFrom + columns, columnFrom + columns + cc);
        }
      }

      if (copyStylesFromColumn > 0) {
        for (var c = 0; c < columns; c++) {
          var col = Column(columnFrom + c);
          col.StyleID = Column(copyStylesFromColumn).StyleID;
        }
      }
      //Adjust tables
      foreach (var tbl in Tables) {
        if (columnFrom > tbl.Address.Start.Column && columnFrom <= tbl.Address.End.Column) {
          InsertTableColumns(columnFrom, columns, tbl);
        }

        tbl.Address = tbl.Address.AddColumn(columnFrom, columns);
      }
    }
  }

  private static void InsertTableColumns(int columnFrom, int columns, ExcelTable tbl) {
    var node = tbl.Columns[0].TopNode.ParentNode;
    var ix = columnFrom - tbl.Address.Start.Column - 1;
    var insPos = node.ChildNodes[ix];
    ix += 2;
    for (int i = 0; i < columns; i++) {
      var name = tbl.Columns.GetUniqueName(
          string.Format("Column{0}", (ix++).ToString(CultureInfo.InvariantCulture)));
      XmlElement tableColumn = (XmlElement)
        tbl.TableXml.CreateNode(XmlNodeType.Element, "tableColumn", ExcelPackage._schemaMain);
      tableColumn.SetAttribute(
          "id",
          (tbl.Columns.Count + i + 1).ToString(CultureInfo.InvariantCulture));
      tableColumn.SetAttribute("name", name);
      insPos = node.InsertAfter(tableColumn, insPos);
    } //Create tbl Column
    tbl._cols = new(tbl);
  }

  /// <summary>
  /// Adds a value to the row of merged cells to fix for inserts or deletes
  /// </summary>
  /// <param name="row"></param>
  /// <param name="rows"></param>
  /// <param name="delete"></param>
  private void FixMergedCellsRow(int row, int rows, bool delete) {
    if (delete) {
      _mergedCells._cells.Delete(row, 0, rows, 0);
    } else {
      _mergedCells._cells.Insert(row, 0, rows, 0);
    }

    List<int> removeIndex = new List<int>();
    for (int i = 0; i < _mergedCells.Count; i++) {
      if (!string.IsNullOrEmpty(_mergedCells[i])) {
        ExcelAddressBase addr = new(_mergedCells[i]),
            newAddr;
        if (delete) {
          newAddr = addr.DeleteRow(row, rows);
          if (newAddr == null) {
            removeIndex.Add(i);
            continue;
          }
        } else {
          newAddr = addr.AddRow(row, rows);
          if (newAddr.Address != addr.Address) {
            //    _mergedCells._cells.Insert(row, 0, rows, 0);
            _mergedCells.SetIndex(newAddr, i);
          }
        }

        if (newAddr.Address != addr.Address) {
          _mergedCells.List[i] = newAddr._address;
        }
      }
    }
    for (int i = removeIndex.Count - 1; i >= 0; i--) {
      _mergedCells.List.RemoveAt(removeIndex[i]);
    }
  }

  /// <summary>
  /// Adds a value to the row of merged cells to fix for inserts or deletes
  /// </summary>
  /// <param name="column"></param>
  /// <param name="columns"></param>
  /// <param name="delete"></param>
  private void FixMergedCellsColumn(int column, int columns, bool delete) {
    if (delete) {
      _mergedCells._cells.Delete(0, column, 0, columns);
    } else {
      _mergedCells._cells.Insert(0, column, 0, columns);
    }
    List<int> removeIndex = new List<int>();
    for (int i = 0; i < _mergedCells.Count; i++) {
      if (!string.IsNullOrEmpty(_mergedCells[i])) {
        ExcelAddressBase addr = new(_mergedCells[i]),
            newAddr;
        if (delete) {
          newAddr = addr.DeleteColumn(column, columns);
          if (newAddr == null) {
            removeIndex.Add(i);
            continue;
          }
        } else {
          newAddr = addr.AddColumn(column, columns);
          if (newAddr.Address != addr.Address) {
            _mergedCells.SetIndex(newAddr, i);
          }
        }

        if (newAddr.Address != addr.Address) {
          _mergedCells.List[i] = newAddr._address;
        }
      }
    }
    for (int i = removeIndex.Count - 1; i >= 0; i--) {
      _mergedCells.List.RemoveAt(removeIndex[i]);
    }
  }

  private void FixSharedFormulasRows(int position, int rows) {
    List<Formulas> added = new List<Formulas>();
    List<Formulas> deleted = new List<Formulas>();

    foreach (int id in _sharedFormulas.Keys) {
      var f = _sharedFormulas[id];
      int fromCol,
          fromRow,
          toCol,
          toRow;

      ExcelCellBase.GetRowColFromAddress(f.Address, out fromRow, out fromCol, out toRow, out toCol);
      if (position >= fromRow
          && position + (Math.Abs(rows))
              <= toRow) //Insert/delete is whithin the share formula address
      {
        if (rows
            > 0) //Insert
        {
          f.Address =
              ExcelCellBase.GetAddress(fromRow, fromCol)
                  + ":"
                  + ExcelCellBase.GetAddress(position - 1, toCol);
          if (toRow != fromRow) {
            Formulas newF = new Formulas(SourceCodeTokenizer.Default);
            newF.StartCol = f.StartCol;
            newF.StartRow = position + rows;
            newF.Address =
                ExcelCellBase.GetAddress(position + rows, fromCol)
                    + ":"
                    + ExcelCellBase.GetAddress(toRow + rows, toCol);
            newF.Formula = ExcelCellBase.TranslateFromR1C1(
                ExcelCellBase.TranslateToR1C1(f.Formula, f.StartRow, f.StartCol),
                position,
                f.StartCol);
            added.Add(newF);
          }
        } else {
          if (fromRow - rows < toRow) {
            f.Address = ExcelCellBase.GetAddress(fromRow, fromCol, toRow + rows, toCol);
          } else {
            f.Address =
                ExcelCellBase.GetAddress(fromRow, fromCol)
                    + ":"
                    + ExcelCellBase.GetAddress(toRow + rows, toCol);
          }
        }
      } else if (position <= toRow) {
        if (rows
            > 0) //Insert before shift down
        {
          f.StartRow += rows;
          //f.Formula = ExcelCell.UpdateFormulaReferences(f.Formula, rows, 0, position, 0); //Recalc the cells positions
          f.Address =
              ExcelCellBase.GetAddress(fromRow + rows, fromCol)
                  + ":"
                  + ExcelCellBase.GetAddress(toRow + rows, toCol);
        } else {
          //Cells[f.Address].SetSharedFormulaID(int.MinValue);
          if (position <= fromRow
              && position + Math.Abs(rows)
                  > toRow) //Delete the formula
          {
            deleted.Add(f);
          } else {
            toRow = toRow + rows < position - 1 ? position - 1 : toRow + rows;
            if (position <= fromRow) {
              fromRow = fromRow + rows < position ? position : fromRow + rows;
            }

            f.Address = ExcelCellBase.GetAddress(fromRow, fromCol, toRow, toCol);
            Cells[f.Address].SetSharedFormulaId(f.Index);
            //f.StartRow = fromRow;

            //f.Formula = ExcelCell.UpdateFormulaReferences(f.Formula, rows, 0, position, 0);
          }
        }
      }
    }

    AddFormulas(added, position, rows);

    //Remove formulas
    foreach (Formulas f in deleted) {
      _sharedFormulas.Remove(f.Index);
    }

    //Fix Formulas
    added = new();
    foreach (int id in _sharedFormulas.Keys) {
      var f = _sharedFormulas[id];
      UpdateSharedFormulaRow(ref f, position, rows, ref added);
    }
    AddFormulas(added, position, rows);
  }

  private void AddFormulas(List<Formulas> added, int position, int rows) {
    //Add new formulas
    foreach (Formulas f in added) {
      f.Index = GetMaxShareFunctionIndex(false);
      _sharedFormulas.Add(f.Index, f);
      Cells[f.Address].SetSharedFormulaId(f.Index);
    }
  }

  private void UpdateSharedFormulaRow(
      ref Formulas formula,
      int startRow,
      int rows,
      ref List<Formulas> newFormulas) {
    int fromRow,
        fromCol,
        toRow,
        toCol;
    int newFormulasCount = newFormulas.Count;
    ExcelCellBase.GetRowColFromAddress(
        formula.Address,
        out fromRow,
        out fromCol,
        out toRow,
        out toCol);
    //int refSplits = Regex.Split(formula.Formula, "#REF!").GetUpperBound(0);
    string formualR1C1;
    if (rows > 0 || fromRow <= startRow) {
      formualR1C1 = ExcelCellBase.TranslateToR1C1(
          formula.Formula,
          formula.StartRow,
          formula.StartCol);
      formula.Formula = ExcelCellBase.TranslateFromR1C1(formualR1C1, fromRow, formula.StartCol);
    } else {
      formualR1C1 = ExcelCellBase.TranslateToR1C1(
          formula.Formula,
          formula.StartRow - rows,
          formula.StartCol);
      formula.Formula = ExcelCellBase.TranslateFromR1C1(
          formualR1C1,
          formula.StartRow,
          formula.StartCol);
    }
    //bool isRef = false;
    //Formulas restFormula=formula;
    string prevFormualR1C1 = formualR1C1;
    for (int row = fromRow; row <= toRow; row++) {
      for (int col = fromCol; col <= toCol; col++) {
        string newFormula;
        string currentFormulaR1C1;
        if (rows > 0 || row < startRow) {
          newFormula = ExcelCellBase.UpdateFormulaReferences(
              ExcelCellBase.TranslateFromR1C1(formualR1C1, row, col),
              rows,
              0,
              startRow,
              0);
          currentFormulaR1C1 = ExcelCellBase.TranslateToR1C1(newFormula, row, col);
        } else {
          newFormula = ExcelCellBase.UpdateFormulaReferences(
              ExcelCellBase.TranslateFromR1C1(formualR1C1, row - rows, col),
              rows,
              0,
              startRow,
              0);
          currentFormulaR1C1 = ExcelCellBase.TranslateToR1C1(newFormula, row, col);
        }
        if (currentFormulaR1C1
            != prevFormualR1C1) //newFormula.Contains("#REF!"))
        {
          //if (refSplits == 0 || Regex.Split(newFormula, "#REF!").GetUpperBound(0) != refSplits)
          //{
          //isRef = true;
          if (row == fromRow && col == fromCol) {
            formula.Formula = newFormula;
          } else {
            if (newFormulas.Count == newFormulasCount) {
              formula.Address = ExcelCellBase.GetAddress(
                  formula.StartRow,
                  formula.StartCol,
                  row - 1,
                  col);
            } else {
              newFormulas[newFormulas.Count - 1].Address = ExcelCellBase.GetAddress(
                  newFormulas[newFormulas.Count - 1].StartRow,
                  newFormulas[newFormulas.Count - 1].StartCol,
                  row - 1,
                  col);
            }
            var refFormula = new Formulas(SourceCodeTokenizer.Default);
            refFormula.Formula = newFormula;
            refFormula.StartRow = row;
            refFormula.StartCol = col;
            newFormulas.Add(refFormula);

            //restFormula = null;
            prevFormualR1C1 = currentFormulaR1C1;
          }
        }
        //    }
        //    else
        //    {
        //        isRef = false;
        //    }
        //}
        //else
        //{
        //    isRef = false;
        //}
        //if (restFormula==null)
        //{
        //if (newFormulas.Count == newFormulasCount)
        //{
        //    formula.Address = ExcelCellBase.GetAddress(formula.StartRow, formula.StartCol, row - 1, col);
        //}
        //else
        //{
        //                            newFormulas[newFormulas.Count - 1].Address = ExcelCellBase.GetAddress(newFormulas[newFormulas.Count - 1].StartRow, newFormulas[0].StartCol, row - 1, col);
        //}

        //restFormula = new Formulas();
        //restFormula.Formula = newFormula;
        //restFormula.StartRow = row;
        //restFormula.StartCol = col;
        //newFormulas.Add(restFormula);
        //}
      }
    }
    if (rows < 0 && formula.StartRow > startRow) {
      if (formula.StartRow + rows < startRow) {
        formula.StartRow = startRow;
      } else {
        formula.StartRow += rows;
      }
    }
    if (newFormulas.Count > newFormulasCount) {
      newFormulas[newFormulas.Count - 1].Address = ExcelCellBase.GetAddress(
          newFormulas[newFormulas.Count - 1].StartRow,
          newFormulas[newFormulas.Count - 1].StartCol,
          toRow,
          toCol);
    }
  }

  /// <summary>
  /// Delete the specified row from the worksheet.
  /// </summary>
  /// <param name="row">A row to be deleted</param>
  public void DeleteRow(int row) {
    DeleteRow(row, 1);
  }

  /// <summary>
  /// Delete the specified row from the worksheet.
  /// </summary>
  /// <param name="rowFrom">The start row</param>
  /// <param name="rows">Number of rows to delete</param>
  public void DeleteRow(int rowFrom, int rows) {
    CheckSheetType();
    if (rowFrom < 1 || rowFrom + rows > ExcelPackage.MaxRows) {
      throw (new ArgumentException(
              "Row out of range. Spans from 1 to "
                  + ExcelPackage.MaxRows.ToString(CultureInfo.InvariantCulture)));
    }
    lock (this) {
      _values.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns);
      _types.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns);
      _formulas.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns);
      _styles.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns);
      _flags.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns);
      _commentsStore.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns);
      _hyperLinks.Delete(rowFrom, 0, rows, ExcelPackage.MaxColumns);

      AdjustFormulasRow(rowFrom, rows);
      FixMergedCellsRow(rowFrom, rows, true);

      foreach (var tbl in Tables) {
        tbl.Address = tbl.Address.DeleteRow(rowFrom, rows);
      }
    }
  }

  /// <summary>
  /// Delete the specified column from the worksheet.
  /// </summary>
  /// <param name="column">The column to be deleted</param>
  public void DeleteColumn(int column) {
    DeleteColumn(column, 1);
  }

  /// <summary>
  /// Delete the specified column from the worksheet.
  /// </summary>
  /// <param name="columnFrom">The start column</param>
  /// <param name="columns">Number of columns to delete</param>
  public void DeleteColumn(int columnFrom, int columns) {
    if (columnFrom < 1 || columnFrom + columns > ExcelPackage.MaxColumns) {
      throw (new ArgumentException(
              "Column out of range. Spans from 1 to "
                  + ExcelPackage.MaxColumns.ToString(CultureInfo.InvariantCulture)));
    }
    lock (this) {
      var col = _values.GetValue(0, columnFrom) as ExcelColumn;
      if (col == null) {
        var r = 0;
        var c = columnFrom;
        if (_values.PrevCell(ref r, ref c)) {
          col = _values.GetValue(0, c) as ExcelColumn;
          if (col._columnMax >= columnFrom) {
            col.ColumnMax = columnFrom - 1;
          }
        }
      }

      _values.Delete(0, columnFrom, ExcelPackage.MaxRows, columns);
      _types.Delete(0, columnFrom, ExcelPackage.MaxRows, columns);
      _formulas.Delete(0, columnFrom, ExcelPackage.MaxRows, columns);
      _styles.Delete(0, columnFrom, ExcelPackage.MaxRows, columns);
      _flags.Delete(0, columnFrom, ExcelPackage.MaxRows, columns);
      _commentsStore.Delete(0, columnFrom, ExcelPackage.MaxRows, columns);
      _hyperLinks.Delete(0, columnFrom, ExcelPackage.MaxRows, columns);

      AdjustFormulasColumn(columnFrom, columns);
      FixMergedCellsColumn(columnFrom, columns, true);

      var csec = new CellsStoreEnumerator<object>(
          _values,
          0,
          columnFrom,
          0,
          ExcelPackage.MaxColumns);
      foreach (var column in csec) {
        if (column is ExcelColumn) {
          var c = (ExcelColumn)column;
          if (c._columnMin >= columnFrom) {
            c._columnMin -= columns;
            c._columnMax -= columns;
          }
        }
      }

      foreach (var tbl in Tables) {
        if (columnFrom >= tbl.Address.Start.Column && columnFrom <= tbl.Address.End.Column) {
          var node = tbl.Columns[0].TopNode.ParentNode;
          var ix = columnFrom - tbl.Address.Start.Column;
          for (int i = 0; i < columns; i++) {
            if (node.ChildNodes.Count > ix) {
              node.RemoveChild(node.ChildNodes[ix]);
            }
          }
          tbl._cols = new(tbl);
        }

        tbl.Address = tbl.Address.DeleteColumn(columnFrom, columns);
      }
    }
  }

  internal void AdjustFormulasRow(int rowFrom, int rows) {
    var delSf = new List<int>();
    foreach (var sf in _sharedFormulas.Values) {
      var a = new ExcelAddress(sf.Address).DeleteRow(rowFrom, rows);
      if (a == null) {
        delSf.Add(sf.Index);
      } else {
        sf.Address = a.Address;
        if (sf.StartRow > rowFrom) {
          var r = Math.Min(sf.StartRow - rowFrom, rows);
          sf.Formula = ExcelCellBase.UpdateFormulaReferences(sf.Formula, -r, 0, rowFrom, 0);
          sf.StartRow -= r;
        }
      }
    }
    foreach (var ix in delSf) {
      _sharedFormulas.Remove(ix);
    }
    delSf = null;
    var cse = new CellsStoreEnumerator<object>(
        _formulas,
        1,
        1,
        ExcelPackage.MaxRows,
        ExcelPackage.MaxColumns);
    while (cse.Next()) {
      if (cse.Value is string) {
        cse.Value = ExcelCellBase.UpdateFormulaReferences(
            cse.Value.ToString(),
            -rows,
            0,
            rowFrom,
            0);
      }
    }
  }

  internal void AdjustFormulasColumn(int columnFrom, int columns) {
    var delSf = new List<int>();
    foreach (var sf in _sharedFormulas.Values) {
      var a = new ExcelAddress(sf.Address).DeleteColumn(columnFrom, columns);
      if (a == null) {
        delSf.Add(sf.Index);
      } else {
        sf.Address = a.Address;
        //sf.Formula = ExcelCellBase.UpdateFormulaReferences(sf.Formula, 0, -columns, 0, columnFrom);
        if (sf.StartCol > columnFrom) {
          var c = Math.Min(sf.StartCol - columnFrom, columns);
          sf.Formula = ExcelCellBase.UpdateFormulaReferences(sf.Formula, 0, -c, 0, 1);
          sf.StartCol -= c;
        }

        //sf.Address = a.Address;
        //sf.Formula = ExcelCellBase.UpdateFormulaReferences(sf.Formula, 0,-columns,0, columnFrom);
        //if (sf.StartCol >= columnFrom)
        //{
        //    sf.StartCol -= sf.StartCol;
        //}
      }
    }
    foreach (var ix in delSf) {
      _sharedFormulas.Remove(ix);
    }
    delSf = null;
    var cse = new CellsStoreEnumerator<object>(
        _formulas,
        1,
        1,
        ExcelPackage.MaxRows,
        ExcelPackage.MaxColumns);
    while (cse.Next()) {
      if (cse.Value is string) {
        cse.Value = ExcelCellBase.UpdateFormulaReferences(
            cse.Value.ToString(),
            0,
            -columns,
            0,
            columnFrom);
      }
    }
  }

  /// <summary>
  /// Deletes the specified row from the worksheet.
  /// </summary>
  /// <param name="rowFrom">The number of the start row to be deleted</param>
  /// <param name="rows">Number of rows to delete</param>
  /// <param name="shiftOtherRowsUp">Not used. Rows are always shifted</param>
  public void DeleteRow(int rowFrom, int rows, bool shiftOtherRowsUp) {
    DeleteRow(rowFrom, rows);
  }

  /// <summary>
  /// Get the cell value from thw worksheet
  /// </summary>
  /// <param name="row">The row number</param>
  /// <param name="column">The row number</param>
  /// <returns>The value</returns>
  public object GetValue(int row, int column) {
    CheckSheetType();
    //ulong cellID = ExcelCellBase.GetCellID(SheetID, Row, Column);
    var v = _values.GetValue(row, column);
    if (v != null) {
      //var cell = ((ExcelCell)_cells[cellID]);
      if (_flags.GetFlagValue(row, column, CellFlags.RichText)) {
        return Cells[row, column].RichText.Text;
      }
      return v;
    }
    return null;
  }

  /// <summary>
  /// Get a strongly typed cell value from the worksheet
  /// </summary>
  /// <typeparam name="T">The type</typeparam>
  /// <param name="row">The row number</param>
  /// <param name="column">The row number</param>
  /// <returns>The value. If the value can't be converted to the specified type, the default value will be returned</returns>
  public T GetValue<T>(int row, int column) {
    CheckSheetType();
    //ulong cellID=ExcelCellBase.GetCellID(SheetID, Row, Column);
    var v = _values.GetValue(row, column);
    if (v == null) {
      return default(T);
    }

    //var cell=((ExcelCell)_cells[cellID]);
    if (_flags.GetFlagValue(row, column, CellFlags.RichText)) {
      return (T)(object)Cells[row, column].RichText.Text;
    }
    return GetTypedValue<T>(v);
  }

  //Thanks to Michael Tran for parts of this method
  internal T GetTypedValue<T>(object v) {
    if (v == null) {
      return default(T);
    }
    Type fromType = v.GetType();
    Type toType = typeof(T);
    if (fromType == toType) {
      return (T)v;
    }
    var cnv = TypeDescriptor.GetConverter(fromType);
    if (toType
        == typeof(DateTime)) //Handle dates
    {
      if (fromType == typeof(TimeSpan)) {
        return ((T)(object)(new DateTime(((TimeSpan)v).Ticks)));
      }
      if (fromType == typeof(string)) {
        DateTime dt;
        if (DateTime.TryParse(v.ToString(), out dt)) {
          return (T)(object)(dt);
        }
        return default(T);
      }
      if (cnv.CanConvertTo(typeof(double))) {
        return (T)(object)(DateTime.FromOADate((double)cnv.ConvertTo(v, typeof(double))));
      }
      return default(T);
    }
    if (toType
        == typeof(TimeSpan)) //Handle timespan
    {
      if (fromType == typeof(DateTime)) {
        return ((T)(object)(new TimeSpan(((DateTime)v).Ticks)));
      }
      if (fromType == typeof(string)) {
        TimeSpan ts;
        if (TimeSpan.TryParse(v.ToString(), out ts)) {
          return (T)(object)(ts);
        }
        return default(T);
      }
      if (cnv.CanConvertTo(typeof(double))) {
        return (T)
          (object)(new TimeSpan(
              DateTime.FromOADate((double)cnv.ConvertTo(v, typeof(double))).Ticks));
      }
      try {
        // Issue 14682 -- "GetValue<decimal>() won't convert strings"
        // As suggested, after all special cases, all .NET to do it's
        // preferred conversion rather than simply returning the default
        return (T)Convert.ChangeType(v, typeof(T));
      } catch (Exception) {
        // This was the previous behaviour -- no conversion is available.
        return default(T);
      }
    }
    if (cnv.CanConvertTo(toType)) {
      return (T)cnv.ConvertTo(v, typeof(T));
    }
    if (toType.IsGenericType && toType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) {
      toType = Nullable.GetUnderlyingType(toType);
      if (cnv.CanConvertTo(toType)) {
        return (T)cnv.ConvertTo(v, typeof(T));
      }
    }

    if (fromType == typeof(double) && toType == typeof(decimal)) {
      return (T)(object)Convert.ToDecimal(v);
    }
    if (fromType == typeof(decimal) && toType == typeof(double)) {
      return (T)(object)Convert.ToDouble(v);
    }
    return default(T);
  }

  /// <summary>
  /// Set the value of a cell
  /// </summary>
  /// <param name="row">The row number</param>
  /// <param name="column">The column number</param>
  /// <param name="value">The value</param>
  public void SetValue(int row, int column, object value) {
    CheckSheetType();
    if (row < 1 || column < 1 || row > ExcelPackage.MaxRows && column > ExcelPackage.MaxColumns) {
      throw new ArgumentOutOfRangeException("Row or Column out of range");
    }
    _values.SetValue(row, column, value);
  }

  /// <summary>
  /// Set the value of a cell
  /// </summary>
  /// <param name="address">The Excel address</param>
  /// <param name="value">The value</param>
  public void SetValue(string address, object value) {
    CheckSheetType();
    int row,
        col;
    ExcelCellBase.GetRowCol(address, out row, out col, true);
    if (row < 1 || col < 1 || row > ExcelPackage.MaxRows && col > ExcelPackage.MaxColumns) {
      throw new ArgumentOutOfRangeException("Address is invalid or out of range");
    }
    _values.SetValue(row, col, value);
  }

  /// <summary>
  /// Get MergeCell Index No
  /// </summary>
  /// <param name="row"></param>
  /// <param name="column"></param>
  /// <returns></returns>
  public int GetMergeCellId(int row, int column) {
    for (int i = 0; i < _mergedCells.Count; i++) {
      if (!string.IsNullOrEmpty(_mergedCells[i])) {
        ExcelRange range = Cells[_mergedCells[i]];

        if (range.Start.Row <= row && row <= range.End.Row) {
          if (range.Start.Column <= column && column <= range.End.Column) {
            return i + 1;
          }
        }
      }
    }
    return 0;
  }

  internal void Save() {
    DeletePrinterSettings();

    if (_worksheetXml != null) {
      if (!(this is ExcelChartsheet)) {
        // save the header & footer (if defined)
        if (_headerFooter != null) {
          HeaderFooter.Save();
        }

        var d = Dimension;
        if (d == null) {
          DeleteAllNode("d:dimension/@ref");
        } else {
          SetXmlNodeString("d:dimension/@ref", d.Address);
        }

        SaveComments();
        SaveTables();
        SavePivotTables();
      }
    }
  }

  internal void SaveHandler(StreamWriter streamWriter) {
    //Create the nodes if they do not exist.
    if (this is ExcelChartsheet) {
      streamWriter.Write(_worksheetXml.OuterXml);
    } else {
      CreateNode("d:cols");
      CreateNode("d:sheetData");
      CreateNode("d:mergeCells");
      CreateNode("d:hyperlinks");
      CreateNode("d:rowBreaks");
      CreateNode("d:colBreaks");

      //StreamWriter sw=new StreamWriter(Part.GetStream(FileMode.Create, FileAccess.Write));
      var xml = _worksheetXml.OuterXml;
      int colStart = 0,
          colEnd = 0;
      GetBlockPos(xml, "cols", ref colStart, ref colEnd);

      streamWriter.Write(xml.Substring(0, colStart));
      var colBreaks = new List<int>();
      //if (_columns.Count > 0)
      //{
      UpdateColumnData(streamWriter);
      //}

      int cellStart = colEnd,
          cellEnd = colEnd;
      GetBlockPos(xml, "sheetData", ref cellStart, ref cellEnd);

      streamWriter.Write(xml.Substring(colEnd, cellStart - colEnd));
      var rowBreaks = new List<int>();
      UpdateRowCellData(streamWriter);

      int mergeStart = cellEnd,
          mergeEnd = cellEnd;

      GetBlockPos(xml, "mergeCells", ref mergeStart, ref mergeEnd);
      streamWriter.Write(xml.Substring(cellEnd, mergeStart - cellEnd));

      CleanupMergedCells(_mergedCells);
      if (_mergedCells.Count > 0) {
        UpdateMergedCells(streamWriter);
      }

      int hyperStart = mergeEnd,
          hyperEnd = mergeEnd;
      GetBlockPos(xml, "hyperlinks", ref hyperStart, ref hyperEnd);
      streamWriter.Write(xml.Substring(mergeEnd, hyperStart - mergeEnd));
      //if (_hyperLinkCells.Count > 0)
      //{
      UpdateHyperLinks(streamWriter);
      // }

      int rowBreakStart = hyperEnd,
          rowBreakEnd = hyperEnd;
      GetBlockPos(xml, "rowBreaks", ref rowBreakStart, ref rowBreakEnd);
      streamWriter.Write(xml.Substring(hyperEnd, rowBreakStart - hyperEnd));
      //if (rowBreaks.Count > 0)
      //{
      UpdateRowBreaks(streamWriter);
      //}

      int colBreakStart = rowBreakEnd,
          colBreakEnd = rowBreakEnd;
      GetBlockPos(xml, "colBreaks", ref colBreakStart, ref colBreakEnd);
      streamWriter.Write(xml.Substring(rowBreakEnd, colBreakStart - rowBreakEnd));
      //if (colBreaks.Count > 0)
      //{
      UpdateColBreaks(streamWriter);
      //}
      streamWriter.Write(xml.Substring(colBreakEnd, xml.Length - colBreakEnd));
    }
  }

  /// <summary>
  /// Delete the printersettings relationship and part.
  /// </summary>
  private void DeletePrinterSettings() {
    //Delete the relationship from the pageSetup tag
    XmlAttribute attr = (XmlAttribute)
      WorksheetXml.SelectSingleNode("//d:pageSetup/@r:id", NameSpaceManager);
    if (attr != null) {
      string relId = attr.Value;
      //First delete the attribute from the XML
      attr.OwnerElement.Attributes.Remove(attr);
      if (Part.RelationshipExists(relId)) {
        var rel = Part.GetRelationship(relId);
        Uri printerSettingsUri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
        Part.DeleteRelationship(rel.Id);

        //Delete the part from the package
        if (_package.Package.PartExists(printerSettingsUri)) {
          _package.Package.DeletePart(printerSettingsUri);
        }
      }
    }
  }

  private void SaveComments() {
    if (_comments != null) {
      if (_comments.Count == 0) {
        if (_comments.Uri != null) {
          Part.DeleteRelationship(_comments.RelId);
          _package.Package.DeletePart(_comments.Uri);
        }
        RemoveLegacyDrawingRel(VmlDrawingsComments.RelId);
      } else {
        if (_comments.Uri == null) {
          _comments.Uri = new(string.Format("/xl/comments{0}.xml", SheetID), UriKind.Relative);
        }
        if (_comments.Part == null) {
          _comments.Part = _package.Package.CreatePart(
              _comments.Uri,
              "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
              _package.Compression);
          var rel = Part.CreateRelationship(
              UriHelper.GetRelativeUri(WorksheetUri, _comments.Uri),
              TargetMode.Internal,
              ExcelPackage._schemaRelationships + "/comments");
        }
        _comments.CommentXml.Save(_comments.Part.GetStream(FileMode.Create));
      }
    }

    if (_vmlDrawings != null) {
      if (_vmlDrawings.Count == 0) {
        if (_vmlDrawings.Uri != null) {
          Part.DeleteRelationship(_vmlDrawings.RelId);
          _package.Package.DeletePart(_vmlDrawings.Uri);
        }
      } else {
        if (_vmlDrawings.Uri == null) {
          _vmlDrawings.Uri = GetNewUri(_package.Package, "/xl/drawings/vmlDrawing{0}.vml");
        }
        if (_vmlDrawings.Part == null) {
          _vmlDrawings.Part = _package.Package.CreatePart(
              _vmlDrawings.Uri,
              "application/vnd.openxmlformats-officedocument.vmlDrawing",
              _package.Compression);
          var rel = Part.CreateRelationship(
              UriHelper.GetRelativeUri(WorksheetUri, _vmlDrawings.Uri),
              TargetMode.Internal,
              ExcelPackage._schemaRelationships + "/vmlDrawing");
          SetXmlNodeString("d:legacyDrawing/@r:id", rel.Id);
          _vmlDrawings.RelId = rel.Id;
        }
        _vmlDrawings.VmlDrawingXml.Save(_vmlDrawings.Part.GetStream());
      }
    }
  }

  /// <summary>
  /// Save all table data
  /// </summary>
  private void SaveTables() {
    foreach (var tbl in Tables) {
      if (tbl.ShowHeader || tbl.ShowTotal) {
        int colNum = tbl.Address._fromCol;
        var colVal = new HashSet<string>();
        foreach (var col in tbl.Columns) {
          string n = col.Name.ToLower(CultureInfo.InvariantCulture);
          if (tbl.ShowHeader) {
            n = tbl.WorkSheet.GetValue<string>(
                tbl.Address._fromRow,
                tbl.Address._fromCol + col.Position);
            if (string.IsNullOrEmpty(n)) {
              n = col.Name.ToLower(CultureInfo.InvariantCulture);
            } else {
              col.Name = n;
            }
          } else {
            n = col.Name.ToLower(CultureInfo.InvariantCulture);
          }

          if (colVal.Contains(n)) {
            throw (new InvalidDataException(
                    string.Format(
                        "Table {0} Column {1} does not have a unique name.",
                        tbl.Name,
                        col.Name)));
          }
          colVal.Add(n);
          col.Name = ConvertUtil.ExcelEncodeString(col.Name);
          if (tbl.ShowHeader) {
            _values.SetValue(tbl.Address._fromRow, colNum, col.Name);
          }
          if (tbl.ShowTotal) {
            SetTableTotalFunction(tbl, col, colNum);
          }
          if (!string.IsNullOrEmpty(col.CalculatedColumnFormula)) {
            int fromRow = tbl.ShowHeader ? tbl.Address._fromRow + 1 : tbl.Address._fromRow;
            int toRow = tbl.ShowTotal ? tbl.Address._toRow - 1 : tbl.Address._toRow;
            for (int row = fromRow; row <= toRow; row++) {
              //Cell(row, colNum).Formula = col.CalculatedColumnFormula;
              SetFormula(row, colNum, col.CalculatedColumnFormula);
            }
          }
          colNum++;
        }
      }
      if (tbl.Part == null) {
        tbl.TableUri = GetNewUri(_package.Package, "/xl/tables/table{0}.xml", tbl.Id);
        tbl.Part = _package.Package.CreatePart(
            tbl.TableUri,
            "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
            Workbook._package.Compression);
        var stream = tbl.Part.GetStream(FileMode.Create);
        tbl.TableXml.Save(stream);
        var rel = Part.CreateRelationship(
            UriHelper.GetRelativeUri(WorksheetUri, tbl.TableUri),
            TargetMode.Internal,
            ExcelPackage._schemaRelationships + "/table");
        tbl.RelationshipID = rel.Id;

        CreateNode("d:tableParts");
        XmlNode tbls = TopNode.SelectSingleNode("d:tableParts", NameSpaceManager);

        var tblNode = tbls.OwnerDocument.CreateElement("tablePart", ExcelPackage._schemaMain);
        tbls.AppendChild(tblNode);
        tblNode.SetAttribute("id", ExcelPackage._schemaRelationships, rel.Id);
      } else {
        var stream = tbl.Part.GetStream(FileMode.Create);
        tbl.TableXml.Save(stream);
      }
    }
  }

  internal void SetTableTotalFunction(ExcelTable tbl, ExcelTableColumn col, int colNum = -1) {
    if (tbl.ShowTotal == false) {
      return;
    }
    if (colNum == -1) {
      for (int i = 0; i < tbl.Columns.Count; i++) {
        if (tbl.Columns[i].Name == col.Name) {
          colNum = tbl.Address._fromCol + i;
        }
      }
    }
    if (col.TotalsRowFunction == RowFunctions.Custom) {
      SetFormula(tbl.Address._toRow, colNum, col.TotalsRowFormula);
    } else if (col.TotalsRowFunction != RowFunctions.None) {
      switch (col.TotalsRowFunction) {
        case RowFunctions.Average:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "101"));
          break;
        case RowFunctions.Count:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "102"));
          break;
        case RowFunctions.CountNums:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "103"));
          break;
        case RowFunctions.Max:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "104"));
          break;
        case RowFunctions.Min:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "105"));
          break;
        case RowFunctions.StdDev:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "107"));
          break;
        case RowFunctions.Var:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "110"));
          break;
        case RowFunctions.Sum:
          SetFormula(tbl.Address._toRow, colNum, GetTotalFunction(col, "109"));
          break;
        default:
          throw (new("Unknown RowFunction enum"));
      }
    } else {
      _values.SetValue(tbl.Address._toRow, colNum, col.TotalsRowLabel);
    }
  }

  internal void SetFormula(int row, int col, object value) {
    _formulas.SetValue(row, col, value);
    if (!_values.Exists(row, col)) {
      _values.SetValue(row, col, null);
    }
  }

  internal void SetStyle(int row, int col, int value) {
    _styles.SetValue(row, col, value);
    if (!_values.Exists(row, col)) {
      _values.SetValue(row, col, null);
    }
  }

  private void SavePivotTables() {
    foreach (var pt in PivotTables) {
      if (pt.DataFields.Count > 1) {
        XmlElement parentNode;
        if (pt.DataOnRows) {
          parentNode =
              pt.PivotTableXml.SelectSingleNode("//d:rowFields", pt.NameSpaceManager) as XmlElement;
          if (parentNode == null) {
            pt.CreateNode("d:rowFields");
            parentNode =
                pt.PivotTableXml.SelectSingleNode("//d:rowFields", pt.NameSpaceManager)
                    as XmlElement;
          }
        } else {
          parentNode =
              pt.PivotTableXml.SelectSingleNode("//d:colFields", pt.NameSpaceManager) as XmlElement;
          if (parentNode == null) {
            pt.CreateNode("d:colFields");
            parentNode =
                pt.PivotTableXml.SelectSingleNode("//d:colFields", pt.NameSpaceManager)
                    as XmlElement;
          }
        }

        if (parentNode.SelectSingleNode("d:field[@ x= \"-2\"]", pt.NameSpaceManager) == null) {
          XmlElement fieldNode = pt.PivotTableXml.CreateElement("field", ExcelPackage._schemaMain);
          fieldNode.SetAttribute("x", "-2");
          parentNode.AppendChild(fieldNode);
        }
      }
      var ws = Workbook.Worksheets[pt.CacheDefinition.SourceRange.WorkSheet];
      var t = ws.Tables.GetFromRange(pt.CacheDefinition.SourceRange);
      var fields = pt.CacheDefinition.CacheDefinitionXml.SelectNodes(
          "d:pivotCacheDefinition/d:cacheFields/d:cacheField",
          NameSpaceManager);
      int ix = 0;
      if (fields != null) {
        var flds = new HashSet<string>();
        foreach (XmlElement node in fields) {
          if (ix >= pt.CacheDefinition.SourceRange.Columns) {
            break;
          }
          var fldName = node.GetAttribute("name"); //Fixes issue 15295 dup name error
          if (string.IsNullOrEmpty(fldName)) {
            fldName =
                (t == null
                    ? pt.CacheDefinition.SourceRange.Offset(0, ix++, 1, 1).Value.ToString()
                    : t.Columns[ix++].Name);
          }
          if (flds.Contains(fldName)) {
            fldName = GetNewName(flds, fldName);
          }
          flds.Add(fldName);
          node.SetAttribute("name", fldName);
        }
        foreach (var df in pt.DataFields) {
          if (string.IsNullOrEmpty(df.Name)) {
            string name;
            if (df.Function == DataFieldFunctions.None) {
              name = df.Field.Name; //Name must be set or Excel will crash on rename.
            } else {
              name = df.Function + " of " + df.Field.Name; //Name must be set or Excel will crash on rename.
            }
            //Make sure name is unique
            var newName = name;
            var i = 2;
            while (pt.DataFields.ExistsDfName(newName, df)) {
              newName = name + (i++).ToString(CultureInfo.InvariantCulture);
            }
            df.Name = newName;
          }
        }
      }
      pt.PivotTableXml.Save(pt.Part.GetStream(FileMode.Create));
      pt.CacheDefinition.CacheDefinitionXml.Save(
          pt.CacheDefinition.Part.GetStream(FileMode.Create));
    }
  }

  private string GetNewName(HashSet<string> flds, string fldName) {
    int ix = 2;
    while (flds.Contains(fldName + ix.ToString(CultureInfo.InvariantCulture))) {
      ix++;
    }
    return fldName + ix.ToString(CultureInfo.InvariantCulture);
  }

  private static string GetTotalFunction(ExcelTableColumn col, string functionNum) {
    return string.Format("SUBTOTAL({0},{1}[{2}])", functionNum, col._tbl.Name, col.Name);
  }

  private void CleanupMergedCells(MergeCellsCollection mergedCells) {
    int i = 0;
    while (i < mergedCells.List.Count) {
      if (mergedCells[i] == null) {
        mergedCells.List.RemoveAt(i);
      } else {
        i++;
      }
    }
  }

  private void UpdateColBreaks(StreamWriter sw) {
    StringBuilder breaks = new StringBuilder();
    int count = 0;
    var cse = new CellsStoreEnumerator<object>(_values, 0, 0, 0, ExcelPackage.MaxColumns);
    //foreach (ExcelColumn col in _columns)
    while (cse.Next()) {
      var col = cse.Value as ExcelColumn;
      if (col != null && col.PageBreak) {
        breaks.AppendFormat("<brk id=\"{0}\" max=\"16383\" man=\"1\" />", cse.Column);
        count++;
      }
    }
    if (count > 0) {
      sw.Write("<colBreaks count=\"{0}\" manualBreakCount=\"{0}\">{1}</colBreaks>", count, breaks);
    }
  }

  private void UpdateRowBreaks(StreamWriter sw) {
    StringBuilder breaks = new StringBuilder();
    int count = 0;
    var cse = new CellsStoreEnumerator<object>(_values, 0, 0, ExcelPackage.MaxRows, 0);
    //foreach(ExcelRow row in _rows)
    while (cse.Next()) {
      var row = cse.Value as RowInternal;
      if (row != null && row.PageBreak) {
        breaks.AppendFormat("<brk id=\"{0}\" max=\"1048575\" man=\"1\" />", cse.Row);
        count++;
      }
    }
    if (count > 0) {
      sw.Write("<rowBreaks count=\"{0}\" manualBreakCount=\"{0}\">{1}</rowBreaks>", count, breaks);
    }
  }

  /// <summary>
  /// Inserts the cols collection into the XML document
  /// </summary>
  private void UpdateColumnData(StreamWriter sw) {
    //ExcelColumn prevCol = null;   //commented out 11/1-12 JK
    //foreach (ExcelColumn col in _columns)
    //{
    //    if (prevCol != null)
    //    {
    //        if(prevCol.ColumnMax != col.ColumnMin-1)
    //        {
    //            prevCol._columnMax=col.ColumnMin-1;
    //        }
    //    }
    //    prevCol = col;
    //}
    var cse = new CellsStoreEnumerator<object>(_values, 0, 1, 0, ExcelPackage.MaxColumns);
    //sw.Write("<cols>");
    //foreach (ExcelColumn col in _columns)
    bool first = true;
    while (cse.Next()) {
      if (first) {
        sw.Write("<cols>");
        first = false;
      }
      var col = cse.Value as ExcelColumn;
      ExcelStyleCollection<ExcelXfs> cellXfs = _package.Workbook.Styles.CellXfs;

      sw.Write("<col min=\"{0}\" max=\"{1}\"", col.ColumnMin, col.ColumnMax);
      if (col.Hidden) {
        //sbXml.Append(" width=\"0\" hidden=\"1\" customWidth=\"1\"");
        sw.Write(" hidden=\"1\"");
      } else if (col.BestFit) {
        sw.Write(" bestFit=\"1\"");
      }
      sw.Write(
          string.Format(
              CultureInfo.InvariantCulture,
              " width=\"{0}\" customWidth=\"1\"",
              col.Width));
      if (col.OutlineLevel > 0) {
        sw.Write(" outlineLevel=\"{0}\" ", col.OutlineLevel);
        if (col.Collapsed) {
          if (col.Hidden) {
            sw.Write(" collapsed=\"1\"");
          } else {
            sw.Write(" collapsed=\"1\" hidden=\"1\""); //Always hidden
          }
        }
      }
      if (col.Phonetic) {
        sw.Write(" phonetic=\"1\"");
      }

      var styleId = col.StyleID >= 0 ? cellXfs[col.StyleID].newID : col.StyleID;
      if (styleId > 0) {
        sw.Write(" style=\"{0}\"", styleId);
      }
      sw.Write(" />");

      //if (col.PageBreak)
      //{
      //    colBreaks.Add(col.ColumnMin);
      //}
    }
    if (!first) {
      sw.Write("</cols>");
    }
  }

  /// <summary>
  /// Insert row and cells into the XML document
  /// </summary>
  private void UpdateRowCellData(StreamWriter sw) {
    ExcelStyleCollection<ExcelXfs> cellXfs = _package.Workbook.Styles.CellXfs;

    int row = -1;

    StringBuilder sbXml = new StringBuilder();
    var ss = _package.Workbook._sharedStrings;
    var styles = _package.Workbook.Styles;
    var cache = new StringBuilder();
    cache.Append("<sheetData>");

    //Set a value for cells with style and no value set.
    var cseStyle = new CellsStoreEnumerator<int>(
        _styles,
        0,
        0,
        ExcelPackage.MaxRows,
        ExcelPackage.MaxColumns);
    foreach (var s in cseStyle) {
      if (!_values.Exists(cseStyle.Row, cseStyle.Column)) {
        _values.SetValue(cseStyle.Row, cseStyle.Column, null);
      }
    }

    var cse = new CellsStoreEnumerator<object>(
        _values,
        1,
        0,
        ExcelPackage.MaxRows,
        ExcelPackage.MaxColumns);
    //foreach (IRangeID r in _cells)
    while (cse.Next()) {
      if (cse.Column > 0) {
        int styleId = cellXfs[styles.GetStyleId(this, cse.Row, cse.Column)].newID;
        //Add the row element if it's a new row
        if (cse.Row != row) {
          WriteRow(cache, cellXfs, row, cse.Row);
          row = cse.Row;
        }
        object v = cse.Value;
        object formula = _formulas.GetValue(cse.Row, cse.Column);
        if (formula is int) {
          int sfId = (int)formula;
          var f = _sharedFormulas[sfId];
          if (f.Address.IndexOf(':') > 0) {
            if (f.StartCol == cse.Column && f.StartRow == cse.Row) {
              if (f.IsArray) {
                cache.AppendFormat(
                    "<c r=\"{0}\" s=\"{1}\"{5}><f ref=\"{2}\" t=\"array\">{3}</f>{4}</c>",
                    cse.CellAddress,
                    styleId < 0 ? 0 : styleId,
                    f.Address,
                    SecurityElement.Escape(f.Formula),
                    GetFormulaValue(v),
                    GetCellType(v, true));
              } else {
                cache.AppendFormat(
                    "<c r=\"{0}\" s=\"{1}\"{6}><f ref=\"{2}\" t=\"shared\"  si=\"{3}\">{4}</f>{5}</c>",
                    cse.CellAddress,
                    styleId < 0 ? 0 : styleId,
                    f.Address,
                    sfId,
                    SecurityElement.Escape(f.Formula),
                    GetFormulaValue(v),
                    GetCellType(v, true));
              }
            } else if (f.IsArray) {
              cache.AppendFormat(
                  "<c r=\"{0}\" s=\"{1}\" />",
                  cse.CellAddress,
                  styleId < 0 ? 0 : styleId);
            } else {
              cache.AppendFormat(
                  "<c r=\"{0}\" s=\"{1}\"{4}><f t=\"shared\" si=\"{2}\" />{3}</c>",
                  cse.CellAddress,
                  styleId < 0 ? 0 : styleId,
                  sfId,
                  GetFormulaValue(v),
                  GetCellType(v, true));
            }
          } else {
            // We can also have a single cell array formula
            if (f.IsArray) {
              cache.AppendFormat(
                  "<c r=\"{0}\" s=\"{1}\"{5}><f ref=\"{2}\" t=\"array\">{3}</f>{4}</c>",
                  cse.CellAddress,
                  styleId < 0 ? 0 : styleId,
                  string.Format("{0}:{1}", f.Address, f.Address),
                  SecurityElement.Escape(f.Formula),
                  GetFormulaValue(v),
                  GetCellType(v, true));
            } else {
              cache.AppendFormat("<c r=\"{0}\" s=\"{1}\">", f.Address, styleId < 0 ? 0 : styleId);
              cache.AppendFormat(
                  "<f>{0}</f>{1}</c>",
                  SecurityElement.Escape(f.Formula),
                  GetFormulaValue(v));
            }
          }
        } else if (formula != null && formula.ToString() != "") {
          cache.AppendFormat(
              "<c r=\"{0}\" s=\"{1}\"{2}>",
              cse.CellAddress,
              styleId < 0 ? 0 : styleId,
              GetCellType(v, true));
          cache.AppendFormat(
              "<f>{0}</f>{1}</c>",
              SecurityElement.Escape(formula.ToString()),
              GetFormulaValue(v));
        } else {
          if (v == null && styleId > 0) {
            cache.AppendFormat(
                "<c r=\"{0}\" s=\"{1}\" />",
                cse.CellAddress,
                styleId < 0 ? 0 : styleId);
          } else if (v != null) {
            if ((v.GetType().IsPrimitive
                        || v is double
                        || v is decimal
                        || v is DateTime
                        || v is TimeSpan)) {
              //string sv = GetValueForXml(v);
              cache.AppendFormat(
                  "<c r=\"{0}\" s=\"{1}\" {2}>",
                  cse.CellAddress,
                  styleId < 0 ? 0 : styleId,
                  GetCellType(v));
              cache.AppendFormat("{0}</c>", GetFormulaValue(v));
            } else {
              int ix;
              if (!ss.ContainsKey(v.ToString())) {
                ix = ss.Count;
                ss.Add(
                    v.ToString(),
                    new() {
                      isRichText = _flags.GetFlagValue(cse.Row, cse.Column, CellFlags.RichText),
                      pos = ix,
                    });
              } else {
                ix = ss[v.ToString()].pos;
              }
              cache.AppendFormat(
                  "<c r=\"{0}\" s=\"{1}\" t=\"s\">",
                  cse.CellAddress,
                  styleId < 0 ? 0 : styleId);
              cache.AppendFormat("<v>{0}</v></c>", ix);
            }
          }
        }
        ////Update hyperlinks.
        //if (cell.Hyperlink != null)
        //{
        //    _hyperLinkCells.Add(cell.CellID);
        //}
      } else //ExcelRow
      {
        //int newRow=((ExcelRow)cse.Value).Row;
        WriteRow(cache, cellXfs, row, cse.Row);
        row = cse.Row;
      }
      if (cache.Length > 0x600000) {
        sw.Write(cache.ToString());
        cache = new();
      }
    }

    if (row != -1) {
      cache.Append("</row>");
    }
    cache.Append("</sheetData>");
    sw.Write(cache.ToString());
    sw.Flush();
  }

  private object GetFormulaValue(object v) {
    //if (_package.Workbook._isCalculated)
    //{
    if (v != null && v.ToString() != "") {
      return "<v>" + SecurityElement.Escape(GetValueForXml(v)) + "</v>"; //Fixes issue 15071
    }
    return "";
  }

  private string GetCellType(object v, bool allowStr = false) {
    if (v is bool) {
      return " t=\"b\"";
    }
    if ((v is double && double.IsInfinity((double)v)) || v is ExcelErrorValue) {
      return " t=\"e\"";
    }
    if (allowStr
        && v != null
        && !(v.GetType().IsPrimitive
                || v is double
                || v is decimal
                || v is DateTime
                || v is TimeSpan)) {
      return " t=\"str\"";
    }
    return "";
  }

  private string GetValueForXml(object v) {
    string s;
    try {
      if (v is DateTime) {
        double sdv = ((DateTime)v).ToOADate();

        if (Workbook.Date1904) {
          sdv -= ExcelWorkbook._date1904Offset;
        }

        s = sdv.ToString(CultureInfo.InvariantCulture);
      } else if (v is TimeSpan) {
        s = new DateTime(((TimeSpan)v).Ticks).ToOADate().ToString(CultureInfo.InvariantCulture);
        ;
      } else if (v.GetType().IsPrimitive || v is double || v is decimal) {
        if (v is double && double.IsNaN((double)v)) {
          s = "";
        } else if (v is double && double.IsInfinity((double)v)) {
          s = "#NUM!";
        } else {
          s = Convert
              .ToDouble(v, CultureInfo.InvariantCulture)
              .ToString("R15", CultureInfo.InvariantCulture);
        }
      } else {
        s = v.ToString();
      }
    } catch {
      s = "0";
    }
    return s;
  }

  private void WriteRow(
      StringBuilder cache,
      ExcelStyleCollection<ExcelXfs> cellXfs,
      int prevRow,
      int row) {
    if (prevRow != -1) {
      cache.Append("</row>");
    }
    //ulong rowID = ExcelRow.GetRowID(SheetID, row);
    cache.AppendFormat("<row r=\"{0}\" ", row);
    RowInternal currRow = _values.GetValue(row, 0) as RowInternal;
    if (currRow != null) {
      if (currRow.Hidden) {
        cache.Append("ht=\"0\" hidden=\"1\" ");
      } else if (currRow.Height != DefaultRowHeight && currRow.Height >= 0) {
        cache.AppendFormat(CultureInfo.InvariantCulture, "ht=\"{0}\" ", currRow.Height);
        if (currRow.CustomHeight) {
          cache.Append("customHeight=\"1\" ");
        }
      }

      if (currRow.OutlineLevel > 0) {
        cache.AppendFormat("outlineLevel =\"{0}\" ", currRow.OutlineLevel);
        if (currRow.Collapsed) {
          if (currRow.Hidden) {
            cache.Append(" collapsed=\"1\" ");
          } else {
            cache.Append(" collapsed=\"1\" hidden=\"1\" "); //Always hidden
          }
        }
      }
      if (currRow.Phonetic) {
        cache.Append("ph=\"1\" ");
      }
    }
    var s = _styles.GetValue(row, 0);
    if (s > 0) {
      cache.AppendFormat("s=\"{0}\" customFormat=\"1\"", cellXfs[s].newID);
    }
    cache.Append(">");
  }

  private void WriteRow(
      StreamWriter sw,
      ExcelStyleCollection<ExcelXfs> cellXfs,
      int prevRow,
      int row) {
    if (prevRow != -1) {
      sw.Write("</row>");
    }
    //ulong rowID = ExcelRow.GetRowID(SheetID, row);
    sw.Write("<row r=\"{0}\" ", row);
    RowInternal currRow = _values.GetValue(row, 0) as RowInternal;
    if (currRow != null) {
      if (currRow.Hidden) {
        sw.Write("ht=\"0\" hidden=\"1\" ");
      } else if (currRow.Height != DefaultRowHeight) {
        sw.Write(string.Format(CultureInfo.InvariantCulture, "ht=\"{0}\" ", currRow.Height));
        if (currRow.CustomHeight) {
          sw.Write("customHeight=\"1\" ");
        }
      }

      if (currRow.OutlineLevel > 0) {
        sw.Write("outlineLevel =\"{0}\" ", currRow.OutlineLevel);
        if (currRow.Collapsed) {
          if (currRow.Hidden) {
            sw.Write(" collapsed=\"1\" ");
          } else {
            sw.Write(" collapsed=\"1\" hidden=\"1\" "); //Always hidden
          }
        }
      }
      if (currRow.Phonetic) {
        sw.Write("ph=\"1\" ");
      }
    }
    var s = _styles.GetValue(row, 0);
    if (s > 0) {
      sw.Write("s=\"{0}\" customFormat=\"1\"", cellXfs[s].newID);
    }
    sw.Write(">");
  }

  /// <summary>
  /// Update xml with hyperlinks
  /// </summary>
  /// <param name="sw">The stream</param>
  private void UpdateHyperLinks(StreamWriter sw) {
    Dictionary<string, string> hyps = new Dictionary<string, string>();
    var cse = new CellsStoreEnumerator<Uri>(_hyperLinks);
    bool first = true;
    //foreach (ulong cell in _hyperLinks)
    while (cse.Next()) {
      if (first) {
        sw.Write("<hyperlinks>");
        first = false;
      }
      //int row, col;
      var uri = _hyperLinks.GetValue(cse.Row, cse.Column);
      //ExcelCell cell = _cells[cellId] as ExcelCell;
      if (uri is ExcelHyperLink
          && !string.IsNullOrEmpty((uri as ExcelHyperLink).ReferenceAddress)) {
        ExcelHyperLink hl = uri as ExcelHyperLink;
        sw.Write(
            "<hyperlink ref=\"{0}\" location=\"{1}\" {2}{3}/>",
            Cells[cse.Row, cse.Column, cse.Row + hl.RowSpann, cse.Column + hl.ColSpann].Address,
            ExcelCellBase.GetFullAddress(
                SecurityElement.Escape(Name),
                SecurityElement.Escape(hl.ReferenceAddress)),
            string.IsNullOrEmpty(hl.Display)
                ? ""
                : "display=\"" + SecurityElement.Escape(hl.Display) + "\" ",
            string.IsNullOrEmpty(hl.ToolTip)
                ? ""
                : "tooltip=\"" + SecurityElement.Escape(hl.ToolTip) + "\" ");
      } else if (uri != null) {
        string id;
        Uri hyp;
        if (uri is ExcelHyperLink) {
          hyp = ((ExcelHyperLink)uri).OriginalUri;
        } else {
          hyp = uri;
        }
        if (hyps.ContainsKey(hyp.OriginalString)) {
          id = hyps[hyp.OriginalString];
        } else {
          var relationship = Part.CreateRelationship(
              hyp,
              TargetMode.External,
              ExcelPackage._schemaHyperlink);
          if (uri is ExcelHyperLink) {
            ExcelHyperLink hl = uri as ExcelHyperLink;
            sw.Write(
                "<hyperlink ref=\"{0}\" {2}{3}r:id=\"{1}\" />",
                ExcelCellBase.GetAddress(cse.Row, cse.Column),
                relationship.Id,
                string.IsNullOrEmpty(hl.Display)
                    ? ""
                    : "display=\"" + SecurityElement.Escape(hl.Display) + "\" ",
                string.IsNullOrEmpty(hl.ToolTip)
                    ? ""
                    : "tooltip=\"" + SecurityElement.Escape(hl.ToolTip) + "\" ");
          } else {
            sw.Write(
                "<hyperlink ref=\"{0}\" r:id=\"{1}\" />",
                ExcelCellBase.GetAddress(cse.Row, cse.Column),
                relationship.Id);
          }
          id = relationship.Id;
        }
        //cell.HyperLinkRId = id;
      }
    }
    if (!first) {
      sw.Write("</hyperlinks>");
    }
  }

  /// <summary>
  /// Create the hyperlinks node in the XML
  /// </summary>
  /// <returns></returns>
  private XmlNode CreateHyperLinkCollection() {
    XmlElement hl = _worksheetXml.CreateElement("hyperlinks", ExcelPackage._schemaMain);
    XmlNode prevNode = _worksheetXml.SelectSingleNode(
        "//d:conditionalFormatting",
        NameSpaceManager);
    if (prevNode == null) {
      prevNode = _worksheetXml.SelectSingleNode("//d:mergeCells", NameSpaceManager);
      if (prevNode == null) {
        prevNode = _worksheetXml.SelectSingleNode("//d:sheetData", NameSpaceManager);
      }
    }
    return _worksheetXml.DocumentElement.InsertAfter(hl, prevNode);
  }

  /// <summary>
  /// Dimension address for the worksheet.
  /// Top left cell to Bottom right.
  /// If the worksheet has no cells, null is returned
  /// </summary>
  public ExcelAddressBase Dimension {
    get {
      CheckSheetType();
      int fromRow,
          fromCol,
          toRow,
          toCol;
      if (_values.GetDimension(out fromRow, out fromCol, out toRow, out toCol)) {
        var addr = new ExcelAddressBase(fromRow, fromCol, toRow, toCol);
        addr._ws = Name;
        return addr;
      }
      return null;
    }
  }

  private ExcelSheetProtection _protection;

  /// <summary>
  /// Access to sheet protection properties
  /// </summary>
  public ExcelSheetProtection Protection {
    get {
      if (_protection == null) {
        _protection = new(NameSpaceManager, TopNode, this);
      }
      return _protection;
    }
  }

  private ExcelProtectedRangeCollection _protectedRanges;

  public ExcelProtectedRangeCollection ProtectedRanges {
    get {
      if (_protectedRanges == null) {
        _protectedRanges = new(NameSpaceManager, TopNode, this);
      }
      return _protectedRanges;
    }
  }

  private ExcelTableCollection _tables;

  /// <summary>
  /// Tables defined in the worksheet.
  /// </summary>
  public ExcelTableCollection Tables {
    get {
      CheckSheetType();
      if (Workbook._nextTableID == int.MinValue) {
        Workbook.ReadAllTables();
      }
      if (_tables == null) {
        _tables = new(this);
      }
      return _tables;
    }
  }

  private ExcelPivotTableCollection _pivotTables;

  /// <summary>
  /// Pivottables defined in the worksheet.
  /// </summary>
  public ExcelPivotTableCollection PivotTables {
    get {
      CheckSheetType();
      if (_pivotTables == null) {
        if (Workbook._nextPivotTableID == int.MinValue) {
          Workbook.ReadAllTables();
        }
        _pivotTables = new(this);
      }
      return _pivotTables;
    }
  }

  private ExcelConditionalFormattingCollection _conditionalFormatting;

  /// <summary>
  /// ConditionalFormatting defined in the worksheet. Use the Add methods to create ConditionalFormatting and add them to the worksheet. Then
  /// set the properties on the instance returned.
  /// </summary>
  /// <seealso cref="ExcelConditionalFormattingCollection"/>
  public ExcelConditionalFormattingCollection ConditionalFormatting {
    get {
      CheckSheetType();
      if (_conditionalFormatting == null) {
        _conditionalFormatting = new(this);
      }
      return _conditionalFormatting;
    }
  }

  private ExcelDataValidationCollection _dataValidation;

  /// <summary>
  /// DataValidation defined in the worksheet. Use the Add methods to create DataValidations and add them to the worksheet. Then
  /// set the properties on the instance returned.
  /// </summary>
  /// <seealso cref="ExcelDataValidationCollection"/>
  public ExcelDataValidationCollection DataValidations {
    get {
      CheckSheetType();
      if (_dataValidation == null) {
        _dataValidation = new(this);
      }
      return _dataValidation;
    }
  }

  /// <summary>
  /// Returns the style ID given a style name.
  /// The style ID will be created if not found, but only if the style name exists!
  /// </summary>
  /// <param name="styleName"></param>
  /// <returns></returns>
  internal int GetStyleId(string styleName) {
    ExcelNamedStyleXml namedStyle = null;
    Workbook.Styles.NamedStyles.FindById(styleName, ref namedStyle);
    if (namedStyle.XfId == int.MinValue) {
      namedStyle.XfId = Workbook.Styles.CellXfs.FindIndexById(namedStyle.Style.Id);
    }
    return namedStyle.XfId;
  }

  /// <summary>
  /// The workbook object
  /// </summary>
  public ExcelWorkbook Workbook => _package.Workbook;

  /// <summary>
  /// Get the next ID from a shared formula or an Array formula
  /// Sharedforumlas will have an id from 0-x. Array formula ids start from 0x4000001-.
  /// </summary>
  /// <param name="isArray">If the formula is an array formula</param>
  /// <returns></returns>
  internal int GetMaxShareFunctionIndex(bool isArray) {
    int i = _sharedFormulas.Count + 1;
    if (isArray) {
      i |= 0x40000000;
    }

    while (_sharedFormulas.ContainsKey(i)) {
      i++;
    }
    return i;
  }

  internal void SetHfLegacyDrawingRel(string relId) {
    SetXmlNodeString("d:legacyDrawingHF/@r:id", relId);
  }

  internal void RemoveLegacyDrawingRel(string relId) {
    var n = WorksheetXml.DocumentElement.SelectSingleNode(
        string.Format("d:legacyDrawing[@r:id=\"{0}\"]", relId),
        NameSpaceManager);
    if (n != null) {
      n.ParentNode.RemoveChild(n);
    }
  }

  internal void UpdateCellsWithDate1904Setting() {
    var cse = new CellsStoreEnumerator<object>(_values);
    var offset = Workbook.Date1904 ? -ExcelWorkbook._date1904Offset : ExcelWorkbook._date1904Offset;
    while (cse.MoveNext()) {
      if (cse.Value is DateTime) {
        try {
          double sdv = ((DateTime)cse.Value).ToOADate();
          sdv += offset;

          cse.Value = DateTime.FromOADate(sdv);
        } catch {}
      }
    }
  }

  public string GetFormula(int row, int col) {
    var v = _formulas.GetValue(row, col);
    if (v is int) {
      return _sharedFormulas[(int)v].GetFormula(row, col, Name);
    }
    if (v != null) {
      return v.ToString();
    }
    return "";
  }

  public string GetFormulaR1C1(int row, int col) {
    var v = _formulas.GetValue(row, col);
    if (v is int) {
      var sf = _sharedFormulas[(int)v];
      return ExcelCellBase.TranslateToR1C1(
          Formulas.RemoveDummyFunction(sf.Formula),
          sf.StartRow,
          sf.StartCol);
    }
    if (v != null) {
      return ExcelCellBase.TranslateToR1C1(Formulas.RemoveDummyFunction(v.ToString()), row, col);
    }
    return "";
  }

  public string GetFormulaR1C1_V1(int row, int col) {
    var v = _formulas.GetValue(row, col);
    if (v is int) {
      var sf = _sharedFormulas[(int)v];
      return ExcelCellBase.TranslateToR1C1_V1(
          Formulas.RemoveDummyFunction(sf.Formula),
          sf.StartRow,
          sf.StartCol);
    }
    if (v != null) {
      return ExcelCellBase.TranslateToR1C1_V1(Formulas.RemoveDummyFunction(v.ToString()), row, col);
    }
    return "";
  }

  public bool IsArrayFormula(int row, int col) =>
    _flags.GetFlagValue(row, col, CellFlags.ArrayFormula);

  public string GetArrayFormulaAddress(int row, int col) {
    var v = _formulas.GetValue(row, col);
    if ((v is int) && (_sharedFormulas[(int)v].IsArray)) {
      return _sharedFormulas[(int)v].Address;
    }
    return "";
  }

  public int GetStyleId(int row, int col) {
    int styleId = 0;
    if (!_styles.Exists(row, col, ref styleId) && !_styles.Exists(row, 0, ref styleId)) {
      styleId = _styles.GetValue(0, col);
    }
    return styleId;
  }

  /// <summary>
  /// Get the ExcelColumn for column (span ColumnMin and ColumnMax)
  /// </summary>
  /// <param name="column"></param>
  /// <returns></returns>
  internal ExcelColumn GetColumn(int column) {
    var c = _values.GetValue(0, column) as ExcelColumn;
    if (c == null) {
      int row = 0,
          col = column;
      if (_values.PrevCell(ref row, ref col)) {
        c = _values.GetValue(0, col) as ExcelColumn;
        if (c != null && c.ColumnMax >= column) {
          return c;
        }
        return null;
      }
    }
    return c;
  }

  public bool Equals(ExcelWorksheet x, ExcelWorksheet y) {
    return x.Name == y.Name
        && x.SheetID == y.SheetID
        && x.WorksheetXml.OuterXml == y.WorksheetXml.OuterXml;
  }

  public int GetHashCode(ExcelWorksheet obj) {
    return obj.WorksheetXml.OuterXml.GetHashCode();
  }
}
