Translate a column index into an Excel Column Name

前端 未结 15 2229
花落未央
花落未央 2020-11-27 20:41

Given a columns\' index, how can you get an Excel column name?

The problem is trickier than it sounds because it\'s not just base-26. The columns

相关标签:
15条回答
  • 2020-11-27 20:54
    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);
            }
    
    
        }
    

    and the test:

    for (int i = 0; i < 100; i++) {
                System.out.println(i + ": " + translateColumnIndexToName(i));
    }
    

    here is the output:

    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
    

    I needed 0 based for POI

    and translation from index to names:

    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;
        }
    
    0 讨论(0)
  • 2020-11-27 20:59

    I enjoy writing recursive functions, but I don't think it's necessary here. This is my solution in VB. It works up to column ZZ. If someone can tell me if it works for AAA to ZZZ that would be nice to know.

    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 
    

    End Function

    0 讨论(0)
  • 2020-11-27 21:03

    The answer I came up with is to get a little recursive. This code is in 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
    

    And in 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'};
    

    The only downside it that it uses 1-indexed columns rather than 0-indexed.

    0 讨论(0)
  • 2020-11-27 21:03

    Here is my answer in C#, for translating both ways between column index and column name.

    /// <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;
    }
    
    0 讨论(0)
  • 2020-11-27 21:08
    # 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
    
    0 讨论(0)
  • 2020-11-27 21:09

    Here is my solution in 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;
    }
    
    0 讨论(0)
提交回复
热议问题