import os import openpyxl as Workbook from openpyxl.utils import get_column_letter from openpyxl.drawing.image import Image import UtilPack as util from abc import ABC, abstractmethod class DBXLStorage(ABC): xls_name = "EPoleDB.xlsx" xls_infosheet = "DBInfo" m_wb = None m_openedXLS = "" m_defaultImgW = 140 def __init__(self, path): self.path = path #def __enter__(self): #self.DBXLSOpen(self.path) def __exit__(self, ex_type, ex_value, traceback): self.DBXLSClose() def DBXLSOpen(self): xls_path = self.GetXLSPath(self.path) util.DbgOut(xls_path, True) try: self.m_wb = Workbook.load_workbook(xls_path) util.DbgOut("xls Open Successed") except FileNotFoundError: self.m_wb = Workbook.Workbook() ws = self.m_wb.active ws.title = self.xls_infosheet #DBInfo ws.cell(row=1,column=1,value="PoleDB_XLS") self.m_wb.save(xls_path) util.DbgOut(f"{xls_path} Created", True) self.m_openedXLS = xls_path if self.m_wb is None: util.DbgOut("XLS Open Something Wrong...", True) self.m_openedXLS = "" self.m_wb = None return self.checkSheetsInfo() def DBXLSClose(self): if self.m_wb is None or self.m_openedXLS is None: util.DbgOut("XLS Close something wrong...", True) return self.m_wb.save(self.m_openedXLS) self.m_wb.close() util.DbgOut(f"Close : {self.m_openedXLS} Saved") self.m_wb = None def GetCellValueStr(self, sheetName, nCol, nRow): sheet = self.getSheet(sheetName); if sheet is None: return "" return sheet.cell(row=nRow, column=nCol).value.str def SetCellValueStr(self, sheetName, nCol, nRow, ValueStr): sheet = self.getSheet(sheetName); if sheet is None: return sheet.cell(row=nRow,column=nCol,value=ValueStr) def SetCellValueImg(self, sheetName, nCol, nRow, ImagePath): sheet = self.getSheet(sheetName); if sheet is None: return if False == os.path.exists(ImagePath): return xlImg = Image(ImagePath) nNewH = util.GetRSzHeight(xlImg.width, xlImg.height, self.m_defaultImgW ) xlImg.height = nNewH xlImg.width = self.m_defaultImgW ColLetter = get_column_letter(nCol) TrgCell = f"{ColLetter}{nRow}" cellW, cellH = util.GetCellSize(xlImg.width, xlImg.height) sheet.row_dimensions[nRow].height = cellH sheet.column_dimensions[ColLetter].width = cellW sheet.add_image(xlImg, TrgCell) def GetCellValue(self, sheetName, nCol, nRow): sheet = self.getSheet(sheetName); if sheet is None: return "" return sheet.cell(nRow, nCol).value # 시트를 가져온다. # 엑셀 파일이 안 열려 있으면 None def getSheet(self, sheetName, bNew = False): retSheet = None if None == sheetName or "" == sheetName: return None if self.m_wb is None: util.DbgOut("XLS not opened", True) return None try: retSheet = self.m_wb[sheetName] except KeyError: if True == bNew: retSheet = self.m_wb.create_sheet(title=sheetName) util.DbgOut(f"GetSheet : {sheetName} is Created", True) return retSheet # 데이터베이스용 엑셀 파일의 경로를 얻어온다. # 폴더만 입력되었으면 파일이름을 삽입하고, 완전한 경로라면 패스 def GetXLSPath(self, pathSrc): retPath = self.path if os.path.isdir(pathSrc): retPath = os.path.join(pathSrc, self.xls_name) return retPath def FindLastRow(self, sheetName): sheet = self.getSheet(sheetName) if sheet is None: return -1 # 마지막 행 찾기 last_row = sheet.max_row # 빈 셀이 있는지 확인하고, 실제로 값이 있는 마지막 행 찾기 while last_row > 0: row = sheet[last_row] # 현재 행을 가져옴 # 현재 행의 모든 셀을 검사하여 값이 있는지 확인 is_empty = True for cell in row: if cell.value is not None: is_empty = False break # 값이 있는 행을 찾았으면 종료 if not is_empty: break # 행 번호를 하나씩 감소시켜 이전 행을 검사 last_row -= 1 return last_row @abstractmethod def checkSheetsInfo(self): pass