web-dev-qa-db-ja.com

openpyxlの座標値から行番号と列番号を取得する

Excelの座標値をopenpyxlの行番号と列番号に変換しようとしています。

たとえば、セル座標がD4である場合、行= 3、列= 3の場合、将来の操作に使用する対応する行番号と列番号を検索します。ws.cell('D4').rowを使用して行番号を簡単に取得できます_4_を返す場合は、1を引くだけです。しかし、同様の引数ws.cell('D4').columnDを返します。操作。だから私はあなたに賢明なスタックオーバーフローの人々に目を向ける。手伝って頂けますか?

32
A Alstone

欲しいのは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]
48
Adam Morris

openpyxlには、番号を列文字に変換するget_column_letterという関数があります。

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

1-> A

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

enter image description here

40
Ohm

これは、ネイサンの答えに基づいています。基本的に、彼の答えは、行および/または列が複数の文字幅である場合、正しく機能しません。すみません-私は少し船に乗りました。完全なスクリプトは次のとおりです。

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; drとコメントの束...

# 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
dylnmc

古いトピックですが、答えは正しくありません!

dylnmcメソッドは良い方法でしたが、いくつかのエラーがあります。 「AA1」や「AAB1」などのセル座標の計算された行は正しくありません。

以下は関数として修正されたバージョンです。

注:この関数は調整された実数を返します。たとえばExcelWriterで使用する場合は、ROWとCOLの両方を1つ差し引く必要があります。したがって、最後の行を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]
0
Mehdi