我正在尝试将excel中的坐标值转换为openpyxl中的行号和列号。
例如,如果我的单元格坐标为D4,我想找到用于将来操作的相应行号和列号,在行= 3,列= 3的情况下,我可以使用{{1}轻松获取行号返回ws.cell('D4').row
然后它只是减去1的问题。但是类似的参数4
返回ws.cell('D4').column
并且我不知道如何轻松地将其转换为int形式以用于后续操作。所以我向你转向stackoverflow的聪明人。你能救我吗?
答案 0 :(得分:42)
您想要的是openpyxl.utils.coordinate_from_string()
和openpyxl.utils.column_index_from_string()
from openpyxl.utils.cell import coordinate_from_string, column_index_from_string
xy = coordinate_from_string('A4') # returns ('A',4)
col = column_index_from_string(xy[0]) # returns 1
row = xy[1]
答案 1 :(得分:36)
openpyxl有一个名为 get_column_letter 的函数,可以将数字转换为列字母。
from openpyxl.utils import get_column_letter
print(get_column_letter(1))
1 - >甲
50 - > AX
1234-- AUL
我一直在使用它:
from openpyxl import Workbook
from openpyxl.utils import get_column_letter
#create excel type item
wb = Workbook()
# select the active worksheet
ws = wb.active
counter = 0
for column in range(1,6):
column_letter = get_column_letter(column)
for row in range(1,11):
counter = counter +1
ws[column_letter + str(row)] = counter
wb.save("sample.xlsx")
答案 2 :(得分:3)
这是建立在内森的回答之上的。基本上,当行和/或列超过一个字符宽时,他的答案无法正常工作。对不起 - 我去了一点。这是完整的脚本:
def main():
from sys import argv, stderr
cells = None
if len(argv) == 1:
cells = ['Ab102', 'C10', 'AFHE3920']
else:
cells = argv[1:]
from re import match as rematch
for cell in cells:
cell = cell.lower()
# generate matched object via regex (groups grouped by parentheses)
m = rematch('([a-z]+)([0-9]+)', cell)
if m is None:
from sys import stderr
print('Invalid cell: {}'.format(cell), file=stderr)
else:
row = 0
for ch in m.group(1):
# ord('a') == 97, so ord(ch) - 96 == 1
row += ord(ch) - 96
col = int(m.group(2))
print('Cell: [{},{}] '.format(row, col))
if __name__ == '__main__':
main()
# make cells with multiple characters in length for row/column
# feel free to change these values
cells = ['Ab102', 'C10', 'AFHE3920']
# import regex
from re import match as rematch
# run through all the cells we made
for cell in cells:
# make sure the cells are lower-case ... just easier
cell = cell.lower()
# generate matched object via regex (groups grouped by parentheses)
############################################################################
# [a-z] matches a character that is a lower-case letter
# [0-9] matches a character that is a number
# The + means there must be at least one and repeats for the character it matches
# the parentheses group the objects (useful with .group())
m = rematch('([a-z]+)([0-9]+)', cell)
# if m is None, then there was no match
if m is None:
# let's tell the user that there was no match because it was an invalid cell
from sys import stderr
print('Invalid cell: {}'.format(cell), file=stderr)
else:
# we have a valid cell!
# let's grab the row and column from it
row = 0
# run through all of the characters in m.group(1) (the letter part)
for ch in m.group(1):
# ord('a') == 97, so ord(ch) - 96 == 1
row += ord(ch) - 96
col = int(m.group(2))
# phew! that was a lot of work for one cell ;)
print('Cell: [{},{}] '.format(row, col))
print('I hope that helps :) ... of course, you could have just used Adam\'s answer,\
but that isn\'t as fun, now is it? ;)')
答案 3 :(得分:0)
旧话题,但答案不正确!
dylnmc 方法是一种很好的方法,但是存在一些错误。像“ AA1”或“ AAB1”这样的单元格坐标的计算行不正确。
下面是作为功能的更正版本。
注意::此函数返回实坐标。例如,如果要在ExcelWriter中使用它,则ROW和COL都应减一。因此,将最后一行替换为 return(row-1,col-1)
例如,“ AA1”为[1,27],而“ AAA1”为[1,703];但是python必须将它们分别设置为[0,26]和[0,702]。
import re
def coord2num(coord):
cell = coord.lower()
# generate matched object via regex (groups grouped by parentheses)
m = re.match('([a-z]+)([0-9]+)', cell)
if m is None:
print('Invalid cell: {}'.format(cell))
return [None,None]
else:
col = 0
for i,ch in enumerate(m.group(1)[::-1]):
n = ord(ch)-96
col+=(26**i)*(n)
row = int(m.group(2))
return[row,col]
答案 4 :(得分:0)
新版本的 openpyxl
似乎支持 cell.col_idx
,它为相关单元格提供了一个从 1 开始的列号。
所以 ws.cell('D4').col_idx
应该给你 4 而不是 D
。
答案 5 :(得分:0)
这将给出列号
col = "BHF"
num = 0
for i in range(len(col)):
num = num + (ord(col[i]) - 64) * pow(26, len(col) - 1 - i)
print(num)
答案 6 :(得分:0)
如果你想在不使用任何库的情况下做到这一点:
def col_row(s):
""" 'AA13' -> (27, 13) """
def col_num(col):
""" 'AA' -> 27 """
s = 0
for i, char in enumerate(reversed(col)):
p = (26 ** i)
s += (1 + ord(char.upper()) - ord('A')) * p
return s
def split_A1(s):
""" 'AA13' -> (AA, 13) """
for i, char in enumerate(s):
if char.isdigit():
return s[:i], int(s[i:])
col, row = split_A1(s)
return col_num(col), row
col_row('ABC13')
# Out[124]: (731, 13)
答案 7 :(得分:-4)
你可以使用纯Python:
cell = "D4"
col = ord(cell[0]) - 65
row = int(cell[1:]) - 1
这使用ord
函数,它接受一个字符并返回其ASCII码。在ASCII中,字母A
为65,B
为66,依此类推。