添加签名图片处理功能

This commit is contained in:
2026-01-04 13:01:37 +08:00
parent 475d23f49e
commit 7f23d64eb2
2 changed files with 138 additions and 22 deletions

View File

@@ -15,6 +15,7 @@
import datetime
import traceback
import io
from typing import Optional, Callable
import openpyxl
@@ -22,6 +23,7 @@ from openpyxl.utils import get_column_letter, column_index_from_string
from openpyxl.workbook.workbook import Workbook
from openpyxl.worksheet.worksheet import Worksheet
from packaging import version
from PIL import Image
from module import LOGLEVEL, COMPATIBLE_VERSION
from module.schema import Performance
@@ -49,6 +51,27 @@ class ExcelReader:
ignore_version_check: bool
pic_list: list
suggestion_template_list: list[Optional[str]]
major_director_signature_image: Optional[Image.Image]
course_leader_signature_image: Optional[Image.Image]
class _SheetImageLoader:
"""Lightweight image loader scoped for ExcelReader use."""
def __init__(self, sheet: Worksheet):
self._images: dict[str, Callable[[], bytes]] = {}
for image in getattr(sheet, "_images", []):
row = image.anchor._from.row + 1
col = get_column_letter(image.anchor._from.col + 1)
self._images[f"{col}{row}"] = image._data
def image_in(self, cell: str) -> bool:
return cell in self._images
def get(self, cell: str) -> Image.Image:
if cell not in self._images:
raise ValueError(f"Cell {cell} doesn't contain an image")
image = io.BytesIO(self._images[cell]())
return Image.open(image)
def __init__(self, file_path: str, version_check: bool = False,
signal: Callable[[str, str], None] = lambda x, y: print(x)):
@@ -75,6 +98,8 @@ class ExcelReader:
self.pic_list = []
self.signal = signal
self.suggestion_template_list = []
self.major_director_signature_image = None
self.course_leader_signature_image = None
def parse_excel(self):
try:
@@ -104,6 +129,13 @@ class ExcelReader:
# 读取课程负责人
self.course_lead_teacher_name = sheet["D8"].value
need_signature_images = CUR_VERSION >= version.parse("9.4") and sheet["H10"].value == ""
if need_signature_images:
self._load_signature_images()
else:
self.major_director_signature_image = None
self.course_leader_signature_image = None
# 读取班级和人数
max_class_size = 4
match CUR_VERSION:
@@ -259,6 +291,24 @@ class ExcelReader:
def run(self):
self.parse_excel()
def _load_signature_images(self):
signature_cells = {
"major_director_signature_image": "K34",
"course_leader_signature_image": "K35",
}
wb_with_images: Workbook = openpyxl.load_workbook(self.file_path, data_only=True)
try:
sheet_with_images: Worksheet = wb_with_images["初始录入"]
loader = self._SheetImageLoader(sheet_with_images)
for attr, cell in signature_cells.items():
if loader.image_in(cell):
setattr(self, attr, loader.get(cell))
else:
setattr(self, attr, None)
finally:
wb_with_images.close()
def clear_all_data(self):
self.kpi_list = []
self.kpi_number = 0
@@ -278,6 +328,8 @@ class ExcelReader:
self.hml_list = []
self.question_data = {}
self.pic_list = []
self.major_director_signature_image = None
self.course_leader_signature_image = None
def set_version_check(self, version_check: bool):
self.ignore_version_check = version_check
@@ -486,7 +538,7 @@ class ExcelReader:
yield "改进措施"
yield ("注:改进措施,包括课时分配、教材选用、教学方式、教学方法、教学内容、评分标准、过程评价及帮扶\n"
f"{self.suggestion_template_list[0] if self.suggestion_template_list[0] is not None else '\n\n\n在这填入您的改进措施\n\n\n'}")
for i in range(88888):
while True:
yield "如果您看到了本段文字,请联系开发者"
def get_word_template_part_2(self):
@@ -581,7 +633,7 @@ class ExcelReader:
yield "改进措施"
yield ("注:改进措施,包括课时分配、教材选用、教学方式、教学方法、教学内容、评分标准、过程评价及帮扶\n"
f"{self.suggestion_template_list[1] if self.suggestion_template_list[1] is not None else '\n\n\n在这填入您的改进措施\n\n\n'}")
for i in range(88888):
while True:
yield "如果您看到了本段文字,请联系开发者"
def get_word_template_part_3(self):
@@ -589,7 +641,7 @@ class ExcelReader:
yield "评价样本的合理性"
yield "R全体样本 £抽样样本"
yield "评价依据的合理性"
yield "考核方法 R合适 £不合适 "
yield "考核方法 R合适 £不合适"
yield "考核内容是否支撑课程目标 R是 £否"
yield "评分标准 R明确 £不明确"
yield "计算过程的合理性"
@@ -603,14 +655,22 @@ class ExcelReader:
yield "专业负责人/系主任(签字)"
yield ("整改意见:\n"
"\n\n\n"
f"{self.suggestion_template_list[3] if self.suggestion_template_list[3] is not None else '\n\n\n'}"
f"\n\n\n\t\t\t\t\t\t\t\t\t签字:\t\t\t日期:{datetime.datetime.now().strftime("%Y-%m-%d")}\n")
f"{" "*8}{self.suggestion_template_list[3] if self.suggestion_template_list[3] is not None else '\n\n\n'}\n\n\n")
yield ""
yield "签字:"
yield ""
yield "日期:"
yield datetime.datetime.now().strftime("%Y-%m-%d")
yield "课程负责人(签字)"
yield ("拟整改计划与措施:\n"
"\n\n\n"
f"{self.suggestion_template_list[4] if self.suggestion_template_list[4] is not None else '\n\n\n'}"
f"\n\n\n\t\t\t\t\t\t\t\t\t签字:\t\t\t日期:{datetime.datetime.now().strftime("%Y-%m-%d")}\n")
for i in range(88888):
f"{" "*8}{self.suggestion_template_list[4] if self.suggestion_template_list[4] is not None else '\n\n\n'}\n\n\n")
yield ""
yield "签字:"
yield ""
yield "日期:"
yield datetime.datetime.now().strftime("%Y-%m-%d")
while True:
yield "如果您看到了本段文字,请联系开发者"