# Copyright (c) 2025 Jeffrey Hsu - JITToolBox # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import json from abc import ABC, abstractmethod from os import PathLike from typing import Optional import openpyxl from openpyxl.workbook import Workbook from openpyxl.worksheet.worksheet import Worksheet from toolbox.models.data_model import ClassInfo from toolbox.models.config import AESConfig class BaseExcelService(ABC): _file_path: str | PathLike _workbook: Optional[Workbook] _sheet: None @abstractmethod def open(self, *args, **kwargs) -> 'BaseExcelService': ... @abstractmethod def save(self) -> 'BaseExcelService': ... @abstractmethod def close(self) -> None: ... @abstractmethod def active_sheet(self, sheet_name: str) -> 'BaseExcelService': ... @property @abstractmethod def cur_active_sheet(self) -> Worksheet: ... class ExcelService(BaseExcelService): def __init__(self, file_path: str | PathLike): self._file_path = file_path self._workbook = None self._sheet = None def open(self, *args, **kwargs): self._workbook = openpyxl.load_workbook(self._file_path, *args, **kwargs) return self def save(self): self._workbook.save(self._file_path) return self def close(self): self._workbook.close() def active_sheet(self, sheet_name: str): self._sheet = self._workbook[sheet_name] return self @property def cur_active_sheet(self): return self._sheet def load_value(self, cell: str): if self._sheet is None: raise ValueError("No active sheet. Please set an active sheet first.") return self._sheet[cell].value class AchievementExcelService(ExcelService): version = '' config = {} def __init__(self, file_path: str | PathLike): super().__init__(file_path) self.open(read_only=True, data_only=True) def load_config(self, config_path: str | PathLike): self.config = AESConfig(config_path) def read_class_info(self) -> list[ClassInfo]: lst = [] self.active_sheet('初始录入') full_name = self.load_value(self.config['class_full_name'].position) for i in range(self.config['class_single_name'].start, self.config['class_single_name'].end): name = self.load_value(self.config['class_single_name'].fposition.format(i)) number = self.load_value(self.config['class_single_number'].fposition.format(i)) if name is None or number is None: break ci = ClassInfo(name, number) ci.full_name = full_name lst.append(ci) if len(lst) == 0: raise ValueError("No class information found in the Excel file.") return lst def read_course_info(self): ...