【问题标题】:How to convert Excel sheet column names into numbers? [duplicate]如何将 Excel 工作表列名转换为数字? [复制]
【发布时间】:2010-10-25 06:59:18
【问题描述】:

我想知道将 excel 工作表列名转换为数字的最佳方法是什么。

我正在使用Excel Package,这是一个处理 .xlsx 文档的好库。不幸的是,这个库没有包含这个功能。

OBS:第一列 A 对应 在这个库中排名第一。

【问题讨论】:

    标签: c# excel


    【解决方案1】:

    这个函数应该适用于任意长度的列名。

    public static int GetColumnNumber(string name)
    {
        int number = 0;
        int pow = 1;
        for (int i = name.Length - 1; i >= 0; i--)
        {
            number += (name[i] - 'A' + 1) * pow;
            pow *= 26;
        }
    
        return number;
    }
    

    【讨论】:

    • 请注意,只有当给定的列名 (name)为大写时,它才会按预期工作。 (将 name[i] 替换为 name.ToUpper()[i] 以解决此问题。)
    【解决方案2】:

    几个月前我不得不处理这个问题。反列 - 列名的列索引 - 也很有趣,如果您尝试使用从零开始的索引来解决它,但没有意识到这会使事情变得复杂,它会变得非常混乱。如果它是一个普通的多元数字系统,它可能会如此简单......

    这是我的解决方案的简化版本,作为一种扩展方法,没有错误处理和所有这些东西。

    public static Int32 ToOneBasedIndex(this String name)
    {
        return name.ToUpper().
           Aggregate(0, (column, letter) => 26 * column + letter - 'A' + 1);
    }
    

    【讨论】:

      【解决方案3】:

      我已经使用它一段时间了,发现它对于超出 AZ 甚至超出 AA-ZZ 的列非常有效...它是通过拆分字符串中的每个字符并递归调用来实现的自己推导出 ASCII 字符的 DEC 值(减去 64),然后将其乘以 26^n。当 n > 4 时,使用 long 的返回值来克服潜在的限制。

          public long columnNumber(String columnName)
          {
              char[] chars = columnName.ToUpper().ToCharArray();
      
              return (long)(Math.Pow(26, chars.Count() - 1)) * 
                  (System.Convert.ToInt32(chars[0]) - 64) + 
                  ((chars.Count() > 2) ? columnNumber(columnName.Substring(1, columnName.Length - 1)) : 
                  ((chars.Count() == 2) ? (System.Convert.ToInt32(chars[chars.Count() - 1]) - 64) : 0));
          }
      

      此外,如果您想获得相反的信息(即传入 columnNumber 并获取 columnName,这里有一些代码可以解决这个问题。

          public String columnName(long columnNumber)
          {
              StringBuilder retVal = new StringBuilder();
              int x = 0;
      
              for (int n = (int)(Math.Log(25*(columnNumber + 1))/Math.Log(26)) - 1; n >= 0; n--)
              {
                  x = (int)((Math.Pow(26,(n + 1)) - 1) / 25 - 1);
                  if (columnNumber > x)
                      retVal.Append(System.Convert.ToChar((int)(((columnNumber - x - 1) / Math.Pow(26, n)) % 26 + 65)));
              }
      
              return retVal.ToString();
          }
      

      【讨论】:

      • 很棒的算法。完美运行!
      【解决方案4】:

      源代码:

      namespace XLS
      {
      /// <summary>
      /// Represents a single cell in a excell sheet
      /// </summary>
      public struct Cell
      {
          private long row;
          private long column;
          private string columnAddress;
          private string address;
          private bool dataChange;
      
          /// <summary>
          /// Initializes a new instance of the XLS.Cell 
          /// class with the specified row and column of excel worksheet
          /// </summary>
          /// <param name="row">The row index of a cell</param>
          /// <param name="column">The column index of a cell</param>
          public Cell(long row, long column)
          {
              this.row = row;
              this.column = column;
              dataChange = true;
              address = string.Empty;
              columnAddress = string.Empty;
          }
      
          /// <summary>
          /// Initializes a new instance of the XLS.Cell
          /// class with the specified address of excel worksheet
          /// </summary>
          /// <param name="address">The adress of a cell</param>
          public Cell(string address)
          {
              this.address = address;
              dataChange = false;
              row = GetRow(address);
              columnAddress = GetColumnAddress(address);
              column = GetColumn(columnAddress);
          }
      
          /// <summary>
          /// Gets or sets the row of this XLS.Cell
          /// </summary>
          public long Row
          {
              get { return row <= 0 ? 1 : row; }
              set { row = value; dataChange = true; }
          }
      
          /// <summary>
          /// Gets or sets the column of this XLS.Cell
          /// </summary>
          public long Column
          {
              get { return column <= 0 ? 1 : column; }
              set { column = value; dataChange = true; }
          }
      
          /// <summary>
          /// Gets or sets the address of this XLS.Cell
          /// </summary>
          public string Address
          {
              get { return dataChange ? ToAddress() : address; }
              set
              {
                  address = value;
                  row = GetRow(address);
                  column = GetColumn(address);
              }
          }
      
          /// <summary>
          /// Gets the column address of this XLS.Cell
          /// </summary>
          public string ColumnAddress
          {
              get { return GetColumnAddress(Address); }
              private set { columnAddress = value; }
          }
      
          #region Private Methods
      
          private static long GetRow(string address)
          {
              return long.Parse(address.Substring(GetStartIndex(address)));
          }
      
          private static string GetColumnAddress(string address)
          {
              return address.Substring(0, GetStartIndex(address)).ToUpperInvariant();
          }
      
          private static long GetColumn(string columnAddress)
          {
              char[] characters = columnAddress.ToCharArray();
              int sum = 0;
              for (int i = 0; i < characters.Length; i++)
              {
                  sum *= 26;
                  sum += (characters[i] - 'A' + 1);
              }
      
              return (long)sum;
          }
      
          private static int GetStartIndex(string address)
          {
              return address.IndexOfAny("123456789".ToCharArray());
          }
      
          private string ToAddress()
          {
              string indexToString = string.Empty;
      
              if (Column > 26)
              {
                  indexToString = ((char)(65 + (int)((Column - 1) / 26) - 1)).ToString();
              }
      
              indexToString += (char)(65 + ((Column - 1) % 26));
      
              dataChange = false;
              return indexToString + Row;
          }
      
          #endregion
      }
      

      }

      【讨论】:

        【解决方案5】:

        O24 有一个列号,你想要一个名字:

        =LEFT(RIGHT(ADDRESS(1,O24),LEN(ADDRESS(1,O24))-1),FIND("$",RIGHT((ADDRESS(1,O24))),LEN(ADDRESS(1 ,O24))-1))-1)

        O37 有一个列名,你想要一个数字:

        =COLUMN(间接(O37&1))

        【讨论】:

          【解决方案6】:
          public static string GetColumnName(int index)
          {
              const string letters = "ZABCDEFGHIJKLMNOPQRSTUVWXY";
          
              int NextPos = (index / 26);
              int LastPos = (index % 26);
              if (LastPos == 0) NextPos--;
          
              if (index > 26)
                  return GetColumnName(NextPos) + letters[LastPos];
              else
                  return letters[LastPos] + "";
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-09-27
            • 2019-10-16
            • 2021-06-11
            • 2021-09-19
            • 1970-01-01
            • 1970-01-01
            • 2019-09-21
            相关资源
            最近更新 更多