Get Excel-Style Column Names from Column Number

前端 未结 8 1564
慢半拍i
慢半拍i 2020-12-01 12:38

This is the code for providing the COLUMN name when the row and col ID is provided but when I give values like row = 1 and col = 104, it should return CZ<

相关标签:
8条回答
  • 2020-12-01 13:01

    Here's another way to get excel column names without a loop, using a pandas multiindex dataframe. This is a modification of a generalized base-to-base converter, so the code is a little lengthier than some of the other options, but I think it's effective:

    def xlcolumn(num):
        base = ["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"]
        baseln = len(base)
        idx = [""]+base
        num = num-1
    
        # create pandas multiindex using idx, base
        # current excel version has 16384 columns (A --> XFD), so multiindex needs to have a minimum of 3 levels:
        #   (26x26x26 = 17576 > 16384 columns) 
    
        index = pd.MultiIndex.from_product([idx, idx, idx],names=['level 1', 'level 2', 'level 3'])
        df = pd.DataFrame(index = index)
        df = df.drop("",level = 'level 3')
        df = df.iloc[:baseln].append(df.drop("",level = 'level 2'))
        df['val']=1
    
        if num < baseln:
            xlcol = str(df.iloc[num].name[2])
        elif num >= baseln and num < baseln**2:
            xlcol = str(df.iloc[num].name[1])+str(df.iloc[num].name[2])
        else:
            xlcol = str(df.iloc[num].name[0])+str(df.iloc[num].name[1])+str(df.iloc[num].name[2])
    
        return xlcol
    
    
    0 讨论(0)
  • 2020-12-01 13:02

    I think it is something like this :

    def get_col(col):
        """Get excel-style column names"""
        (div, mod) = divmod(col, 26)
        if div == 0:
            return str(unichr(mod+64))
        elif mod == 0:
            return str(unichr(div+64-1)+'Z')
        else:
            return str(unichr(div+64)+unichr(mod+64))
    

    Some tests :

    >>> def get_col(col):
    ...     (div, mod) = divmod(col, 26)
    ...     if div == 0:
    ...         return str(unichr(mod+64))
    ...     elif mod == 0:
    ...         return str(unichr(div+64-1)+'Z')
    ...     else:
    ...         return str(unichr(div+64)+unichr(mod+64))
    ... 
    >>> get_col(105)
    'DA'
    >>> get_col(104)
    'CZ'
    >>> get_col(1)
    'A'
    >>> get_col(55)
    'BC'
    
    0 讨论(0)
  • 2020-12-01 13:02

    I think i figured it out. divmod(104,26) gives mod=0 which makes chr(0+64) = 64 ie '@'.

    if i add this line before column_label "mod=26 if mod==0 else mod" i think it should work fine

    column_label=''
    div=104
    while div:
        (div, mod) = divmod(div, 26)
        mod=26 if mod==0 else mod
        column_label = chr(mod + 64) + column_label
    
    print column_label
    
    0 讨论(0)
  • 2020-12-01 13:10

    use this code:

    def xlscol(colnum):
        a = []
        while colnum:
            colnum, remainder = divmod(colnum - 1, 26)
            a.append(remainder)
        a.reverse()
        return ''.join([chr(n + ord('A')) for n in a])
    
    0 讨论(0)
  • 2020-12-01 13:15

    I love maritineau's answer since its code looks plain and easy to follow. But it can't handle the column number which is greater than 26**2 + 26. So I modify part of it.

    def excel_col(col):
        """Covert 1-relative column number to excel-style column label."""
        quot, rem = divmod(col-1,26)
        return excel_col(quot) + chr(rem+ord('A')) if col!=0 else ''
    
    
    
    if __name__=='__main__':
        for i in [1, 26, 27, 26**3+26**2+26]:
            print 'excel_col({0}) -> {1}'.format(i, excel_col(i))
    

    Results

    excel_col(1) -> A
    excel_col(26) -> Z
    excel_col(27) -> AA
    excel_col(18278) -> ZZZ
    
    0 讨论(0)
  • 2020-12-01 13:21
    def ColNum2ColName(n):
       convertString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
       base = 26
       i = n - 1
    
       if i < base:
          return convertString[i]
       else:
          return ColNum2ColName(i//base) + convertString[i%base]
    

    EDIT: Right, right zondo.

    I just approached A, B, .. AA, AB, ... as a numeric base with digits A-Z.

    A = 1
    B = 2
     .
     .
    X = 24
    Y = 25
    Z = 26
     .
     .
     .
    

    It's an easy way without any while loop etc. and works for any number > 0.

    0 讨论(0)
提交回复
热议问题