C# 如何将Excel工作表列名转换为数字?
我想知道将excel工作表列名转换为数字的最佳方法是什么 我正在使用一个很好的库来处理.xlsx文档。很遗憾,此库没有包含此功能 OBS:第一列A对应 到这个图书馆的第一位C# 如何将Excel工作表列名转换为数字?,c#,excel,C#,Excel,我想知道将excel工作表列名转换为数字的最佳方法是什么 我正在使用一个很好的库来处理.xlsx文档。很遗憾,此库没有包含此功能 OBS:第一列A对应 到这个图书馆的第一位 此函数应适用于任意长度的列名 public static int GetColumnNumber(string name) { int number = 0; int pow = 1; for (int i = name.Length - 1; i >= 0; i--) {
此函数应适用于任意长度的列名
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;
}
几个月前我不得不处理这件事。列索引到列名的倒数也很有趣,如果你试图用一个从零开始的索引来解决它,而没有意识到这会使事情复杂化,那么它就会变得非常混乱。如果它是一个普通的多元数字系统,它可能会很简单 这是我的解决方案的一个简化版本,作为一个扩展方法,没有错误处理之类的东西
public static Int32 ToOneBasedIndex(this String name)
{
return name.ToUpper().
Aggregate(0, (column, letter) => 26 * column + letter - 'A' + 1);
}
我已经用这个做了一段时间了,发现它对a-Z以外,甚至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();
}
源代码:
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
}
名称空间XLS
{
///
///表示Excel工作表中的单个单元格
///
公共结构单元
{
私人长排;
私人长柱;
私有字符串列地址;
私有字符串地址;
私有布尔数据交换;
///
///初始化XLS.Cell的新实例
///使用excel工作表的指定行和列初始化
///
///单元格的行索引
///单元格的列索引
公共单元格(长行、长列)
{
this.row=行;
this.column=列;
dataChange=true;
address=string.Empty;
columnAddress=string.Empty;
}
///
///初始化XLS.Cell的新实例
///使用excel工作表的指定地址初始化
///
///细胞的地址
公共单元格(字符串地址)
{
this.address=地址;
dataChange=false;
row=GetRow(地址);
columnAddress=GetColumnAddress(地址);
column=GetColumn(columnAddress);
}
///
///获取或设置此XLS.Cell的行
///
公众长队
{
get{return rowO24有一个列号,您需要一个名称:
=左(右(地址(1,O24)),LEN(地址(1,O24))-1,FIND(“$”),右(地址(1,O24)),LEN(地址(1,O24))-1)
O37有一个列名,您需要一个数字:
=列(间接(O37&1))请注意,只有当给定的列名(name
)为大写时,此选项才能按预期工作。(将name[i]
替换为name.ToUpper()[i]
以解决此问题。)伟大的算法。工作完美!
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] + "";
}