xlrd

import xlrd
from re import search
from random import randint


# -----------------------------------------------------------------------------
def open(file_path):
	"""
	NAME:   open <- OPEN excel file
	INPT:   Отримує адресу file_path xls-файлу, відкриває його
	OUTP:   Повертає посилання на першу сторінку Sheet1
	NOTE:   ! Тільки для першого листа !

	EXAMPLE:
			sheet1 = _xl.open(path_to_xls_file)
	"""

	book = xlrd.open_workbook(file_path)

	return book.sheet_by_index(0)  # Sheet1


# -----------------------------------------------------------------------------
def col_by_name(colname):
	"""'A' -> 0, 'Z' -> 25, 'AA' -> 26, etc
		From xlwt.Utils
	"""
	col = 0
	power = 1
	for i in range(len(colname)-1, -1, -1):
		ch = colname[i]
		col += (ord(ch) - ord('A') + 1) * power
		power *= 26
	return col - 1


# -----------------------------------------------------------------------------
def cell_abs(addr, type=0):
	"""
	NAME:   cell_abs <- eXcel get CELL ABSolute address
	INPT:   Отримує адресу комірки у вигляді 'літера'+'число'
	OUTP:   Повертає абсолютні координати комірки (число,число) у вигляді:
				type = 0 - кортеж
				type = інше_значення - словник
	NOTE:   ! Тільки для літер A...Z !

	EXAMPLE:
			(row, col) = _xl.cell_abs('A20')  # (0, 19)
			_xl.dict = cell_abs('C15',1)   # {rowx: 2, colx: 14}
	"""

	res = search('^([A-Z]{1,})(\d{1,2})$', addr)

	if res:
		col = res.group(1)  # letter
		row = res.group(2)  # digit
	else:
		return None

	# col = ord(col) - 65   # моя реалізація для 1ї літери (65 - це код латинської літери 'A')
	col = col_by_name(col)  # реалізація з xlwt.Utils
	row = int(row) - 1      # в модулі xlrd рядки починаються з нуля 0

	if type == 0:
		return (row, col)
	else:
		return {rowx: row, colx: col}


# -----------------------------------------------------------------------------
def rows_cols(addr_beg, addr_end):
	"""
	NAME:   rows_cols <- ROWS & COLS count
	INPT:   Отримує діапазон комірок, що заданий двома адресами у вигляді
			'літера'+'число'
	OUTP:   Повертає кількість рядків і колонок

	EXAMPLE:
			(rows, cols) = _xl.rows_cols('B21', 'G26')  # (6, 6)
	"""
	(row_beg, col_beg) = cell_abs(addr_beg)
	(row_end, col_end) = cell_abs(addr_end)

	return (row_end - row_beg + 1, col_end - col_beg + 1)

# -----------------------------------------------------------------------------
def cell_val(sheet, addr):
	"""
	NAME:   cell_val <- eXcel get CELL VALue
	INPT:   Отримує адресу комірки у вигляді 'літера'+'число'
				sheet - лист Excel
				addr - адреса
	OUTP:   Повертає значення комірки у вигляді

	EXAMPLE:
			_xl.cell_value = cell_val(sh,'B2')
			!!! Здається, в незалежності від формату комірки (текст, число, цифр після коми)
			повертається число, якщо в комірці цифри (причому, float) '22' -> 22.0
			і текст, якщо є літери.
	"""

	(row, col) = cell_abs(addr)

	val = sheet.cell_value(rowx=row, colx=col)

	return val


# -----------------------------------------------------------------------------
def cells_vals(sheet, addr_beg, addr_end):
	"""
	NAME:   cells_vals <- eXcel get CELLS VALueS range
	INPT:   Отримує діапазон комірок, що заданий двома адресами у вигляді
			'літера'+'число'
				sheet - лист Excel
				addr_beg - початкова адреса
				addr_end - кінцева адреса
	OUTP:   Повертає список списків значень комірок по рядкам і колонкам
			заданого діапазона

	EXAMPLE:
			lists = _xl.cells_vals_range(sh, 'A5', 'F15')
	"""

	(row_beg, col_beg) = cell_abs(addr_beg)
	(row_end, col_end) = cell_abs(addr_end)

	l = list()
	ll = list()

	current_row = row_beg
	for row in range(row_beg, row_end+1):
		if current_row != row:
			l.append(ll)
			current_row += 1
			ll = list()
		for col in range(col_beg, col_end+1):
			ll.append(round(sheet.cell_value(rowx=row, colx=col),2))

	l.append(ll)

	return l

Last updated