python - salida - obteniendo los números de fila y columna del valor de coordenadas en openpyxl
recorrer excel en python (5)
Estoy tratando de convertir un valor de coordenadas en excel a un número de fila y número de columna en openpyxl.
Por ejemplo, si la coordenada de mi celda es D4, quiero encontrar los números de fila y columna correspondientes para usar en futuras operaciones, en el caso fila = 3, columna = 3. Puedo obtener el número de fila fácilmente usando ws.cell(''D4'').row
que devuelve 4
, es solo una cuestión de restar 1. Pero un argumento similar ws.cell(''D4'').column
devuelve D
y no sé cómo ws.cell(''D4'').column
esto fácilmente en forma int para operaciones posteriores. Así que me dirijo a ustedes, amigos sabios de stackoverflow. ¿Me puedes ayudar?
Esto se está construyendo a partir de la respuesta de Nathan. Básicamente, su respuesta no funciona correctamente cuando la fila y / o columna tiene más de un carácter de ancho. Lo siento, me fui un poco por la borda. Aquí está el script completo:
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 con un montón de comentarios ...
# 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? ;)'')
Lo que quieres es openpyxl.utils.coordinate_from_string()
y openpyxl.utils.column_index_from_string()
from openpyxl.utils 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]
Usted podría simplemente usar Python puro:
cell = "D4"
col = ord(cell[0]) - 65
row = int(cell[1:]) - 1
Esto utiliza la función ord
que toma un carácter y devuelve su código ASCII. En ASCII, la letra A
es 65, B
es 66 y así sucesivamente.
Viejo tema, pero la respuesta no es correcta!
El método dylnmc fue bueno, pero tiene algunos errores. La fila calculada para coords celulares como "AA1" o "AAB1" no es correcta.
A continuación se muestra la versión corregida como una función.
NOTA: Esta función devuelve lo real coordinado. Si desea usarlo, por ejemplo, en ExcelWriter, tanto ROW como COL deben deducirse por uno. Así que reemplace la última línea con retorno (fila-1, col-1)
Por ejemplo, ''AA1'' es [1,27] y ''AAA1'' es [1,703]; pero el pitón debe tenerlos como [0,26] y [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]
openpyxl tiene una función llamada get_column_letter que convierte un número en una letra de columna.
from openpyxl.utils import get_column_letter
print(get_column_letter(1))
1 -> A
50 -> AX
1234-- AUL
Lo he estado usando como:
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")