179 lines
5.7 KiB
Python
179 lines
5.7 KiB
Python
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字符(约24pt),1.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()
|