以Python方式将excel或电子表格列字母转换为数字

以Python方式将excel或电子表格列字母转换为数字,python,excel,google-sheets,python-2.x,Python,Excel,Google Sheets,Python 2.x,是否有一种更具python风格的方式将excel样式的列转换为数字(从1开始) 工作代码最多两个字母: def列到编号(c): “”“返回与excel样式列对应的编号。”“” 数字=-25 对于c中的l: 如果不是string.ascii_字母中的l: 返回错误 数字+=ord(l.upper())-64+25 返回号码 代码运行: >>列到列编号('2') 假的 >>>列到列编号('A') 1. >>>列至列编号('AB') 28 三封信不起作用 >>列到列编号(“ABA”) 54 >>>

是否有一种更具python风格的方式将excel样式的列转换为数字(从1开始)

工作代码最多两个字母:

def列到编号(c):
“”“返回与excel样式列对应的编号。”“”
数字=-25
对于c中的l:
如果不是string.ascii_字母中的l:
返回错误
数字+=ord(l.upper())-64+25
返回号码
代码运行:

>>列到列编号('2')
假的
>>>列到列编号('A')
1.
>>>列至列编号('AB')
28
三封信不起作用

>>列到列编号(“ABA”)
54
>>>列至列编号(“AAB”)
54

参考资料:

在VBA中,这应该可以满足您的需要:

函数columnNumber(colLetter作为字符串)作为整数
Dim colNumber作为整数
作为整数的Dim i
colLetter=UCase(colLetter)
colNumber=0
对于i=1至Len(夹头)
colNumber=colNumber+(Asc(Mid(colLetter,Len(colLetter)-i+1,1))-64)*26^(i-1)
下一个
columnNumber=columnNumber
端函数
您可以像使用Excel公式一样使用它——以字母形式输入列作为字符串(例如,“AA”),并且无论列的长度如何,都应该可以工作


在处理三个字母时,您的代码会中断,因为您的计算方式——您需要使用base 26。

我不确定自己是否理解正确,是否要将引用的C代码“翻译”为python?如果是这样的话,你就走上了正确的道路;只需将其修改为:

def列到编号(c):
“”“返回与excel样式列对应的编号。”“”
总和=0
对于c中的l:
如果不是string.ascii_字母中的l:
返回错误
总和*=26
sum+=ord(l.upper())-64
回报金额

有一种方法可以让它更具python风格(使用三个或更多字母,使用更少的幻数):

作为使用reduce的一行程序(不检查输入,可读性较差,所以我不推荐):

只要做:

print ws.Range("E2").Column
呼叫示例:

from win32com import client
xl = client.Dispatch("Excel.Application")
wb = xl.Workbooks.Open("c:/somePath/file.xls")
xl.Visible = 1
ws = wb.Sheets("sheet 1")
print ws.Range("E2").Column
结果:

>>5

这里有一种方法。它是模块中代码的变体:


读完这篇文章后,我决定找到一种方法,直接在Excel单元格中执行此操作。它甚至可以解释Z之后的列

只要将这个公式粘贴到任何列的任何行的单元格中,它就会给出相应的数字

=IF(LEN(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))=2,
 CODE(LEFT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1))-64*26)+
 CODE(RIGHT(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""),1)-64),
 CODE(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4),ROW(),""))-64)
这里的主题是抓住该列的字母,根据字母
A
的ASCII字符代码是64这一事实,获取该列的
code()
,然后减去64

import openpyxl
(column_string, row) = openpyxl.cell.coordinate_from_string(address)
column = openpyxl.cell.column_index_from_string(column_string) 

简洁优雅的Ruby版本:

