fix: 适配没有英语名字的情况

This commit is contained in:
2025-12-12 17:24:32 +08:00
parent cbf87d2569
commit 9d347f9bc9
9 changed files with 181 additions and 34 deletions

Binary file not shown.

39
main.spec Normal file
View File

@@ -0,0 +1,39 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.pyw'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['public\\icon.ico'],
)

BIN
public/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

View File

@@ -13,6 +13,7 @@ dependencies = [
"pandas>=2.3.3", "pandas>=2.3.3",
"pandas-stubs==2.3.3.251201", "pandas-stubs==2.3.3.251201",
"pillow>=12.0.0", "pillow>=12.0.0",
"pyinstaller>=6.17.0",
"python-pptx>=1.0.2", "python-pptx>=1.0.2",
"pywin32>=311", "pywin32>=311",
"rich>=14.2.0", "rich>=14.2.0",

View File

@@ -191,3 +191,14 @@ def initialize_project(root_dir="."):
logger.warning( logger.warning(
f"⚠️ 警告: 模板文件不存在 ({src_excel})data 文件夹内将没有 Excel 文件。" f"⚠️ 警告: 模板文件不存在 ({src_excel})data 文件夹内将没有 Excel 文件。"
) )
def check_file_exists(file_path):
"""
判断文件是否存在
"""
if (file_path and isinstance(file_path, str) and os.path.exists(file_path)):
logger.info(f"✅ 文件存在: {file_path}")
return True
else:
logger.error(f"❌ 文件不存在: {file_path}")
return False

View File

@@ -11,6 +11,7 @@ import traceback
import comtypes.client import comtypes.client
from config.config import load_config from config.config import load_config
from utils.agent_utils import generate_comment from utils.agent_utils import generate_comment
from utils.file_utils import check_file_exists
from utils.font_utils import install_fonts_from_directory from utils.font_utils import install_fonts_from_directory
from utils.image_utils import find_image_path from utils.image_utils import find_image_path
from utils.zodiac_utils import calculate_zodiac from utils.zodiac_utils import calculate_zodiac
@@ -222,47 +223,50 @@ def generate_report():
# --- 页面 3 --- # --- 页面 3 ---
student_image_folder = os.path.join(config["image_folder"], name) student_image_folder = os.path.join(config["image_folder"], name)
logger.info(f"学生:{name},图片文件夹: {student_image_folder}") logger.info(f"学生:{name},图片文件夹: {student_image_folder}")
if os.path.exists(student_image_folder): # 判断学生图片文件夹是否存在
me_image_path = find_image_path(student_image_folder, "me") if not os.path.exists(student_image_folder):
logger.warning(
f"⚠️ 警告: 学生:{name},学生图片文件夹不存在 {student_image_folder}"
)
continue
# 构造信息字典供 helper 使用 # 检查姓名是否为空
info_dict = { if not name:
"name": name, logger.error(f"⚠️ 警告: 学生:{name},姓名为空,跳过")
"english_name": english_name, break
"sex": sex, # 构造学生信息字典
"birthday": birthday.strftime("%Y-%m-%d") if pd.notna(birthday) else "", student_info_dict = {
"zodiac": zodiac, "name": name,
"friend": friend, "english_name": english_name if pd.notna(english_name) else "",
"hobby": hobby, "sex": sex if pd.notna(sex) else "",
"game": game, "birthday": (
"food": food, birthday.strftime("%Y-%m-%d") if pd.notna(birthday) else ""
} ),
# 逻辑:必须同时满足 "不是None" 且 "是字符串" 且 "文件存在" 才能执行 "zodiac": zodiac if pd.notna(zodiac) else "",
if ( "friend": friend if pd.notna(friend) else "",
me_image_path "hobby": hobby if pd.notna(hobby) else "",
and isinstance(me_image_path, str) "game": game if pd.notna(game) else "",
and os.path.exists(me_image_path) "food": food if pd.notna(food) else "",
): }
replace_three_page(prs, info_dict, me_image_path) # 获取学生个人照片路径
else: me_image_path = find_image_path(student_image_folder, "me")
# 只有在这里打印日志,告诉用户跳过了,但不中断程序 # 检查学生图片是否存在,若不存在则跳过
replace_three_page(prs, info_dict, None) if check_file_exists(me_image_path):
replace_three_page(prs, student_info_dict, me_image_path)
else: else:
logger.warning(f"⚠️ 警告: 学生{name},学生图片文件不存在 {student_image_folder}") logger.warning(f"⚠️ 警告: 学生图片文件不存在 {me_image_path}")
# --- 页面 4 --- # --- 页面 4 ---
class_image_path = find_image_path( class_image_path = find_image_path(
config["image_folder"], config["class_name"] config["image_folder"], config["class_name"]
) )
if (
class_image_path # 添加检查班级图片是否存在,若不存在则跳过
and isinstance(class_image_path, str) if check_file_exists(class_image_path):
and os.path.exists(class_image_path)
):
replace_four_page(prs, class_image_path) replace_four_page(prs, class_image_path)
else: else:
logger.warning(f"⚠️ 警告: 班级图片文件不存在 {class_image_path}") logger.warning(f"⚠️ 警告: 班级图片文件不存在 {class_image_path}")
# --- 页面 5 --- # --- 页面 5 ---
if os.path.exists(student_image_folder): if os.path.exists(student_image_folder):
img1_path = find_image_path(student_image_folder, "1") img1_path = find_image_path(student_image_folder, "1")
@@ -335,10 +339,10 @@ def batch_convert_folder(folder_path):
try: try:
# 1. 启动应用 (只启动一次) # 1. 启动应用 (只启动一次)
powerpoint = comtypes.client.CreateObject("PowerPoint.Application") powerpoint = comtypes.client.CreateObject("PowerPoint.Application")
# 【建议】在后台线程运行时,有时设置为不可见更稳定, # 【建议】在后台线程运行时,有时设置为不可见更稳定,
# 但如果遇到转换卡死,可以尝试去掉下面这行的注释,让它显示出来 # 但如果遇到转换卡死,可以尝试去掉下面这行的注释,让它显示出来
# powerpoint.Visible = 1 # powerpoint.Visible = 1
for filename in files: for filename in files:
ppt_path = os.path.join(folder_path, filename) ppt_path = os.path.join(folder_path, filename)
@@ -354,7 +358,7 @@ def batch_convert_folder(folder_path):
try: try:
# 打开 -> 另存为 -> 关闭 # 打开 -> 另存为 -> 关闭
deck = powerpoint.Presentations.Open(ppt_path) deck = powerpoint.Presentations.Open(ppt_path)
deck.SaveAs(pdf_path, 32) # 32 代表 PDF 格式 deck.SaveAs(pdf_path, 32) # 32 代表 PDF 格式
deck.Close() deck.Close()
except Exception as e: except Exception as e:
logger.error(f"文件 {filename} 转换出错: {e}") logger.error(f"文件 {filename} 转换出错: {e}")
@@ -376,6 +380,7 @@ def batch_convert_folder(folder_path):
# 【核心修复 2】释放资源 # 【核心修复 2】释放资源
pythoncom.CoUninitialize() pythoncom.CoUninitialize()
# ========================================== # ==========================================
# 5. 生成属相(根据names.xlsx文件生成属相) # 5. 生成属相(根据names.xlsx文件生成属相)
# ========================================== # ==========================================

91
uv.lock generated
View File

@@ -2,6 +2,15 @@ version = 1
revision = 2 revision = 2
requires-python = ">=3.13" requires-python = ">=3.13"
[[package]]
name = "altgraph"
version = "0.17.5"
source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/7e/f8/97fdf103f38fed6792a1601dbc16cc8aac56e7459a9fff08c812d8ae177a/altgraph-0.17.5.tar.gz", hash = "sha256:c87b395dd12fabde9c99573a9749d67da8d29ef9de0125c7f536699b4a9bc9e7" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl", hash = "sha256:f3a22400bce1b0c701683820ac4f3b159cd301acab067c51c653e06961600597" },
]
[[package]] [[package]]
name = "annotated-types" name = "annotated-types"
version = "0.7.0" version = "0.7.0"
@@ -122,6 +131,7 @@ dependencies = [
{ name = "pandas" }, { name = "pandas" },
{ name = "pandas-stubs" }, { name = "pandas-stubs" },
{ name = "pillow" }, { name = "pillow" },
{ name = "pyinstaller" },
{ name = "python-pptx" }, { name = "python-pptx" },
{ name = "pywin32" }, { name = "pywin32" },
{ name = "rich" }, { name = "rich" },
@@ -138,6 +148,7 @@ requires-dist = [
{ name = "pandas", specifier = ">=2.3.3" }, { name = "pandas", specifier = ">=2.3.3" },
{ name = "pandas-stubs", specifier = "==2.3.3.251201" }, { name = "pandas-stubs", specifier = "==2.3.3.251201" },
{ name = "pillow", specifier = ">=12.0.0" }, { name = "pillow", specifier = ">=12.0.0" },
{ name = "pyinstaller", specifier = ">=6.17.0" },
{ name = "python-pptx", specifier = ">=1.0.2" }, { name = "python-pptx", specifier = ">=1.0.2" },
{ name = "pywin32", specifier = ">=311" }, { name = "pywin32", specifier = ">=311" },
{ name = "rich", specifier = ">=14.2.0" }, { name = "rich", specifier = ">=14.2.0" },
@@ -459,6 +470,18 @@ wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/92/aa/df863bcc39c5e0946263454aba394de8a9084dbaff8ad143846b0d844739/lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c" }, { url = "https://mirrors.aliyun.com/pypi/packages/92/aa/df863bcc39c5e0946263454aba394de8a9084dbaff8ad143846b0d844739/lxml-6.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:bb4c1847b303835d89d785a18801a883436cdfd5dc3d62947f9c49e24f0f5a2c" },
] ]
[[package]]
name = "macholib"
version = "1.16.4"
source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
dependencies = [
{ name = "altgraph" },
]
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/10/2f/97589876ea967487978071c9042518d28b958d87b17dceb7cdc1d881f963/macholib-1.16.4.tar.gz", hash = "sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl", hash = "sha256:da1a3fa8266e30f0ce7e97c6a54eefaae8edd1e5f86f3eb8b95457cae90265ea" },
]
[[package]] [[package]]
name = "markdown-it-py" name = "markdown-it-py"
version = "4.0.0" version = "4.0.0"
@@ -692,6 +715,15 @@ wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/e2/68/78a3c253f146254b8e2c19f4a4768f272e12ef11001d9b45ec7b165db054/pandas_stubs-2.3.3.251201-py3-none-any.whl", hash = "sha256:eb5c9b6138bd8492fd74a47b09c9497341a278fcfbc8633ea4b35b230ebf4be5" }, { url = "https://mirrors.aliyun.com/pypi/packages/e2/68/78a3c253f146254b8e2c19f4a4768f272e12ef11001d9b45ec7b165db054/pandas_stubs-2.3.3.251201-py3-none-any.whl", hash = "sha256:eb5c9b6138bd8492fd74a47b09c9497341a278fcfbc8633ea4b35b230ebf4be5" },
] ]
[[package]]
name = "pefile"
version = "2024.8.26"
source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/03/4f/2750f7f6f025a1507cd3b7218691671eecfd0bbebebe8b39aa0fe1d360b8/pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f" },
]
[[package]] [[package]]
name = "pillow" name = "pillow"
version = "12.0.0" version = "12.0.0"
@@ -827,6 +859,47 @@ wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" }, { url = "https://mirrors.aliyun.com/pypi/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" },
] ]
[[package]]
name = "pyinstaller"
version = "6.17.0"
source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
dependencies = [
{ name = "altgraph" },
{ name = "macholib", marker = "sys_platform == 'darwin'" },
{ name = "packaging" },
{ name = "pefile", marker = "sys_platform == 'win32'" },
{ name = "pyinstaller-hooks-contrib" },
{ name = "pywin32-ctypes", marker = "sys_platform == 'win32'" },
{ name = "setuptools" },
]
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/01/80/9e0dad9c69a7cfd4b5aaede8c6225d762bab7247a2a6b7651e1995522001/pyinstaller-6.17.0.tar.gz", hash = "sha256:be372bd911392b88277e510940ac32a5c2a6ce4b8d00a311c78fa443f4f27313" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/35/f5/37e419d84d5284ecab11ef8b61306a3b978fe6f0fd69a9541e16bfd72e65/pyinstaller-6.17.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:4e446b8030c6e5a2f712e3f82011ecf6c7ead86008357b0d23a0ec4bcde31dac" },
{ url = "https://mirrors.aliyun.com/pypi/packages/9e/b6/2e184879ab9cf90a1d2867fdd34d507c4d246b3cc52ca05aad00bfc70ee7/pyinstaller-6.17.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:aa9fd87aaa28239c6f0d0210114029bd03f8cac316a90bab071a5092d7c85ad7" },
{ url = "https://mirrors.aliyun.com/pypi/packages/40/76/f529de98f7e5cce7904c19b224990003fc2267eda2ee5fdd8452acb420a9/pyinstaller-6.17.0-py3-none-manylinux2014_i686.whl", hash = "sha256:060b122e43e7c0b23e759a4153be34bd70914135ab955bb18a67181e0dca85a2" },
{ url = "https://mirrors.aliyun.com/pypi/packages/a3/10/c02bfbb050cafc4c353cf69baf95407e211e1372bd286ab5ce5cbc13a30a/pyinstaller-6.17.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:cd213d1a545c97dfe4a3c40e8213ff7c5127fc115c49229f27a3fa541503444b" },
{ url = "https://mirrors.aliyun.com/pypi/packages/11/9d/69fdacfd9335695f5900a376cfe3e4aed28f0720ffc15fee81fdb9d920bc/pyinstaller-6.17.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:89c0d18ba8b62c6607abd8cf2299ae5ffa5c36d8c47f39608ce8c3f357f6099f" },
{ url = "https://mirrors.aliyun.com/pypi/packages/5e/1e/e8e36e1568f6865ac706c6e1f875c1a346ddaa9f9a8f923d66545d2240ed/pyinstaller-6.17.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2a147b83cdebb07855bd5a663600891550062373a2ca375c58eacead33741a27" },
{ url = "https://mirrors.aliyun.com/pypi/packages/8d/15/9dc0f81ccb746c27bfa6ee53164422fe47ee079c7a717d9c4791aba78797/pyinstaller-6.17.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:f8cfbbfa6708e54fb936df6dd6eafaf133e84efb0d2fe25b91cfeefa793c4ca4" },
{ url = "https://mirrors.aliyun.com/pypi/packages/97/e6/bed54821c1ebe1275c559661d3e7bfa23c406673b515252dfbf89db56c65/pyinstaller-6.17.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:97f4c1942f7b4cd73f9e38b49cc8f5f8a6fbb44922cb60dd3073a189b77ee1ae" },
{ url = "https://mirrors.aliyun.com/pypi/packages/c7/84/897d759198676b910d69d42640b6d25d50b449f2209e18127a974cf59dbe/pyinstaller-6.17.0-py3-none-win32.whl", hash = "sha256:ce0be227a037fd4be672226db709088565484f597d6b230bceec19850fdd4c85" },
{ url = "https://mirrors.aliyun.com/pypi/packages/2d/f5/6a122efe024433ecc34aab6f499e0bd2bbe059c639b77b0045aa2421b0bf/pyinstaller-6.17.0-py3-none-win_amd64.whl", hash = "sha256:b019940dbf7a01489d6b26f9fb97db74b504e0a757010f7ad078675befc85a82" },
{ url = "https://mirrors.aliyun.com/pypi/packages/c4/96/14991773c9e599707a53594429ccf372f9ee638df3b7d26b65fd1a7433f0/pyinstaller-6.17.0-py3-none-win_arm64.whl", hash = "sha256:3c92a335e338170df7e615f75279cfeea97ade89e6dd7694943c8c185460f7b7" },
]
[[package]]
name = "pyinstaller-hooks-contrib"
version = "2025.10"
source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
dependencies = [
{ name = "packaging" },
{ name = "setuptools" },
]
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/26/4f/e33132acdb8f732978e577b8a0130a412cbfe7a3414605e3fd380a975522/pyinstaller_hooks_contrib-2025.10.tar.gz", hash = "sha256:a1a737e5c0dccf1cf6f19a25e2efd109b9fec9ddd625f97f553dac16ee884881" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/86/de/a7688eed49a1d3df337cdaa4c0d64e231309a52f269850a72051975e3c4a/pyinstaller_hooks_contrib-2025.10-py3-none-any.whl", hash = "sha256:aa7a378518772846221f63a84d6306d9827299323243db890851474dfd1231a9" },
]
[[package]] [[package]]
name = "python-dateutil" name = "python-dateutil"
version = "2.9.0.post0" version = "2.9.0.post0"
@@ -876,6 +949,15 @@ wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42" }, { url = "https://mirrors.aliyun.com/pypi/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42" },
] ]
[[package]]
name = "pywin32-ctypes"
version = "0.2.3"
source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8" },
]
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "6.0.3" version = "6.0.3"
@@ -1016,6 +1098,15 @@ wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd" }, { url = "https://mirrors.aliyun.com/pypi/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd" },
] ]
[[package]]
name = "setuptools"
version = "80.9.0"
source = { registry = "https://mirrors.aliyun.com/pypi/simple/" }
sdist = { url = "https://mirrors.aliyun.com/pypi/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c" }
wheels = [
{ url = "https://mirrors.aliyun.com/pypi/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922" },
]
[[package]] [[package]]
name = "six" name = "six"
version = "1.17.0" version = "1.17.0"