Files
gpf_pet_hospital/format_thesis_docx.py
2026-02-25 14:35:12 +08:00

179 lines
5.7 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.

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Pt, RGBColor
SRC = r"D:\bs\gpf_pet_hospital\爱维宠物医院管理系统毕业论文-2026版.docx"
DST = r"D:\bs\gpf_pet_hospital\爱维宠物医院管理系统毕业论文-2026版-排版.docx"
def set_style_font(
style,
east_asia_font: str,
size_pt: float,
bold: bool | None = None,
west_font: str = "Times New Roman",
):
font = style.font
font.name = west_font
font.size = Pt(size_pt)
if bold is not None:
font.bold = bold
font.color.rgb = RGBColor(0, 0, 0)
rfonts = style.element.get_or_add_rPr().get_or_add_rFonts()
rfonts.set(qn("w:ascii"), west_font)
rfonts.set(qn("w:hAnsi"), west_font)
rfonts.set(qn("w:eastAsia"), east_asia_font)
def set_runs_font(
paragraph,
east_asia_font: str,
size_pt: float,
bold: bool | None = None,
west_font: str = "Times New Roman",
):
for run in paragraph.runs:
run.font.name = west_font
run.font.size = Pt(size_pt)
if bold is not None:
run.font.bold = bold
run.font.color.rgb = RGBColor(0, 0, 0)
rpr = run._element.get_or_add_rPr()
rfonts = rpr.get_or_add_rFonts()
rfonts.set(qn("w:ascii"), west_font)
rfonts.set(qn("w:hAnsi"), west_font)
rfonts.set(qn("w:eastAsia"), east_asia_font)
def set_runs_common(paragraph, italic: bool | None = None, color_black: bool = True):
for run in paragraph.runs:
if italic is not None:
run.font.italic = italic
if color_black:
run.font.color.rgb = RGBColor(0, 0, 0)
def is_numbered_paragraph(paragraph) -> bool:
ppr = paragraph._p.pPr
if ppr is None:
return False
return ppr.numPr is not None
def set_table_all_borders_black(table):
for row in table.rows:
for cell in row.cells:
tc = cell._tc
tc_pr = tc.get_or_add_tcPr()
tc_borders = tc_pr.find(qn("w:tcBorders"))
if tc_borders is None:
tc_borders = OxmlElement("w:tcBorders")
tc_pr.append(tc_borders)
for edge in ("top", "left", "bottom", "right", "insideH", "insideV"):
edge_tag = qn(f"w:{edge}")
elem = tc_borders.find(edge_tag)
if elem is None:
elem = OxmlElement(f"w:{edge}")
tc_borders.append(elem)
elem.set(qn("w:val"), "single")
elem.set(qn("w:sz"), "8")
elem.set(qn("w:color"), "000000")
elem.set(qn("w:space"), "0")
def iter_table_paragraphs(table):
for row in table.rows:
for cell in row.cells:
for p in cell.paragraphs:
yield p
for t in cell.tables:
yield from iter_table_paragraphs(t)
def format_paragraph(p):
style_name = p.style.name if p.style is not None else ""
if style_name == "Heading 1":
apply_para_format(p, 1.5, 0, WD_ALIGN_PARAGRAPH.CENTER)
set_runs_font(p, "黑体", 22, True)
elif style_name == "Heading 2":
apply_para_format(p, 1.5, 32)
set_runs_font(p, "黑体", 16, True)
elif style_name == "Heading 3":
apply_para_format(p, 1.5, 28)
set_runs_font(p, "宋体", 14, True)
elif style_name == "Heading 4":
apply_para_format(p, 1.5, 24)
set_runs_font(p, "宋体", 12, True)
set_runs_common(p, italic=False, color_black=True)
elif is_numbered_paragraph(p) or style_name.startswith("List Number"):
p.paragraph_format.line_spacing = 1.5
set_runs_font(p, "宋体", 12)
set_runs_common(p, color_black=True)
else:
apply_para_format(p, 1.5, 24)
set_runs_font(p, "宋体", 12)
set_runs_common(p, color_black=True)
def apply_para_format(paragraph, line_spacing: float, first_line_pt: float | None = None, align=None):
fmt = paragraph.paragraph_format
fmt.line_spacing = line_spacing
if first_line_pt is not None:
fmt.first_line_indent = Pt(first_line_pt)
if align is not None:
paragraph.alignment = align
def main():
doc = Document(SRC)
normal = doc.styles["Normal"]
h1 = doc.styles["Heading 1"]
h2 = doc.styles["Heading 2"]
h3 = doc.styles["Heading 3"]
h4 = doc.styles["Heading 4"]
# 正文宋体小四首行缩进2字符约24pt1.5倍行距
set_style_font(normal, "宋体", 12)
normal.paragraph_format.line_spacing = 1.5
normal.paragraph_format.first_line_indent = Pt(24)
# 标题1黑体二号加粗居中1.5倍行距
set_style_font(h1, "黑体", 22, True)
h1.paragraph_format.line_spacing = 1.5
h1.paragraph_format.first_line_indent = Pt(0)
# 标题2黑体三号加粗首行缩进2字符1.5倍行距
set_style_font(h2, "黑体", 16, True)
h2.paragraph_format.line_spacing = 1.5
h2.paragraph_format.first_line_indent = Pt(32)
# 标题3宋体四号加粗首行缩进2字符1.5倍行距
set_style_font(h3, "宋体", 14, True)
h3.paragraph_format.line_spacing = 1.5
h3.paragraph_format.first_line_indent = Pt(28)
# 标题4加粗取消斜体黑色1.5倍行距
set_style_font(h4, "宋体", 12, True)
h4.font.italic = False
h4.paragraph_format.line_spacing = 1.5
h4.paragraph_format.first_line_indent = Pt(24)
for p in doc.paragraphs:
format_paragraph(p)
for t in doc.tables:
set_table_all_borders_black(t)
for p in iter_table_paragraphs(t):
format_paragraph(p)
doc.save(DST)
print(DST)
if __name__ == "__main__":
main()