49

我试图将excel中的坐标值转换为openpyxl中的行号和列号。

例如,如果我的单元格坐标是 D4,我想找到相应的行号和列号以用于将来的操作,在这种情况下 row = 3,column = 3。我可以使用 ws.cell('D4').rowwhich 返回轻松获得行号,4那么这只是一个问题减 1。但是ws.cell('D4').column返回了一个类似的参数D,我不知道如何轻松地将其转换为 int 形式以进行后续操作。所以我求助于stackoverflow的聪明人。你能帮助我吗?

4

9 回答 9

76

你想要的是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]
于 2012-10-15T19:39:30.423 回答
69

openpyxl 有一个名为get_column_letter的函数,可以将数字转换为列字母。

from openpyxl.utils import get_column_letter
print(get_column_letter(1))

1 --> 一个

50 --> 斧头

第1234章

我一直在使用它:

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")

在此处输入图像描述

于 2015-11-08T20:30:46.957 回答
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()

Tl;博士有一堆评论......

# 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? ;)')
于 2015-10-26T20:46:27.040 回答
1

openpyxl.utils.cell模块中有一个方法可以满足所需的功能。方法openpyxl.utils.cell.coordinate_to_tuple()将字母数字 excel 坐标作为字符串作为输入,并将这些坐标作为整数元组返回。

openpyxl.utils.cell.coordinate_to_tuple('B1')
>> (1, 2)

这提供了使用指定库的更简洁的单行解决方案。

于 2021-12-28T17:46:49.130 回答
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]
于 2018-10-30T09:31:39.737 回答
0

它看起来像新版本的openpyxlsupport cell.col_idx,它为有问题的单元格提供从 1 开始的列号。

所以ws.cell('D4').col_idx应该给你 4 而不是D.

于 2021-03-04T18:34:12.967 回答
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)
于 2021-04-30T12:22:44.553 回答
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)
于 2021-05-28T11:36:05.567 回答
-4

你可以只使用纯 Python:

cell = "D4"
col = ord(cell[0]) - 65
row = int(cell[1:]) - 1

这使用了ord接受一个字符并返回其 ASCII 码的函数。在 ASCII 中,字母A是 65,B是 66,依此类推。

于 2012-10-15T19:29:16.780 回答