给定列索引,如何获得Excel列名?
这个问题比听起来更棘手,因为它只是而不是只是基数为26。列不像普通数字那样换行。即使Microsoft Support Example也不会超出ZZZ。
免责声明:这是我之前做过的一些代码,今天再次遇到了我的桌面。我认为值得在这里作为预先回答的问题发布。
答案 0 :(得分:19)
我想出的答案是获得一点递归。这段代码在VB.Net中:
Function ColumnName(ByVal index As Integer) As String
Static chars() As Char = {"A"c, "B"c, "C"c, "D"c, "E"c, "F"c, "G"c, "H"c, "I"c, "J"c, "K"c, "L"c, "M"c, "N"c, "O"c, "P"c, "Q"c, "R"c, "S"c, "T"c, "U"c, "V"c, "W"c, "X"c, "Y"c, "Z"c}
index -= 1 ''//adjust so it matches 0-indexed array rather than 1-indexed column
Dim quotient As Integer = index \ 26 ''//normal / operator rounds. \ does integer division, which truncates
If quotient > 0 Then
ColumnName = ColumnName(quotient) & chars(index Mod 26)
Else
ColumnName = chars(index Mod 26)
End If
End Function
在C#中:
string ColumnName(int index)
{
index -= 1; //adjust so it matches 0-indexed array rather than 1-indexed column
int quotient = index / 26;
if (quotient > 0)
return ColumnName(quotient) + chars[index % 26].ToString();
else
return chars[index % 26].ToString();
}
private char[] chars = new char[] {'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'};
唯一的缺点是它使用1索引列而不是0索引。
答案 1 :(得分:18)
这是Joel的令人敬畏的代码,它被修改为使用基于零的列索引并且没有char数组。
Public Shared Function GetExcelColumn(ByVal index As Integer) As String
Dim quotient As Integer = index \ 26 ''//Truncate
If quotient > 0 Then
Return GetExcelColumn(quotient - 1) & Chr((index Mod 26) + 64).ToString
Else
Return Chr(index + 64).ToString
End If
End Function
答案 2 :(得分:8)
正是出于这个原因,我在Excel的编程接口中避免了列名。使用数字列可以很好地处理Cell(r,c)引用和R1C1寻址。
EDIT:Range函数也采用单元格引用,如Range(Cell(r1,c1),Cell(r2,c2))。此外,您可以使用地址功能获取单元格或范围的A1样式地址。
EDIT2:这是一个VBA函数,它使用Address()函数来检索列名:
Function colname(colindex)
x = Cells(1, colindex).Address(False, False) ' get the range name (e.g. AB1)
colname = Mid(x, 1, Len(x) - 1) ' return all but last character
End Function
答案 3 :(得分:4)
# Python 2.x, no recursive function calls
def colname_from_colx(colx):
assert colx >= 0
colname = ''
r = colx
while 1:
r, d = divmod(r, 26)
colname = chr(d + ord('A')) + colname
if not r:
return colname
r -= 1
答案 4 :(得分:4)
public static String translateColumnIndexToName(int index) {
//assert (index >= 0);
int quotient = (index)/ 26;
if (quotient > 0) {
return translateColumnIndexToName(quotient-1) + (char) ((index % 26) + 65);
} else {
return "" + (char) ((index % 26) + 65);
}
}
和测试:
for (int i = 0; i < 100; i++) {
System.out.println(i + ": " + translateColumnIndexToName(i));
}
这是输出:
0: A
1: B
2: C
3: D
4: E
5: F
6: G
7: H
8: I
9: J
10: K
11: L
12: M
13: N
14: O
15: P
16: Q
17: R
18: S
19: T
20: U
21: V
22: W
23: X
24: Y
25: Z
26: AA
27: AB
28: AC
我需要0基于POI
并从索引到名称的翻译:
public static int translateComunNameToIndex0(String columnName) {
if (columnName == null) {
return -1;
}
columnName = columnName.toUpperCase().trim();
int colNo = -1;
switch (columnName.length()) {
case 1:
colNo = (int) columnName.charAt(0) - 64;
break;
case 2:
colNo = ((int) columnName.charAt(0) - 64) * 26 + ((int) columnName.charAt(1) - 64);
break;
default:
//illegal argument exception
throw new IllegalArgumentException(columnName);
}
return colNo;
}
答案 5 :(得分:3)
这是一篇旧帖子,但在看到一些解决方案之后,我想出了自己的C#变体。基于0,没有递归:
public static String GetExcelColumnName(int columnIndex)
{
if (columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex: " + columnIndex);
}
Stack<char> stack = new Stack<char>();
while (columnIndex >= 0)
{
stack.Push((char)('A' + (columnIndex % 26)));
columnIndex = (columnIndex / 26) - 1;
}
return new String(stack.ToArray());
}
以下是关键转换点的一些测试结果:
0: A
1: B
2: C
...
24: Y
25: Z
26: AA
27: AB
...
50: AY
51: AZ
52: BA
53: BB
...
700: ZY
701: ZZ
702: AAA
703: AAB
答案 6 :(得分:1)
php版本,感谢这篇帖子帮我弄明白! ^^
/**
* Get excel column name
* @param index : a column index we want to get the value in excel column format
* @return (string) : excel column format
*/
function getexcelcolumnname($index) {
//Get the quotient : if the index superior to base 26 max ?
$quotient = $index / 26;
if ($quotient >= 1) {
//If yes, get top level column + the current column code
return getexcelcolumnname($quotient-1). chr(($index % 26)+65);
} else {
//If no just return the current column code
return chr(65 + $index);
}
}
答案 7 :(得分:1)
JavaScript解决方案
/**
* Calculate the column letter abbreviation from a 0 based index
* @param {Number} value
* @returns {string}
*/
getColumnFromIndex = function (value) {
var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
value++;
var remainder, result = "";
do {
remainder = value % 26;
result = base[(remainder || 26) - 1] + result;
value = Math.floor(value / 26);
} while (value > 0);
return result;
};
答案 8 :(得分:1)
在python中,带递归。从Joey的answer翻译而来。到目前为止,经过测试可以达到GetExcelByColumn(35)='AI'
def GetExcelColumn(index):
quotient = int(index / 26)
if quotient > 0:
return GetExcelColumn(quotient) + str(chr((index % 26) + 64))
else:
return str(chr(index + 64))
答案 9 :(得分:0)
我喜欢编写递归函数,但我不认为这是必要的。这是我在VB中的解决方案。它适用于ZZ列。如果有人能告诉我它是否适用于AAA到ZZZ,那将是一件好事。
Public Function TranslateColumnIndexToName(index As Integer) As String
'
Dim remainder As Integer
Dim remainder2 As Integer
Dim quotient As Integer
Dim quotient2 As Integer
'
quotient2 = ((index) / (26 * 26)) - 2
remainder2 = (index Mod (26 * 26)) - 1
quotient = ((remainder2) / 26) - 2
remainder = (index Mod 26) - 1
'
If quotient2 > 0 Then
TranslateColumnIndexToName = ChrW(quotient2 + 65) & ChrW(quotient + 65) & ChrW(remainder + 65)
ElseIf quotient > 0 Then
TranslateColumnIndexToName = ChrW(quotient + 65) & ChrW(remainder + 65)
Else
TranslateColumnIndexToName = ChrW(remainder + 65)
End If
结束功能
答案 10 :(得分:0)
这是我在C#中的解决方案
// test
void Main()
{
for( var i = 0; i< 1000; i++ )
{ var byte_array = code( i );
Console.WriteLine("{0} | {1} | {2}", i, byte_array, offset(byte_array));
}
}
// Converts an offset to AAA code
public string code( int offset )
{
List<byte> byte_array = new List<byte>();
while( offset >= 0 )
{
byte_array.Add( Convert.ToByte(65 + offset % 26) );
offset = offset / 26 - 1;
}
return ASCIIEncoding.ASCII.GetString( byte_array.ToArray().Reverse().ToArray());
}
// Converts AAA code to an offset
public int offset( string code)
{
var offset = 0;
var byte_array = Encoding.ASCII.GetBytes( code ).Reverse().ToArray();
for( var i = 0; i < byte_array.Length; i++ )
{
offset += (byte_array[i] - 65 + 1) * Convert.ToInt32(Math.Pow(26.0, Convert.ToDouble(i)));
}
return offset - 1;
}
答案 11 :(得分:0)
以下是我在C#中的答案,用于在列索引和列名之间进行两种转换。
/// <summary>
/// Gets the name of a column given the index, as it would appear in Excel.
/// </summary>
/// <param name="columnIndex">The zero-based column index number.</param>
/// <returns>The name of the column.</returns>
/// <example>Column 0 = A, 26 = AA.</example>
public static string GetColumnName(int columnIndex)
{
if (columnIndex < 0) throw new ArgumentOutOfRangeException("columnIndex", "Column index cannot be negative.");
var dividend = columnIndex + 1;
var columnName = string.Empty;
while (dividend > 0)
{
var modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo) + columnName;
dividend = (dividend - modulo) / 26;
}
return columnName;
}
/// <summary>
/// Gets the zero-based column index given a column name.
/// </summary>
/// <param name="columnName">The column name.</param>
/// <returns>The index of the column.</returns>
public static int GetColumnIndex(string columnName)
{
var index = 0;
var total = 0;
for (var i = columnName.Length - 1; i >= 0; i--)
total += (columnName.ToUpperInvariant()[i] - 64) * (int)Math.Pow(26, index++);
return total - 1;
}
答案 12 :(得分:0)
在Ruby中:
class Fixnum
def col_name
quot = self/26
(quot>0 ? (quot-1).col_name : "") + (self%26+65).chr
end
end
puts 0.col_name # => "A"
puts 51.col_name # => "AZ"
答案 13 :(得分:0)
此JavaScript版本显示其核心是转换为基础26:
function colName(x)
{
x = (parseInt("ooooooop0", 26) + x).toString(26);
return x.slice(x.indexOf('p') + 1).replace(/./g, function(c)
{
c = c.charCodeAt(0);
return String.fromCharCode(c < 64 ? c + 17 : c - 22);
});
}
.toString(26)
位表明Joel Coehoorn错了:这是一个简单的基本转换。
(注意:基于Dana在生产中的答案,我有一个更直接的实现。它不那么沉重,适用于较大的数字,虽然这不会影响我,但也没有明确表示数学原理。)
P.S。这是在重要点评估的功能:
0 A
1 B
9 J
10 K
24 Y
25 Z
26 AA
27 AB
700 ZY
701 ZZ
702 AAA
703 AAB
18276 ZZY
18277 ZZZ
18278 AAAA
18279 AAAB
475252 ZZZY
475253 ZZZZ
475254 AAAAA
475255 AAAAB
12356628 ZZZZY
12356629 ZZZZZ
12356630 AAAAAA
12356631 AAAAAB
321272404 ZZZZZY
321272405 ZZZZZZ
321272406 AAAAAAA
321272407 AAAAAAB
8353082580 ZZZZZZY
8353082581 ZZZZZZZ
8353082582 AAAAAAAA
8353082583 AAAAAAAB
答案 14 :(得分:0)
这是Swift 4:
@IBAction func printlaction(_ sender: Any) {
let textN : Int = Int (number_textfield.text!)!
reslut.text = String (printEXCL_Letter(index: textN))
}
func printEXCL_Letter(index : Int) -> String {
let letters = ["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"]
var index = index;
index -= 1
let index_div = index / 26
if (index_div > 0){
return printEXCL_Letter(index: index_div) + letters[index % 26];
}
else {
return letters[index % 26]
}
}