Use the python-docx library to precisely manipulate Word document formatting, suitable for format analysis, format normalization, and batch modification.
Core Rules
Execute immediately when invoked:
- Confirm file path: Ask the user for the full path of the Word document
- Clarify requirements: Confirm whether it is format analysis or format modification, and what the target specification is
- Select template: Choose an appropriate code template or script based on requirements
- Generate script: Create a standalone Python script file
- Execute and verify: Use
uv runto execute and check results
Mandatory Constraints:
- ✓ Must use
uv run --with python-docx python3 script.py - ✓ Must handle
doc.paragraphsanddoc.tables(document body is often inside tables) - ✓ Must set separately Chinese and English fonts (use
qn('w:eastAsia')) - ✓ Must ask the user for the file path and output path
- ✗ Prohibited to use directly
pythoncommand (missing dependencies) - ✗ Prohibited to omit table content processing (common mistake)
When to Use
Trigger Scenarios:
- Analyze Word document formatting (font/font size/indentation/line spacing)
- Batch-modify document formatting
- Unify typesetting specifications (academic papers, reports, etc.)
- Handle mixed Chinese and English fonts
- Modify cross-reference/reference styles
Trigger Keywords: modify Word formatting, unify fonts, adjust indentation, analyze document formatting, reference formatting
Decision Tree
用户需求是什么?
├─ 不清楚当前格式 → 使用 scripts/analyze.py
├─ 应用公文标准 → 使用 scripts/format_official.py
├─ 应用学术标准 → 使用 scripts/format_academic.py
├─ 统一正文格式 → 使用【快速模板:批量格式化】
├─ 修改参考文献 → 使用【快速模板:参考文献处理】
└─ 自定义需求 → 基于【基础模板】组合
Quick Start
Basic Template
from docx import Document
from docx.shared import Pt
from docx.oxml.ns import qn
doc = Document('input.docx')
def set_font(run, cn='宋体', en='Times New Roman', size=10.5):
"""设置中英文字体"""
run.font.name = en
run._element.rPr.rFonts.set(qn('w:eastAsia'), cn)
run.font.size = Pt(size)
def process_all_paragraphs(doc, process_func):
"""遍历所有段落(包括表格内)"""
for para in doc.paragraphs:
process_func(para)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
process_func(para)
# 使用示例
def format_para(para):
para.paragraph_format.first_line_indent = Pt(21)
for run in para.runs:
set_font(run, cn='宋体', en='Times New Roman', size=10.5)
process_all_paragraphs(doc, format_para)
doc.save('output.docx')
Quick Template: Batch Formatting
from docx import Document
from docx.shared import Pt
from docx.oxml.ns import qn
doc = Document('input.docx')
for para in doc.paragraphs:
if len(para.text.strip()) > 30:
para.paragraph_format.first_line_indent = Pt(21)
para.paragraph_format.line_spacing = 1.5
for run in para.runs:
run.font.name = 'Times New Roman'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
run.font.size = Pt(10.5)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
if len(para.text.strip()) > 30:
para.paragraph_format.first_line_indent = Pt(21)
for run in para.runs:
run.font.name = 'Times New Roman'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
run.font.size = Pt(10.5)
doc.save('output.docx')
Quick Template: Reference Processing
from docx import Document
from docx.shared import Pt, RGBColor
import re
doc = Document('input.docx')
ref_pattern = re.compile(r'\[\d+\]')
for para in doc.paragraphs:
if para.text.strip().startswith('[') and ']' in para.text[:5]:
para.paragraph_format.first_line_indent = Pt(-21)
para.paragraph_format.left_indent = Pt(21)
for run in para.runs:
if ref_pattern.search(run.text):
run.font.color.rgb = RGBColor(0, 0, 255)
doc.save('output.docx')
Execution Checklist
Before generating the script:
- The file path provided by the user has been confirmed
- The target format specification has been clarified
- An appropriate template or script has been selected
The script must include:
- Handle both
doc.paragraphsanddoc.tables - Use
qn('w:eastAsia')to set Chinese fonts - Correct input/output file paths
Remind the user before execution:
- Back up the original file or use a different output file name
- Confirm the file is not open in another program
Execute command:
uv run --with python-docx python3 script.py
Common Errors
| Error | Cause | Solution |
|---|---|---|
| Modification not taking effect | Table content omitted | Check whether doc.tables |
| Chinese font incorrect | Did not use qn('w:eastAsia') |
Chinese fonts must be set separately |
| File open failed | Wrong path or file in use | Check the path, close Word |
| Missing dependency | Did not use uv run |
Use the full command |
Related Documentation
- STANDARDS.md - Default format standards (official documents/academic papers) and parameter quick reference
- EXAMPLES.md - Detailed example code (multi-level headings, tables, images, headers and footers, etc.)
- scripts/ - Preset tool scripts (analysis, official document formatting, academic formatting)
Markdown to DOCX
Read Markdown documents directly and write them to DOCX according to formatting requirements, without pandoc.
Basic Template
from docx import Document
from docx.shared import Pt
from docx.oxml.ns import qn
from docx.enum.text import WD_ALIGN_PARAGRAPH
import re
doc = Document()
def add_heading(doc, text, level):
"""添加标题"""
para = doc.add_paragraph(text)
if level == 1:
para.alignment = WD_ALIGN_PARAGRAPH.CENTER
for run in para.runs:
run.font.name = 'Arial'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
run.font.size = Pt(15)
run.font.bold = True
elif level == 2:
para.alignment = WD_ALIGN_PARAGRAPH.LEFT
for run in para.runs:
run.font.name = 'Arial'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
run.font.size = Pt(14)
run.font.bold = True
elif level == 3:
para.alignment = WD_ALIGN_PARAGRAPH.LEFT
for run in para.runs:
run.font.name = 'Arial'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
run.font.size = Pt(12)
run.font.bold = True
def add_paragraph(doc, text):
"""添加正文段落"""
para = doc.add_paragraph(text)
para.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
para.paragraph_format.first_line_indent = Pt(24)
para.paragraph_format.line_spacing = 1.5
for run in para.runs:
run.font.name = 'Times New Roman'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
run.font.size = Pt(12)
# 读取 Markdown
with open('input.md', 'r', encoding='utf-8') as f:
for line in f:
line = line.rstrip()
if not line:
continue
# 标题
if line.startswith('# '):
add_heading(doc, line[2:], 1)
elif line.startswith('## '):
add_heading(doc, line[3:], 2)
elif line.startswith('### '):
add_heading(doc, line[4:], 3)
# 正文
else:
add_paragraph(doc, line)
doc.save('output.docx')
Use Preset Scripts:
uv run --with python-docx python3 .claude/skills/docx-format/scripts/md_to_docx.py input.md output.docx
Notes
- Only .docx is supported: Legacy .doc is not supported
- Table content: The main text of academic papers, reports, etc. is often inside tables and must be handled
- Unit conversion:
font.sizeReturns EMU and requires conversion (÷ 914400 × 72) - Back up original files: It is recommended to back up before modification
- Markdown conversion: Use pandoc for conversion, then format