AutoFramework/Base/Class/Excel.py

242 lines
8.8 KiB
Python

import os, re, openpyxl
from openpyxl.utils import get_column_letter, column_index_from_string
def colIndexFromString(string):
return column_index_from_string(string) - 1
def rowIndexFromString(string):
return int(string) - 1
class Excel:
__readonly__ = None
__autosave__ = None
__filename__ = None
__workbook__ = None
__workshet__ = None
def open(self, filename=None, sheet=None, read_only=False, auto_save=False):
"""打开Excel文档 | Open Excel document.
:param filename: 将要打开的Excel文档的文件路径 | The file path of the Excel document that will be opened.
:param sheet: 将要打开的工作表名称或索引,默认为当前活动工作表 | The name or index of the worksheet to open, defaults to the currently active worksheet.
:param read_only: 只读模式 | Read-only mode.
:param auto_save: 自动保存 | Auto save when modified.
:return:
"""
self.__readonly__ = read_only
if self.__workbook__:
raise Exception('文件已经打开 | File has been opened.')
self.__filename__ = os.path.abspath(filename)
self.__workbook__ = openpyxl.load_workbook(filename, read_only=read_only)
self.select(sheet)
self.__autosave__ = auto_save
return self
def select(self, sheet):
"""选择活动工作表 | Select active worksheet.
:param sheet: 工作表名称或索引或工作表对象,默认为当前活动工作表 | Sheet name or index or sheet object, defaults to the currently active sheet.
:return:
"""
if isinstance(sheet, int):
self.__workshet__ = self.__workbook__[self.sheetList()[sheet]]
elif isinstance(sheet, str):
self.__workshet__ = self.__workbook__[sheet]
elif not sheet:
self.__workshet__ = self.__workbook__.active
else:
self.__workshet__ = sheet
if not self.__readonly__:
self.__workbook__.active = self.__workshet__
return self
def sheetName(self):
"""返回当前工作表名称 | Returns the current sheet name.
:return:
"""
return self.__workshet__.title
def sheetList(self):
"""返回当前工作簿的工作表名称列表 | Returns a list of sheet names for the current workbook.
:return:
"""
return self.__workbook__.sheetnames
def sheetNrow(self):
"""获取当前工作表的最大有效行 | Get the maximum valid number of rows for the current worksheet.
:return:
"""
return self.__workshet__.max_row
def sheetNcol(self):
"""获取当前工作表的最大有效列 | Get the maximum valid number of cols for the current worksheet.
:return:
"""
return self.__workshet__.max_column
def cellSelect(self, cell):
"""设置活动单元格 | Set active cell.
:param cell:
:return:
"""
if not self.__readonly__:
try:
cell_letter = cell.column_letter + str(cell.row)
self.__workshet__.sheet_view.selection[0].activeCell = cell_letter
self.__workshet__.sheet_view.selection[0].sqref = cell_letter
except:
pass
def cellGet(self, row: int = None, col: int = None, cell: str = None):
if cell:
cell_object = self.__workshet__[cell]
else:
if row < 0 or col < 0:
raise Exception('行或列值必须大于等于0 | Row or column values must be at least 0.')
cell_object = self.__workshet__.cell(row=row + 1, column=col + 1)
self.cellSelect(cell=cell_object)
return cell_object.value
def cellPut(self, row: int = None, col: int = None, cell: str = None, value=None):
if cell:
cell_object = self.__workshet__[cell]
else:
if row < 0 or col < 0:
raise Exception('行或列值必须大于等于0 | Row or column values must be at least 0.')
cell_object = self.__workshet__.cell(row=row + 1, column=col + 1)
self.cellSelect(cell=cell_object)
cell_object.value = value
self.saveAuto()
return True
def cellMultView(self, area='', from_col=0, from_row=0, to_col=0, to_row=0):
minCol = from_col
minRow = from_row
maxCol = to_col
maxRow = to_row
if area:
area = area + ':'
area = area.upper()
area = area.split(':')
minCell = area[0]
maxCell = area[1]
minColList = re.findall('([A-Z]+)', minCell)
minRowList = re.findall('([0-9]+)', minCell)
maxColList = re.findall('([A-Z]+)', maxCell)
maxRowList = re.findall('([0-9]+)', maxCell)
minColString = (minColList and minColList[0]) or ''
minRowString = (minRowList and minRowList[0]) or ''
maxColString = (maxColList and maxColList[0]) or ''
maxRowString = (maxRowList and maxRowList[0]) or ''
ncols = self.sheetNcol()
nrows = self.sheetNrow()
if minCell:
minCol = minColString or 'A'
minCol = column_index_from_string(minCol) - 1
# print(minCol)
minRow = minRowString or '1'
minRow = int(minRow) - 1
# print(minRow)
if maxCell:
if minColString and minRowString:
maxCol = maxColString or get_column_letter(ncols)
maxCol = column_index_from_string(maxCol) - 1
# print(maxCol)
maxRow = maxRowString or nrows
maxRow = int(maxRow) - 1
# print(maxRow)
elif minColString and minRowString == '':
maxCol = column_index_from_string(maxColString) - 1
maxRow = nrows - 1
elif minRowString and minColString == '':
maxCol = ncols - 1
maxRow = int(maxRowString) - 1
else:
if minColString and minRowString:
maxCol = minCol
maxRow = minRow
elif minColString and minRowString == '':
maxCol = minCol
maxRow = nrows - 1
elif minRowString and minColString == '':
maxCol = ncols - 1
maxRow = minRow
cellList = self.__workshet__._cells_by_row(min_col=minCol + 1, min_row=minRow + 1, max_col=maxCol + 1,
max_row=maxRow + 1)
result = []
for lineList in cellList:
lineResult = []
for cellObject in lineList:
lineResult.append(cellObject.value)
result.append(lineResult)
return result
def save(self, filename=None):
"""保存 | Save.
:param filename: 另存为的文件路径,默认为保存文件 | The file path to save as, the default is to save the file.
:return:
"""
self.__workbook__.save(filename or self.__filename__)
return True
def saveAuto(self):
if self.__autosave__:
return self.save()
def saveExit(self):
"""保存并退出 | Save and exit.
:return:
"""
self.save()
self.exit()
return True
def exit(self):
"""退出 | Close the workbook and exit.
:return:
"""
self.__workbook__.close()
self.__workshet__ = None
self.__workbook__ = None
self.__filename__ = None
self.__autosave__ = None
return True
excel = Excel().open(filename='../../example.xlsx', read_only=False, auto_save=True)
# print(excel.sheetList())
excel.select(0)
# print(excel.cellMultView(area='H9:L11'))
# print(excel.cellMultView(area='1:3'))
# print(excel.cellMultView(area='A:C'))
# print(excel.cellMultView(area='4'))
# print(excel.cellMultView(area='D'))
# print(excel.cellMultView(area='D1'))
# print(excel.cellMultView(area='A1:F1', from_col=7, from_row=8, to_col=11, to_row=10))
print(excel.cellMultView(area='F'))
for i in range(0, 7):
excel.cellPut(row=9, col=7 + i, value=i * 10 + 1)
print(colIndexFromString('D'))
# print(excel.sheetName())
# print(excel.sheetNrow())
# print(excel.sheetNcol())
# print(excel.cellPut(row=0, col=0, value='id777'))
# print(excel.cellGet(row=0, col=0))
# print(excel.save())
# print(excel.exit())
# a = openpyxl.load_workbook('../../example.xlsx')
# print(a.active._cells_by_row(min_row=1, min_col=1, max_row=3, max_col=3).__next__())
# # 根据列的数字返回字母
# print(get_column_letter(8)) # B
# # 根据字母返回列的数字
# print(column_index_from_string('ab')) # 4
#
# print(re.findall('([A-Za-z]+)', 'AB2'))