基于Python自动化实现Word文档专业排版
在办公自动化领域,用 Python 处理 Word 文档已经是非常成熟和高效的方案了。通过几个核心库的配合使用,完全可以实现从文档生成、批量处理到专业排版的全流程自动化。
核心库选型与对比
在开始写代码之前,需要了解目前 Python 生态中几个主流的 Word 处理库,根据实际需求选择合适的工具组合。
| 库名称 | 定位 | 核心能力 | 适用场景 |
|---|---|---|---|
| python-docx | 基础操作库 | 创建/读取 .docx,添加段落、表格、图片、页眉页脚,设置基础样式 | 日常办公自动化,入门首选 |
| docxtpl | 模板引擎 | 基于 Jinja2 语法,支持变量、循环、条件判断,模板与数据分离 | 批量生成合同、报告、证书 |
| Spire.Doc | 专业商业库 | 全格式支持(.doc/.docx),高级排版,高精度转换 | 企业级文档处理需求 |
| Aspose.Words | 企业级商业库 | 完整文档生命周期管理,超强格式保真度 | 专业文档管理系统 |
| python-docx-template | python-docx 扩展 | 在 python-docx 基础上增强模板功能 | 需要 python-docx 原生能力的模板场景 |
环境搭建
pip install python-docx pip install docxtpl pip install openpyxl pandas # 用于数据读取 pip install Pillow # 图片处理
建议使用虚拟环境管理依赖,避免版本冲突。
核心功能实现
创建文档与段落操作
这是最基础的文档生成方式,下面代码展示了创建文档、添加各级标题、设置段落对齐和字体格式的完整流程。
from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
def create_basic_document():
"""创建基础文档"""
doc = Document()
# 添加标题(0级标题,类似大标题)
doc.add_heading('Python自动化排版工具', level=0)
# 添加一级标题
doc.add_heading('第一章 引言', level=1)
# 添加二级标题
doc.add_heading('1.1 背景介绍', level=2)
# 添加段落并设置格式
para = doc.add_paragraph()
run = para.add_run('这是使用Python自动生成的第一个段落。')
run.font.size = Pt(12)
run.font.name = '宋体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体') # 解决中文显示问题
# 居中对齐示例
center_para = doc.add_paragraph()
center_run = center_para.add_run('居中对齐标题')
center_run.font.size = Pt(14)
center_run.font.bold = True
center_para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 设置段落缩进和行距
from docx.shared import Cm
indent_para = doc.add_paragraph('这是一个设置了首行缩进和段前间距的段落,用于展示专业排版效果。')
indent_para.paragraph_format.first_line_indent = Cm(0.75) # 首行缩进
indent_para.paragraph_format.space_before = Pt(12) # 段前间距
indent_para.paragraph_format.space_after = Pt(6) # 段后间距
doc.save('basic_document.docx')
print("基础文档创建完成!")
create_basic_document()关键知识点:
doc.add_heading(level=x)中 level 的范围是 0~9,0 为文档主标题,1~9 对应各级标题。- 设置中文字体时,需要同时设置
run.font.name和run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体'),否则中文可能显示异常。 - 段落间距的单位可以使用
Pt(磅)、Cm(厘米)等。
表格操作(Excel 数据导入)
表格是 Word 文档中常用的元素,结合 pandas 可以轻松实现 Excel 数据导入到 Word 表格。
from docx import Document
from docx.shared import Pt, RGBColor
from docx.oxml.ns import qn
import pandas as pd
def create_sales_report_table():
"""创建销售报告表格"""
doc = Document()
doc.add_heading('2026年第一季度销售报告', level=0)
# 从 Excel 读取数据(实际使用时可替换为真实文件路径)
# df = pd.read_excel('sales_data.xlsx')
# 这里用示例数据代替
data = {
'产品名称': ['智能手表A', '降噪耳机B', '无线充电器C', '运动手环D'],
'1月销量': [1250, 980, 2100, 1560],
'2月销量': [1420, 1050, 2350, 1680],
'3月销量': [1680, 1180, 2580, 1820]
}
df = pd.DataFrame(data)
# 创建表格(行数 = 数据行数 + 标题行)
table = doc.add_table(rows=len(df) + 1, cols=len(df.columns))
table.style = 'Table Grid' # 应用网格样式
# 设置表头
header_cells = table.rows[0].cells
for i, col_name in enumerate(df.columns):
header_cells[i].text = col_name
# 设置表头格式
run = header_cells[i].paragraphs[0].runs[0]
run.font.bold = True
run.font.size = Pt(11)
run.font.name = '微软雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')
# 填充数据
for idx, row in df.iterrows():
row_cells = table.rows[idx + 1].cells
for col_idx, value in enumerate(row):
row_cells[col_idx].text = str(value)
# 调整列宽
for col_idx in range(len(df.columns)):
table.columns[col_idx].width = Cm(3) if col_idx == 0 else Cm(2)
doc.save('sales_report.docx')
print("销售报告生成完成!")
create_sales_report_table()实际项目中,如果不需要整表创建,也可以使用 doc.add_table(rows=1, cols=3) 配合 add_row() 动态追加数据的方式。但使用 pandas 配合上述代码可以更灵活地处理来源 Excel 数据。
图文混排与图片控制
插入带题注的图片并自动居中是专业排版中的常见需求,下面代码实现了自动居中并添加题注编号。
from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
import os
def insert_image_with_caption(doc, img_path, caption_text):
"""插入带题注的图片,自动居中并编号"""
# 插入图片段落并居中
para = doc.add_paragraph()
run = para.add_run()
run.add_picture(img_path, width=Inches(4.5))
para.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 获取当前图片序号
pic_count = len(doc.inline_shapes)
# 添加题注
caption = doc.add_paragraph(f'图{pic_count} {caption_text}')
caption.style = 'Caption'
caption.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 设置题注字体
for run in caption.runs:
run.font.size = Pt(10)
run.font.name = '宋体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
def create_picture_document():
"""创建图文混排文档"""
doc = Document()
doc.add_heading('产品技术白皮书', level=0)
doc.add_heading('第二章 产品设计', level=1)
doc.add_paragraph('本章节展示了产品的整体设计架构和技术优势。')
# 插入图片(请替换为实际图片路径)
# insert_image_with_caption(doc, 'architecture.png', '产品架构图')
doc.add_paragraph('从上图可以看出,本产品采用了模块化设计,各模块之间通过标准化接口通信。')
doc.add_paragraph('这一设计理念带来了以下优势:')
# 添加列表
ul = doc.add_paragraph()
for item in ['可扩展性强', '维护成本低', '开发效率高']:
ul.add_run(f'• {item}\n')
doc.save('technical_report.docx')
print("技术白皮书生成完成!")
create_picture_document()使用 add_picture 时,可以通过 width 和 height 参数精确控制图片尺寸。
专业排版技巧
样式模板应用
通过 doc.styles 管理样式可以实现全局格式统一,避免重复设置。
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
def apply_unified_styles():
"""应用统一样式模板"""
doc = Document()
# 获取并修改标题样式
heading1_style = doc.styles['Heading 1']
heading1_style.font.size = Pt(18)
heading1_style.font.bold = True
heading1_style.font.name = '黑体'
heading1_style._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
heading1_style.paragraph_format.space_before = Pt(18)
heading1_style.paragraph_format.space_after = Pt(12)
# 修改正文样式
normal_style = doc.styles['Normal']
normal_style.font.size = Pt(11)
normal_style.font.name = '宋体'
normal_style._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
normal_style.paragraph_format.first_line_indent = Cm(0.75)
normal_style.paragraph_format.line_spacing = 1.5
# 创建自定义样式
custom_style = doc.styles.add_style('Custom Note', 1) # 1 表示段落样式
custom_style.font.size = Pt(10)
custom_style.font.color.rgb = RGBColor(100, 100, 100)
custom_style.font.italic = True
custom_style.paragraph_format.space_before = Pt(6)
# 使用样式
doc.add_heading('第一章 项目概述', level=1)
doc.add_paragraph('这是应用统一样式后的正文内容,所有格式将保持一致。')
note_para = doc.add_paragraph('【注释】此处为自定义样式展示', style='Custom Note')
doc.save('styled_document.docx')
print("样式文档生成完成!")
apply_unified_styles()样式修改的核心要点是修改样式定义而非逐个元素设置,这样后期需要调整格式时只需修改样式定义,所有应用该样式的内容会自动更新。
页眉页脚与页码
页眉页脚操作可以通过 section 对象轻松获取,页码的添加则需要通过底层 XML 实现。
from docx import Document
from docx.shared import Pt
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
def add_header_footer_with_pagination():
"""添加页眉页脚和页码"""
doc = Document()
# 获取第一个节的页眉
section = doc.sections[0]
header = section.header
header_para = header.paragraphs[0]
header_para.text = "技术报告 | 机密文档"
header_para.alignment = 1 # 居中
# 添加页脚和页码
footer = section.footer
footer_para = footer.paragraphs[0]
footer_para.alignment = 1 # 居中
# 通过底层 XML 添加页码字段
run = footer_para.add_run()
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'begin')
run._r.append(fldChar)
instrText = OxmlElement('w:instrText')
instrText.text = "PAGE"
run._r.append(instrText)
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'end')
run._r.append(fldChar)
run.add_text(" / ")
run = footer_para.add_run()
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'begin')
run._r.append(fldChar)
instrText = OxmlElement('w:instrText')
instrText.text = "NUMPAGES"
run._r.append(instrText)
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'end')
run._r.append(fldChar)
# 添加文档内容
for i in range(1, 6):
doc.add_heading(f'第{i}章 内容章节', level=1)
doc.add_paragraph(f'这是第{i}章的具体内容,文档将自动生成页码。')
doc.add_page_break()
doc.save('document_with_pagination.docx')
print("带页码文档生成完成!")
add_header_footer_with_pagination()页码字段(field)不是普通文本,而是 Word 的动态字段,需要通过 OOXML 的字段元素来构造。
自动生成目录
目录生成需要理解 Word 中目录字段的工作原理,通过插入 TOC 字段实现。
from docx import Document
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
def add_auto_table_of_contents():
"""添加自动目录"""
doc = Document()
# 插入目录
doc.add_heading('文档目录', level=0)
# 插入 TOC 字段
paragraph = doc.add_paragraph()
run = paragraph.add_run()
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'begin')
run._r.append(fldChar)
instrText = OxmlElement('w:instrText')
instrText.text = 'TOC \\o "1-3" \\h \\z \\u'
run._r.append(instrText)
fldChar = OxmlElement('w:fldChar')
fldChar.set(qn('w:fldCharType'), 'end')
run._r.append(fldChar)
# 添加章节内容
for i in range(1, 5):
doc.add_heading(f'第{i}章 主要内容', level=1)
for j in range(1, 4):
doc.add_heading(f'{i}.{j} 小节内容', level=2)
doc.add_paragraph('这是小节的具体内容描述,目录会自动捕捉并显示。')
doc.add_page_break()
doc.save('document_with_toc.docx')
print("带自动目录的文档生成完成!")
add_auto_table_of_contents()目录字段 \o "1-3" 的含义是包含级别 1-3 的标题,\h 表示超级链接,\z 表示隐藏标签,\u 表示使用段落大纲级别。
高级排版功能
分节与页面设置
分节是 Word 排版中的高级功能,允许在同一文档中设置不同的页面布局。
from docx import Document
from docx.shared import Cm
from docx.enum.section import WD_SECTION
def add_section_and_layout():
"""分节与页面设置"""
doc = Document()
# 获取文档的第一节
section = doc.sections[0]
# 设置页面边距
section.top_margin = Cm(2.54)
section.bottom_margin = Cm(2.54)
section.left_margin = Cm(3.17)
section.right_margin = Cm(3.17)
# 添加文档内容
doc.add_heading('报告正文', level=1)
doc.add_paragraph('这是报告正文的第一页内容,使用标准页边距设置。')
doc.add_page_break()
# 添加新节
new_section = doc.add_section(WD_SECTION.NEW_PAGE)
# 为新节设置不同的页边距(方便插入宽表格)
new_section.top_margin = Cm(2.0)
new_section.bottom_margin = Cm(2.0)
new_section.left_margin = Cm(1.5)
new_section.right_margin = Cm(1.5)
doc.add_heading('附录', level=1)
doc.add_paragraph('附录部分使用更宽的页面边距,便于展示大型表格和图表。')
doc.save('document_with_sections.docx')
print("分节文档生成完成!")
add_section_and_layout()中文排版优化(字体与编码)
处理中文文档时,字体设置和编码处理是两个最常见的坑。通过以下函数可以系统性地解决这些问题。
from docx import Document
from docx.shared import Pt
from docx.oxml.ns import qn
def optimize_chinese_document():
"""优化中文文档排版"""
doc = Document()
# 统一设置全局中文字体
def set_chinese_font(run, font_name='宋体', font_size=12):
run.font.name = font_name
run.font.size = Pt(font_size)
run._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)
# 添加标题
title = doc.add_heading('中文文档排版优化指南', level=0)
for run in title.runs:
run.font.name = '黑体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
run.font.size = Pt(22)
# 添加正文内容
para = doc.add_paragraph()
run = para.add_run('这是一段经过优化后的中文文档内容,字体显示正常,段落格式专业。')
set_chinese_font(run, '宋体', 12)
# 设置段落首行缩进
para.paragraph_format.first_line_indent = Cm(0.75)
doc.save('optimized_chinese_doc.docx')
print("中文优化文档生成完成!")
optimize_chinese_document()中文字体设置的根本原因是 python-docx 默认的英文字体不支持中文,需要通过修改 XML 中的 w:eastAsia 属性来指定中文字体,两者是独立设置的。
知识扩展
下面分享了一个基于Python开发的word文档专业排版工具,完整代码如下:
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from docx import Document
from docx.shared import Pt, Cm
from docx.oxml.ns import qn
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING
import os
import re
import sys
# --- 1. 环境检测与 .doc 转换模块 (仅Windows有效) ---
if sys.platform.startswith('win'):
try:
import win32com.client
CONVERT_ENABLED = True
except ImportError:
CONVERT_ENABLED = False
print("提示: 如需处理 .doc 文件,请安装 pywin32: pip install pywin32")
else:
CONVERT_ENABLED = False
def convert_doc_to_docx(doc_path):
"""将旧版 .doc 转换为 .docx"""
if not CONVERT_ENABLED:
return False, "非Windows环境,无法转换 .doc 文件"
word = None
try:
# 优先尝试 WPS
word = win32com.client.Dispatch("Kwps.Application")
except:
try:
# 备选尝试 Office
word = win32com.client.Dispatch("Word.Application")
except:
return False, "未检测到WPS或Office软件"
try:
doc = word.Documents.Open(doc_path)
docx_path = doc_path + "x"
# WPS和Office通用的保存格式代码 (wdFormatXMLDocument)
doc.SaveAs(docx_path, 12)
doc.Close()
word.Quit()
return True, docx_path
except Exception as e:
if word: word.Quit()
return False, f"转换失败: {str(e)}"
# --- 2. 核心配置 (初始化默认值) ---
CONFIG = {
"margin": (2.54, 2.54, 3.17, 3.17),
"western_font": "Times New Roman",
"line_height": Pt(28.95),
"line_rule": WD_LINE_SPACING.EXACTLY,
"fonts": {
"title": "方正小标宋_GBK",
"heading_1": "黑体",
"heading_2": "楷体_GB2312",
"heading_3": "仿宋_GB2312",
"body": "仿宋_GB2312"
},
"font_sizes": {
"title": 22,
"heading_1": 16,
"heading_2": 16,
"heading_3": 16,
"body": 16
}
}
def set_font(run, chinese_font, western_font):
"""强制设置字体 (解决WPS中字体不生效的问题)"""
run.font.name = western_font
r = run._element.rPr
if r is not None:
# 移除旧的东亚字体设置
rFonts = r.find(qn('w:eastAsia'))
if rFonts is not None:
r.remove(rFonts)
# 添加新的东亚字体
new_rFonts = r.makeelement(qn('w:eastAsia'), {})
new_rFonts.set(qn('w:val'), chinese_font)
r.append(new_rFonts)
def process_document(input_path, output_path):
"""核心处理逻辑"""
# --- 步骤1: 处理文件格式 ---
file_ext = os.path.splitext(input_path)[1].lower()
temp_docx_path = None
if file_ext == ".doc":
print("转换中: .doc -> .docx")
success, result = convert_doc_to_docx(input_path)
if not success:
return False, result
temp_docx_path = result
process_path = temp_docx_path
elif file_ext == ".docx":
process_path = input_path
else:
return False, "不支持的文件格式"
try:
doc = Document(process_path)
# 设置页边距
for section in doc.sections:
section.top_margin = Cm(CONFIG["margin"][0])
section.bottom_margin = Cm(CONFIG["margin"][1])
section.left_margin = Cm(CONFIG["margin"][2])
section.right_margin = Cm(CONFIG["margin"][3])
# --- 步骤2: 遍历段落并应用自定义样式 ---
for para in doc.paragraphs:
if not para.text.strip():
continue
text = para.text.strip()
# 标题1: 匹配 "一、" 格式
if re.match(r'^[一二三四五六七八九十]、', text):
pf = para.paragraph_format
pf.first_line_indent = Pt(0) # 取消缩进
pf.alignment = WD_ALIGN_PARAGRAPH.LEFT
pf.line_spacing_rule = CONFIG["line_rule"]
pf.line_spacing = CONFIG["line_height"]
for run in para.runs:
set_font(run, CONFIG["fonts"]["heading_1"], CONFIG["western_font"])
run.font.size = Pt(CONFIG["font_sizes"]["heading_1"])
run.font.bold = False
# 标题2: 匹配 "(一)" 格式
elif re.match(r'^[((][\u4e00-\u9fa5]+[))]', text):
pf = para.paragraph_format
pf.first_line_indent = Pt(0)
pf.alignment = WD_ALIGN_PARAGRAPH.LEFT
pf.line_spacing_rule = CONFIG["line_rule"]
pf.line_spacing = CONFIG["line_height"]
for run in para.runs:
set_font(run, CONFIG["fonts"]["heading_2"], CONFIG["western_font"])
run.font.size = Pt(CONFIG["font_sizes"]["heading_2"])
run.font.bold = False
# 标题3: 匹配 "1." 或 "1、" 格式
elif re.match(r'^\d+[\.、]', text):
pf = para.paragraph_format
pf.first_line_indent = Pt(0)
pf.alignment = WD_ALIGN_PARAGRAPH.LEFT
pf.line_spacing_rule = CONFIG["line_rule"]
pf.line_spacing = CONFIG["line_height"]
for run in para.runs:
set_font(run, CONFIG["fonts"]["heading_3"], CONFIG["western_font"])
run.font.size = Pt(CONFIG["font_sizes"]["heading_3"])
run.font.bold = True
# 正文: 默认样式
else:
pf = para.paragraph_format
pf.first_line_indent = Cm(0.74) # 首行缩进2字符
pf.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
pf.line_spacing_rule = CONFIG["line_rule"]
pf.line_spacing = CONFIG["line_height"]
for run in para.runs:
set_font(run, CONFIG["fonts"]["body"], CONFIG["western_font"])
run.font.size = Pt(CONFIG["font_sizes"]["body"])
run.font.bold = False
# --- 步骤3: 处理文档大标题 (第1段) ---
if len(doc.paragraphs) > 0:
first_para = doc.paragraphs[0]
if first_para.text.strip():
pf = first_para.paragraph_format
pf.alignment = WD_ALIGN_PARAGRAPH.CENTER
pf.space_after = Pt(12)
for run in first_para.runs:
set_font(run, CONFIG["fonts"]["title"], CONFIG["western_font"])
run.font.size = Pt(CONFIG["font_sizes"]["title"])
run.font.bold = False
doc.save(output_path)
# 清理临时文件
if temp_docx_path and os.path.exists(temp_docx_path):
os.remove(temp_docx_path)
return True, f"成功! 保存至: {output_path}"
except Exception as e:
if temp_docx_path and os.path.exists(temp_docx_path):
os.remove(temp_docx_path)
return False, f"处理异常: {str(e)}"
# --- 3. 美观的GUI界面 (含自定义配置) ---
class ModernTypesettingApp:
def __init__(self, root):
self.root = root
self.root.title("🖋️ WPS 智能排版大师 (含自定义)")
self.root.geometry("750x600")
self.root.resizable(True, True)
self.setup_styles()
self.create_widgets()
def setup_styles(self):
style = ttk.Style()
style.configure("TLabel", font=("微软雅黑", 10))
style.configure("TButton", font=("微软雅黑", 9))
self.root.configure(bg='#f5f5f5')
def create_widgets(self):
notebook = ttk.Notebook(self.root)
notebook.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# --- Tab 1: 主操作界面 ---
tab_main = ttk.Frame(notebook)
notebook.add(tab_main, text="📄 文档处理")
main_frame = ttk.LabelFrame(tab_main, text=" 任务配置 ", padding=20)
main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
# 输入输出
tk.Label(main_frame, text="输入文件:", font=("微软雅黑", 10)).grid(row=0, column=0, sticky=tk.W, pady=10)
self.input_entry = tk.Entry(main_frame, width=40, font=("Consolas", 10), relief="solid")
self.input_entry.grid(row=0, column=1, padx=10, pady=10, sticky=tk.EW)
tk.Button(main_frame, text="📂 选择文件", command=self.browse_input, bg="#007ACC", fg="white").grid(row=0, column=2, padx=10)
tk.Label(main_frame, text="输出目录:", font=("微软雅黑", 10)).grid(row=1, column=0, sticky=tk.W, pady=10)
self.output_entry = tk.Entry(main_frame, width=40, font=("Consolas", 10), relief="solid")
self.output_entry.grid(row=1, column=1, padx=10, pady=10, sticky=tk.EW)
tk.Button(main_frame, text="📁 选择文件夹", command=self.browse_output, bg="#28A745", fg="white").grid(row=1, column=2, padx=10)
# 控制按钮
btn_frame = tk.Frame(main_frame)
btn_frame.grid(row=2, column=0, columnspan=3, pady=30)
self.start_btn = tk.Button(btn_frame, text="🚀 开始排版",
command=self.start_process,
bg="#DC3545", fg="white", width=15, height=2, font=("微软雅黑", 10, "bold"))
self.start_btn.pack(side=tk.LEFT, padx=20)
tk.Button(btn_frame, text="❌ 退出", command=self.root.quit,
width=15, height=2).pack(side=tk.LEFT, padx=20)
# 状态栏
self.status_var = tk.StringVar()
self.status_var.set("就绪: 支持 .doc 和 .docx 格式")
status_bar = tk.Label(self.root, textvariable=self.status_var, relief="sunken",
bg="#e9ecef", fg="gray", font=("Consolas", 9))
status_bar.pack(side=tk.BOTTOM, fill=tk.X)
# --- Tab 2: 字体配置界面 ---
tab_config = ttk.Frame(notebook)
notebook.add(tab_config, text="🎨 字体配置")
config_frame = ttk.LabelFrame(tab_config, text=" 自定义样式设置 ", padding=20)
config_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)
# 字体选择行
tk.Label(config_frame, text="字体名称", font=("微软雅黑", 10, "bold")).grid(row=0, column=1, padx=40)
tk.Label(config_frame, text="字号(磅)", font=("微软雅黑", 10, "bold")).grid(row=0, column=2, padx=20)
# 标题配置
tk.Label(config_frame, text="文档大标题:", fg="blue").grid(row=1, column=0, sticky=tk.W, pady=10)
self.title_font = ttk.Combobox(config_frame, values=[
'方正小标宋_GBK', '黑体', '宋体', '微软雅黑'
], width=15)
self.title_font.set(CONFIG["fonts"]["title"])
self.title_font.grid(row=1, column=1)
self.title_size = ttk.Combobox(config_frame, values=[16, 18, 20, 22, 24, 26, 28], width=8)
self.title_size.set(CONFIG["font_sizes"]["title"])
self.title_size.grid(row=1, column=2)
# 一级标题
tk.Label(config_frame, text="一级标题(一、):", fg="darkgreen").grid(row=2, column=0, sticky=tk.W, pady=10)
self.l1_font = ttk.Combobox(config_frame, values=[
'黑体', '方正小标宋_GBK', '楷体_GB2312'
], width=15)
self.l1_font.set(CONFIG["fonts"]["heading_1"])
self.l1_font.grid(row=2, column=1)
self.l1_size = ttk.Combobox(config_frame, values=[14, 15, 16, 17, 18], width=8)
self.l1_size.set(CONFIG["font_sizes"]["heading_1"])
self.l1_size.grid(row=2, column=2)
# 二级标题
tk.Label(config_frame, text="二级标题((一)):", fg="purple").grid(row=3, column=0, sticky=tk.W, pady=10)
self.l2_font = ttk.Combobox(config_frame, values=[
'楷体_GB2312', '仿宋_GB2312', '黑体'
], width=15)
self.l2_font.set(CONFIG["fonts"]["heading_2"])
self.l2_font.grid(row=3, column=1)
self.l2_size = ttk.Combobox(config_frame, values=[14, 15, 16, 17, 18], width=8)
self.l2_size.set(CONFIG["font_sizes"]["heading_2"])
self.l2_size.grid(row=3, column=2)
# 正文配置
tk.Label(config_frame, text="正文/三级标题:", fg="gray").grid(row=4, column=0, sticky=tk.W, pady=10)
self.body_font = ttk.Combobox(config_frame, values=[
'仿宋_GB2312', '宋体', '黑体'
], width=15)
self.body_font.set(CONFIG["fonts"]["body"])
self.body_font.grid(row=4, column=1)
self.body_size = ttk.Combobox(config_frame, values=[14, 15, 16, 17, 18], width=8)
self.body_size.set(CONFIG["font_sizes"]["body"])
self.body_size.grid(row=4, column=2)
# 操作按钮
opt_frame = tk.Frame(config_frame)
opt_frame.grid(row=5, column=0, columnspan=3, pady=30)
tk.Button(opt_frame, text="💾 保存配置", command=self.save_config,
bg="#17A2B8", fg="white", width=15).pack(side=tk.LEFT, padx=20)
tk.Button(opt_frame, text="🔙 恢复默认", command=self.reset_config,
bg="#6C757D", fg="white", width=15).pack(side=tk.LEFT, padx=20)
def browse_input(self):
file_path = filedialog.askopenfilename(
title="选择Word文档",
filetypes=[("Word文档", "*.docx *.doc"), ("All Files", "*.*")]
)
if file_path:
self.input_entry.delete(0, tk.END)
self.input_entry.insert(0, file_path)
def browse_output(self):
dir_path = filedialog.askdirectory()
if dir_path:
self.output_entry.delete(0, tk.END)
self.output_entry.insert(0, dir_path)
def save_config(self):
"""保存用户自定义的字体设置"""
try:
CONFIG["fonts"]["title"] = self.title_font.get()
CONFIG["fonts"]["heading_1"] = self.l1_font.get()
CONFIG["fonts"]["heading_2"] = self.l2_font.get()
CONFIG["fonts"]["body"] = self.body_font.get()
CONFIG["font_sizes"]["title"] = int(self.title_size.get())
CONFIG["font_sizes"]["heading_1"] = int(self.l1_size.get())
CONFIG["font_sizes"]["heading_2"] = int(self.l2_size.get())
CONFIG["font_sizes"]["body"] = int(self.body_size.get())
self.status_var.set("✅ 配置已更新,下次处理生效")
messagebox.showinfo("成功", "字体配置已保存!")
except Exception as e:
messagebox.showerror("错误", f"配置保存失败: {e}")
def reset_config(self):
"""恢复默认配置"""
# 这里直接写死默认值
self.title_font.set('方正小标宋_GBK')
self.l1_font.set('黑体')
self.l2_font.set('楷体_GB2312')
self.body_font.set('仿宋_GB2312')
self.title_size.set(22)
self.l1_size.set(16)
self.l2_size.set(16)
self.body_size.set(16)
self.save_config()
self.status_var.set("⚙️ 已恢复默认设置")
def start_process(self):
input_file = self.input_entry.get()
output_dir = self.output_entry.get()
if not input_file or not output_dir:
messagebox.showwarning("警告", "请输入文件路径和输出目录!")
return
if not os.path.exists(input_file):
messagebox.showerror("错误", "输入文件不存在!")
return
# 生成输出路径
filename = os.path.basename(input_file)
name, ext = os.path.splitext(filename)
output_file = os.path.join(output_dir, f"{name}_已排版{ext}")
self.status_var.set("🔄 正在处理中 (可能需要几秒)...")
self.root.update_idletasks()
success, msg = process_document(input_file, output_file)
if success:
self.status_var.set("✅ 处理完成!")
messagebox.showinfo("成功", f"任务完成!\n\n{msg}")
else:
self.status_var.set("❌ 处理失败")
messagebox.showerror("错误", f"处理失败:\n{msg}")
if __name__ == "__main__":
root = tk.Tk()
app = ModernTypesettingApp(root)
root.mainloop()使用前准备
1.安装依赖:如果你有 .doc 文件需要处理,请务必在终端运行:
pip install pywin32
(如果没有 .doc 文件,只处理 .docx,则不需要安装)
2.字体库:代码中使用了 仿宋_GB2312 和 楷体_GB2312。如果你的电脑(特别是非Windows系统)没有这些字体,WPS 可能会显示异常。如果报错,可以在配置界面手动选择系统中已有的字体(如“仿宋”、“楷体”)。
功能说明
- Tab 1 (文档处理):选择你的
.doc或.docx文件,点击开始。 - Tab 2 (字体配置):你可以在这里修改“文档大标题”、“一级标题”、“二级标题”和“正文”的字体及大小。修改后点击“保存配置”,下次处理文档时就会生效。
以上就是基于Python自动化实现Word文档专业排版的详细内容,更多关于Python Word文档排版的资料请关注脚本之家其它相关文章!
相关文章
Python 如何手动编写一个自己的LRU缓存装饰器的方法实现
本文主要介绍了Python如何手动编写一个自己的LRU缓存装饰器,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2021-12-12
在python中logger setlevel没有生效的解决
今天小编就为大家分享一篇在python中logger setlevel没有生效的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-02-02
Python实现http服务器(http.server模块传参 接收参数)实例
这篇文章主要为大家介绍了Python实现http服务器(http.server模块传参 接收参数)实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-11-11
浅析Python中getattr和getattribute的调用
在Python中,getattr和getattribute是两个用于属性访问的重要函数,它们可以在运行时动态地获取对象的属性或自定义属性访问行为,下面我们就来学习一下它们的具体用法吧2023-11-11
Python报错TypeError: tuple indices must be
在Python编程过程中,我们经常会遇到各种各样的报错信息,其中,“TypeError: tuple indices must be integers or slices, not str”这个报错,对于很多开发者来说,可能既熟悉又陌生,今天,我们就来深入探讨一下这个报错,看看它是如何产生的,以及如何快速有效地解决它2025-01-01
Python tkinter分隔控件(Seperator)的使用
这篇文章主要介绍了Python tkinter分隔控件(Seperator)的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-04-04


最新评论