如何在c#中将数值转换为Excel列名,而不使用直接从Excel中获取值的自动化。
Excel 2007的范围可能是1到16384,这是它支持的列数。结果值应以excel列名的形式出现,例如A、AA、AAA等。
如何在c#中将数值转换为Excel列名,而不使用直接从Excel中获取值的自动化。
Excel 2007的范围可能是1到16384,这是它支持的列数。结果值应以excel列名的形式出现,例如A、AA、AAA等。
当前回答
private String getColumn(int c) {
String s = "";
do {
s = (char)('A' + (c % 26)) + s;
c /= 26;
} while (c-- > 0);
return s;
}
它不是以26为底,系统中没有0。如果有的话,'Z'后面应该是'BA'而不是'AA'。
其他回答
private String getColumn(int c) {
String s = "";
do {
s = (char)('A' + (c % 26)) + s;
c /= 26;
} while (c-- > 0);
return s;
}
它不是以26为底,系统中没有0。如果有的话,'Z'后面应该是'BA'而不是'AA'。
int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
int nChar = nCol % 26;
nCol = (nCol - nChar) / 26;
// You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;
更新:Peter的评论是正确的。这就是我在浏览器中编写代码的结果。:-)我的解决方案是不编译,它是最左边的字母,它是在反向顺序构建字符串-现在都固定了。
除了bug之外,该算法基本上是将一个数字从10进制转换为26进制。
更新2:Joel Coehoorn是对的-上面的代码将返回AB为27。如果它是一个以26为底的实数,AA就等于A, Z之后的下一个数字就是BA。
int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
int nChar = nCol % 26;
if (nChar == 0)
nChar = 26;
nCol = (nCol - nChar) / 26;
sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
sCol = sChars[nCol] + sCol;
我今天必须做这个工作,我的实现使用递归:
private static string GetColumnLetter(string colNumber)
{
if (string.IsNullOrEmpty(colNumber))
{
throw new ArgumentNullException(colNumber);
}
string colName = String.Empty;
try
{
var colNum = Convert.ToInt32(colNumber);
var mod = colNum % 26;
var div = Math.Floor((double)(colNum)/26);
colName = ((div > 0) ? GetColumnLetter((div - 1).ToString()) : String.Empty) + Convert.ToChar(mod + 65);
}
finally
{
colName = colName == String.Empty ? "A" : colName;
}
return colName;
}
该方法将数字视为字符串,而以“0”开头的数字(A = 0)
虽然我在这方面姗姗来迟,但格雷厄姆的答案远非最佳。特别是,你不需要使用模数,调用ToString()和apply (int)强制转换。考虑到在c#世界中的大多数情况下,您将从0开始编号,以下是我的修订:
public static string GetColumnName(int index) // zero-based
{
const byte BASE = 'Z' - 'A' + 1;
string name = String.Empty;
do
{
name = Convert.ToChar('A' + index % BASE) + name;
index = index / BASE - 1;
}
while (index >= 0);
return name;
}
下面是我在Python中如何做的。算法说明如下:
alph = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
def labelrec(n, res):
if n<26:
return alph[n]+res
else:
rem = n%26
res = alph[rem]+res
n = n/26-1
return labelrec(n, res)
函数labelrec可以用数字和一个空字符串来调用,比如:
print labelrec(16383, '')
以下是它有效的原因: 如果十进制数字的书写方式与Excel表格列相同,那么数字0-9将被正常书写,但10将变成“00”,然后20将变成“10”,以此类推。映射几个数字:
0-0
9-9
10-00
20-10
100-90
110-000
1110-0000
所以,模式很清楚。从单位的位置开始,如果一个数字小于10,它的表示与数字本身相同,否则您需要通过减去1来调整剩余的数字并递归。当数字小于10时可以停止。
同样的逻辑适用于上述解决方案中以26为基数的数字。
注:如果你想让数字从1开始,在输入数字减去1后调用相同的函数。