/*******************************************************************************
* 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.Collections.Immutable;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace AppsheetEpplus;

/// <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,
      ExcelWorkbook workbook,
      Uri worksheetUri,
      string name,
      int sheetId,
      int positionId,
      eWorkSheetHidden hidden)
      : base(ns, pck, workbook, worksheetUri, name, 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 readonly 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 readonly CellStore<int> _cells = new();
    private readonly List<string> _list = [];

    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) {
      //Validate
      if (doValidate && Validate(address) == false) {
        throw (new ArgumentException("Can't merge and already merged range"));
      }
      var 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 readonly CellStore<object> _values = new();
  internal readonly CellStore<string> _types = new();
  internal readonly CellStore<int> _styles = new();
  internal readonly CellStore<object> _formulas = new();
  internal readonly FlagCellStore _flags = new();
  internal CellStore<List<Token>> _formulaTokens;

  internal readonly CellStore<Uri> _hyperLinks = new();
  internal readonly CellStore<ExcelComment> _commentsStore = new();

  internal readonly Dictionary<int, Formulas> _sharedFormulas = new();

  internal readonly ExcelPackage _package;
  private readonly ExcelWorkbook _workbook;
  private ExcelWorksheetView _sheetView;

  internal static ImmutableArray<string> WorksheetSchemaNodeOrder = [
    "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",
  ];

  protected override ImmutableArray<string> SchemaNodeOrder => WorksheetSchemaNodeOrder;

  internal ExcelWorksheet(
      XmlNamespaceManager ns,
      ExcelPackage excelPackage,
      ExcelWorkbook workbook,
      Uri worksheetUri,
      string name,
      int sheetId,
      int positionId,
      eWorkSheetHidden hidden)
      : base(ns, null) {
    _workbook = workbook;
    _package = excelPackage;
    _names = new(Workbook, this);

    Hidden = hidden;
    Name = name;
    PositionID = positionId;
    SheetID = sheetId;

    Part = _package.Package.GetPart(worksheetUri);
    Part.SaveHandler = SaveHandler;

    // First Columns, rows, cells, mergecells, hyperlinks and pagebreakes are loaded from an
    // XmlTextReader to optimize speed.
    using var stream = Part.GetStream();
    var 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);
    var xml = GetWorkSheetXml(stream, start, end, out var encoding);

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

    TopNode = WorksheetXml.DocumentElement;
  }

  /// <summary>
  /// The Zip.ZipPackagePart for the worksheet within the package
  /// </summary>
  internal ZipPackagePart Part { get; }

  /// <summary>
  /// The unique identifier for the worksheet.
  /// </summary>
  internal int SheetID { get; }

  /// <summary>
  /// The position of the worksheet.
  /// </summary>
  internal int PositionID { get; }

  /// <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; }

  private readonly 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 = _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) {
        _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);
        _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 _codeModuleNamePath = "d:sheetPr/@codeName";

  internal string CodeModuleName {
    get => GetXmlNodeString(_codeModuleNamePath);
    set => SetXmlNodeString(_codeModuleNamePath, 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>
  internal XmlDocument WorksheetXml { get; } = new();

  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;
      }
    }
  }

  /// <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) {
          if (int.TryParse(xr.GetAttribute("id"), out var 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) {
          if (int.TryParse(xr.GetAttribute("id"), out var 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);

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

  /// <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") {
        ExcelCellBase.GetRowColFromAddress(
            xr.GetAttribute("ref"),
            out var fromRow,
            out var fromCol,
            out int toRow,
            out var 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;
      }
    }
  }

  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");
          _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 >= _workbook._sharedStringsList.Count) {
        throw new(
            string.Format(
                "ReadElementContentAsInt returned index value '{0}' which is greater than _sharedStringsList count of {1}.",
                ix,
                _workbook._sharedStringsList.Count));
      }

      _values.SetValue(row, col, _workbook._sharedStringsList[ix].Text);
      if (_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
      {
        if (double.TryParse(v, NumberStyles.Any, CultureInfo.InvariantCulture, out var 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
      {
        if (double.TryParse(v, NumberStyles.Any, CultureInfo.InvariantCulture, out var 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 {
        if (double.TryParse(v, NumberStyles.Any, CultureInfo.InvariantCulture, out var 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);
    //}
  }

  ///// <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 readonly 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 toCol,
        toRow;
    //Get rows and columns and validate as well
    ExcelCellBase.GetRowColFromAddress(
        address,
        out var fromRow,
        out var 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."));
    }

    _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."));
    }

    _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 column) {
        lst.Add(column);
      }
    }

    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 = [];
    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 = [];
    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]);
    }
  }

  /// <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)));
    }
    _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)));
    }
    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 excelColumn) {
        if (excelColumn._columnMin >= columnFrom) {
          excelColumn._columnMin -= columns;
          excelColumn._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);
    }
    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;
        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;
        }
      }
    }
    foreach (var ix in delSf) {
      _sharedFormulas.Remove(ix);
    }
    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();
    var v = _values.GetValue(row, column);
    if (v != null) {
      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)) {
        if (DateTime.TryParse(v.ToString(), out var 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)) {
        if (TimeSpan.TryParse(v.ToString(), out var 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();
    ExcelCellBase.GetRowCol(address, out var row, out var 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 (!(this is ExcelChartsheet)) {
      var d = Dimension;
      if (d == null) {
        DeleteAllNode("d:dimension/@ref");
      } else {
        SetXmlNodeString("d:dimension/@ref", d.Address);
      }
      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));
      UpdateColumnData(streamWriter);

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

      streamWriter.Write(xml.Substring(colEnd, cellStart - colEnd));
      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));
      UpdateHyperLinks(streamWriter);

      int rowBreakStart = hyperEnd,
          rowBreakEnd = hyperEnd;
      GetBlockPos(xml, "rowBreaks", ref rowBreakStart, ref rowBreakEnd);
      streamWriter.Write(xml.Substring(hyperEnd, rowBreakStart - hyperEnd));
      UpdateRowBreaks(streamWriter);

      int colBreakStart = rowBreakEnd,
          colBreakEnd = rowBreakEnd;
      GetBlockPos(xml, "colBreaks", ref colBreakStart, ref colBreakEnd);
      streamWriter.Write(xml.Substring(rowBreakEnd, colBreakStart - rowBreakEnd));
      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);
        }
      }
    }
  }

  /// <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++;
        }
      }
    }
  }

  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;
          }
        }
      }
    }
  }

  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);
    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) {
    var cse = new CellsStoreEnumerator<object>(_values, 0, 1, 0, ExcelPackage.MaxColumns);
    bool first = true;
    while (cse.Next()) {
      if (first) {
        sw.Write("<cols>");
        first = false;
      }
      var col = cse.Value as ExcelColumn;
      ExcelStyleCollection<ExcelXfs> cellXfs = _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 (!first) {
      sw.Write("</cols>");
    }
  }

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

    int row = -1;

    var ss = _workbook._sharedStrings;
    var styles = _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 sfId) {
          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);
            }
          }
        }
      } else //ExcelRow
      {
        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 (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 d && double.IsInfinity(d)) || 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 time) {
        double sdv = time.ToOADate();

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

        s = sdv.ToString(CultureInfo.InvariantCulture);
      } else if (v is TimeSpan span) {
        s = new DateTime(span.Ticks).ToOADate().ToString(CultureInfo.InvariantCulture);
        ;
      } else if (v.GetType().IsPrimitive || v is double || v is decimal) {
        if (v is double d && double.IsNaN(d)) {
          s = "";
        } else if (v is double d1 && double.IsInfinity(d1)) {
          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(">");
  }

  /// <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 link && !string.IsNullOrEmpty(link.ReferenceAddress)) {
        sw.Write(
            "<hyperlink ref=\"{0}\" location=\"{1}\" {2}{3}/>",
            Cells[cse.Row, cse.Column, cse.Row + link.RowSpann, cse.Column + link.ColSpann].Address,
            ExcelCellBase.GetFullAddress(
                SecurityElement.Escape(Name),
                SecurityElement.Escape(link.ReferenceAddress)),
            string.IsNullOrEmpty(link.Display)
                ? ""
                : "display=\"" + SecurityElement.Escape(link.Display) + "\" ",
            string.IsNullOrEmpty(link.ToolTip)
                ? ""
                : "tooltip=\"" + SecurityElement.Escape(link.ToolTip) + "\" ");
      } else if (uri != null) {
        Uri hyp;
        if (uri is ExcelHyperLink hyperLink) {
          hyp = hyperLink.OriginalUri;
        } else {
          hyp = uri;
        }
        if (!hyps.ContainsKey(hyp.OriginalString)) {
          var relationship = Part.CreateRelationship(
              hyp,
              TargetMode.External,
              ExcelPackage._schemaHyperlink);
          if (uri is ExcelHyperLink hl) {
            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);
          }
        }
      }
    }
    if (!first) {
      sw.Write("</hyperlinks>");
    }
  }

  /// <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();
      if (_values.GetDimension(out var fromRow, out var fromCol, out var toRow, out var 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);
      }
      return _protection;
    }
  }

  private ExcelProtectedRangeCollection _protectedRanges;

  public ExcelProtectedRangeCollection ProtectedRanges {
    get {
      if (_protectedRanges == null) {
        _protectedRanges = new(NameSpaceManager, TopNode);
      }
      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 => _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 UpdateCellsWithDate1904Setting() {
    var cse = new CellsStoreEnumerator<object>(_values);
    var offset = Workbook.Date1904 ? -ExcelWorkbook._date1904Offset : ExcelWorkbook._date1904Offset;
    while (cse.MoveNext()) {
      if (cse.Value is DateTime time) {
        try {
          double sdv = time.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 i) {
      return _sharedFormulas[i].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 i) {
      var sf = _sharedFormulas[i];
      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 i) {
      var sf = _sharedFormulas[i];
      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 i) && (_sharedFormulas[i].IsArray)) {
      return _sharedFormulas[i].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();
  }
}
