Files
draft-closing-report-default/scripts/service/docx_service.py

90 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Word 初稿渲染(python-docx)。
初稿结构:封面信息 → 目录骨架 → 六章(3/4/5 章自动成文,1/2/6 章素材要点 + [待补充] 占位)。
写入技能 output/ 目录(用户可取)。python-docx 为技能特有依赖(requirements.txt 声明)。
"""
from __future__ import annotations
from typing import Any
from util.logging_config import get_skill_logger
from util.runtime_paths import get_output_dir
def _log():
try:
return get_skill_logger()
except RuntimeError:
return None
def _check_docx_available() -> None:
try:
import docx # noqa: F401
except ImportError as exc:
raise RuntimeError(
"python-docx 未安装(技能依赖安装异常);请重新安装技能,或先用 HTML 预览查看初稿内容。"
) from exc
def write_docx(project: dict[str, Any], sections: dict[str, list[str]], batch_no: str) -> str:
"""生成《结题报告(初稿)》docx,返回文件路径。"""
_check_docx_available()
import docx
from docx.enum.text import WD_COLOR_INDEX
from docx.shared import Pt
document = docx.Document()
log = _log()
if log:
log.info("docx_render_start project_no=%s stage=docx", project.get("project_no"))
title = document.add_heading("结题报告(初稿)", level=0)
title.alignment = 1
info_table = document.add_table(rows=0, cols=2)
info_table.style = "Table Grid"
for label, value in (
("项目名称", project.get("project_name")),
("项目编号", project.get("project_no")),
("项目负责人", project.get("pi_name")),
("所属学院", project.get("department")),
("项目类型", project.get("program")),
("执行周期", f"{project.get('start_date') or '—'} ~ {project.get('end_date') or '—'}"),
("生成批次", batch_no),
):
row = info_table.add_row().cells
row[0].text = str(label)
row[1].text = str(value if value not in (None, "") else "—")
document.add_heading("目录(骨架,终稿请按本单位模板调整)", level=1)
for section_title in sections:
document.add_paragraph(section_title, style="List Number")
for section_title, paragraphs in sections.items():
document.add_heading(section_title, level=1)
for paragraph in paragraphs:
text = str(paragraph)
p = document.add_paragraph()
run = p.add_run(text)
if text.startswith("[待补充"):
run.italic = True
run.font.highlight_color = WD_COLOR_INDEX.YELLOW # 占位黄底提示,便于教师定位待写章节
notice = document.add_paragraph()
notice_run = notice.add_run(
"说明:本初稿由结题报告初稿助手按台账数据自动生成;数字章节(完成情况/决算/成果清单)请逐项核对,"
"叙事章节仅提供素材要点,须由项目负责人本人撰写终稿;严禁引入台账之外的成果或结论。"
)
notice_run.font.size = Pt(9)
project_no = str(project.get("project_no") or "未编号")
filename = f"结题报告初稿-{project_no}.docx"
path = get_output_dir() + "/" + filename
document.save(path)
if log:
log.info("docx_render_done project_no=%s path=%s stage=docx", project_no, path)
return path