def col_num(col_name)
    col_name.split(//).inject(0) { |n, c| n * 26 + c.upcase.ord - "A".ord + 1 }
end

对于从零开始的索引(例如A=0、B=1等):

我做了一行:

colNameToNum = lambda cn: sum([((ord(cn[-1-pos]) - 64) * 26 ** pos) for pos in range(len(cn))])
它的工作原理是以相反的顺序遍历字母,然后乘以1、26、26*26等,然后对列表求和。这种方法也适用于较长的字母字符串

我称之为:

印刷品(Colnametonium(“AA”))#27


打印(colNameToNum(“XFD”)#我相信是允许的最高列。Result=16384

您可以使用理解和字符串来使用此oneliner,这非常容易使用:

sum([string.ascii_lowercase.index(c) + 26 ** i for i,c in enumerate(col_letters)])
在Python 2.7.1和3.5.2中测试的单行程序 所有测试都打印出来
在安装openpyxl模块后,您可以将以下内容添加到控制台:

import openpyxl
from openpyxl.utils import get_column_letter, column_index_from_string
workbook = openpyxl.load_workbook('your_workbook.xlsx')
sheet = wb.get_sheet_by_name('your_sheet_from_workbook')
print(get_column_letter(1))
print(column_index_from_string('A'))
只需更改字母和数字以满足您的需要,或者创建一个for循环来完成整个项目的工作。我希望这有帮助。干杯

以下是我使用的内容(在找到此页面之前写下):

还有一些跑步:

>>> col_to_index('A')
1
>>> col_to_index('AB')
28
>>> col_to_index('ABCD')
19010
使用:

这一衬里由几个部分组成,因此解释如下:

column\u id[:-1]
:反转字符串,例如将
'AZ'
转换为
'ZA'
,这样做有一个很好的理由,稍后我们将看到

enumerate()
:生成一个iterable,例如
(0,'Z'),(1,'a')

通过一些观察:

 A -> 1  = (26**0)*1              # ** is the exponential operator
 B -> 2  = (26**0)*2 
 Z -> 26 = (26**0)*26
AA -> 27 = (26**0)*1  + (26**1)*1
AB -> 28 = (26**0)*2  + (26**1)*1
AZ -> 52 = (26**0)*26 + (26**1)*1  # recall that we have (0, 'Z'), (1, 'A')
颠倒
列\u id
枚举()
允许我们使用索引作为26的指数。剩下的就无关紧要了

字母。索引(j)
:为我们提供
字母中字母的索引


sum()
:获取数字列表并返回总数。

您也可以通过一系列乘法和加法来完成此操作,如下所示。此处“A”将等于
1
。运行时间是
O(n)
其中
n
是列的长度,
col

import functools
def spreadsheet_column_encoding(col):
    return functools.reduce(
        lambda result, char: result * 26 + ord(char) - ord("A") + 1, col, 0
    )
例如
ZZ
=
702

0 * 26 + 90 - 65 + 1 = 26
26 * 26 + 90 - 65 + 1 = 702
附言:
ord('Z')=90


若要将数字转换为列字母,请参阅我的答案。您可以使用除法和模计算进行相反的操作。

这里是一个递归解决方案:

def column_string_to_num(s):
    n = ord(s[-1]) - 64
    if s[:-1]:
        return 26 * (column_string_to_num(s[:-1])) + n
    else:
        return n
    
column_string_to_num("AB")
#output: 28
也可以用类似的方式递归定义逆:

def column_num_to_string(n):
    n, rem = divmod(n - 1, 26)
    next_char = chr(65 + rem)
    if n:
        return column_string(n) + next_char
    else:
        return next_char

column_num_to_string(28)
#output: 'AB'

那么,如何返回到另一个方向呢?要返回到另一个方向,请参阅@Devon的答案,使用这个函数:这有点像从一串数字中计算整数值。除了这里的基数是26,而不是10,这个问题与Ruby无关。
import openpyxl
from openpyxl.utils import get_column_letter, column_index_from_string
workbook = openpyxl.load_workbook('your_workbook.xlsx')
sheet = wb.get_sheet_by_name('your_sheet_from_workbook')
print(get_column_letter(1))
print(column_index_from_string('A'))
def col_to_index(col):
    return sum((ord(c) - 64) * 26**i for i, c in enumerate(reversed(col))) - 1
>>> col_to_index('A')
1
>>> col_to_index('AB')
28
>>> col_to_index('ABCD')
19010
LETTERS = list(string.ascii_uppercase)
def column_number(column_id):
    return sum([(LETTERS.index(j)+1)*(26**i) for i,j in enumerate(column_id[::-1])])
 A -> 1  = (26**0)*1              # ** is the exponential operator
 B -> 2  = (26**0)*2 
 Z -> 26 = (26**0)*26
AA -> 27 = (26**0)*1  + (26**1)*1
AB -> 28 = (26**0)*2  + (26**1)*1
AZ -> 52 = (26**0)*26 + (26**1)*1  # recall that we have (0, 'Z'), (1, 'A')
import functools
def spreadsheet_column_encoding(col):
    return functools.reduce(
        lambda result, char: result * 26 + ord(char) - ord("A") + 1, col, 0
    )
0 * 26 + 90 - 65 + 1 = 26
26 * 26 + 90 - 65 + 1 = 702
def column_string_to_num(s):
    n = ord(s[-1]) - 64
    if s[:-1]:
        return 26 * (column_string_to_num(s[:-1])) + n
    else:
        return n
    
column_string_to_num("AB")
#output: 28
def column_num_to_string(n):
    n, rem = divmod(n - 1, 26)
    next_char = chr(65 + rem)
    if n:
        return column_string(n) + next_char
    else:
        return next_char

column_num_to_string(28)
#output: 'AB'