第15讲:Word 文档处理 Skill 开发

第15讲:Word 文档处理 Skill 开发

掌握 Word 文档的自动化处理技能,实现文档生成、格式调整、内容提取等操作,大幅提升文档处理效率。

一、场景分析

1.1 用户痛点

Word 是办公中最常用的文档工具,但重复性工作很多:

  • 文档生成耗时:合同、报告、通知等需要反复编写相似内容
  • 格式调整繁琐:统一全文字体、段落、标题样式费时费力
  • 模板填充低效:邮件合并、批量生成文档操作复杂
  • 内容提取困难:从大量文档中提取特定信息效率低
  • 批量处理不便:多个文档需要统一修改格式或内容

1.2 典型应用场景

场景需求描述Skill 价值
合同生成根据模板和数据批量生成合同一键批量生成
报告撰写自动整理数据并生成分析报告数据自动填充
通知发布批量生成个性化通知文档邮件合并功能
文档归档提取文档关键信息建立索引内容智能提取
格式统一批量修改文档格式和样式自动化格式调整

二、核心功能设计

2.1 Skill 功能架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
📝 Word 智能助手
├── 文档生成
│ ├── 模板填充
│ ├── 内容生成
│ ├── 目录生成
│ └── 页眉页脚
├── 格式处理
│ ├── 样式统一
│ ├── 字体调整
│ ├── 段落设置
│ └── 页面布局
├── 内容操作
│ ├── 文字提取
│ ├── 表格提取
│ ├── 图片提取
│ └── 批注处理
├── 批量处理
│ ├── 批量替换
│ ├── 批量转换
│ ├── 批量合并
│ └── 批量拆分
└── 高级功能
├── 邮件合并
├── 修订追踪
├── 文档保护
└── 宏命令

2.2 技术选型

Word 处理的核心技术栈:

功能Python 库说明
Word 操作python-docx创建、修改 Word 文档
模板处理docxtpl基于 Jinja2 的模板填充
格式转换pandoc / LibreOffice格式互转
内容提取python-docx / textract提取文字、表格

三、技术实现

3.1 Coze 平台实现

3.1.1 基础操作代码

创建 Word 文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn

def create_document():
"""创建新的 Word 文档"""
doc = Document()

# 设置默认字体
doc.styles['Normal'].font.name = '微软雅黑'
doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')

return doc

def add_heading(doc, text, level=1):
"""
添加标题

Args:
doc: Document 对象
text: 标题文字
level: 标题级别 (1-9)
"""
heading = doc.add_heading(text, level=level)

# 设置中文字体
for run in heading.runs:
run.font.name = '微软雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')

return heading

def add_paragraph(doc, text, style=None, alignment=None):
"""
添加段落

Args:
doc: Document 对象
text: 段落文字
style: 段落样式
alignment: 对齐方式
"""
p = doc.add_paragraph(text, style=style)

if alignment:
p.alignment = alignment

# 设置中文字体
for run in p.runs:
run.font.name = '微软雅黑'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')

return p

添加表格:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def add_table(doc, data, style='Light Grid Accent 1'):
"""
添加表格

Args:
doc: Document 对象
data: 二维列表,表格数据
style: 表格样式
"""
if not data or not data[0]:
return None

rows = len(data)
cols = len(data[0])

table = doc.add_table(rows=rows, cols=cols)
table.style = style

# 填充数据
for i, row_data in enumerate(data):
row = table.rows[i]
for j, cell_data in enumerate(row_data):
row.cells[j].text = str(cell_data)

return table

添加图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def add_image(doc, image_path, width=None, height=None):
"""
添加图片

Args:
doc: Document 对象
image_path: 图片路径
width: 宽度(Inches 对象)
height: 高度(Inches 对象)
"""
if width:
doc.add_picture(image_path, width=width)
elif height:
doc.add_picture(image_path, height=height)
else:
doc.add_picture(image_path)

return doc

3.1.2 模板填充代码

使用 docxtpl 进行模板填充:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from docxtpl import DocxTemplate

def fill_template(template_path, data, output_path):
"""
填充 Word 模板

Args:
template_path: 模板文件路径
data: 填充数据字典
output_path: 输出文件路径
"""
doc = DocxTemplate(template_path)
doc.render(data)
doc.save(output_path)
return output_path

# 示例:合同模板填充
contract_data = {
'contract_no': 'HT2024001',
'party_a': '甲方公司名称',
'party_b': '乙方公司名称',
'amount': '¥100,000',
'start_date': '2024年1月1日',
'end_date': '2024年12月31日',
'sign_date': '2024年1月1日'
}

# fill_template('contract_template.docx', contract_data, 'contract_filled.docx')

模板示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
合同编号:{{ contract_no }}

甲方:{{ party_a }}
乙方:{{ party_b }}

经双方友好协商,达成以下协议:

一、合同金额
本合同总金额为 {{ amount }}。

二、合同期限
自 {{ start_date }} 起至 {{ end_date }} 止。

三、签署日期
本合同于 {{ sign_date }} 签署。

甲方(盖章):___________ 乙方(盖章):___________

3.1.3 邮件合并代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def mail_merge(template_path, data_list, output_prefix):
"""
邮件合并 - 批量生成文档

Args:
template_path: 模板文件路径
data_list: 数据列表,每个元素是一个字典
output_prefix: 输出文件名前缀

Returns:
生成的文件路径列表
"""
output_files = []

for i, data in enumerate(data_list):
output_path = f"{output_prefix}_{i+1}.docx"
fill_template(template_path, data, output_path)
output_files.append(output_path)

return output_files

# 示例:批量生成邀请函
invitees = [
{'name': '张三', 'company': 'A公司', 'date': '2024年3月15日'},
{'name': '李四', 'company': 'B公司', 'date': '2024年3月15日'},
{'name': '王五', 'company': 'C公司', 'date': '2024年3月15日'}
]

# mail_merge('invitation_template.docx', invitees, 'invitation')

3.1.4 格式设置代码

设置段落格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from docx.shared import Pt, Inches
from docx.enum.text import WD_LINE_SPACING

def set_paragraph_format(paragraph,
font_size=12,
font_name='微软雅黑',
bold=False,
alignment=None,
line_spacing=1.5,
first_line_indent=None):
"""
设置段落格式

Args:
paragraph: 段落对象
font_size: 字体大小(磅)
font_name: 字体名称
bold: 是否加粗
alignment: 对齐方式
line_spacing: 行间距
first_line_indent: 首行缩进(Inches 对象)
"""
# 设置字体
for run in paragraph.runs:
run.font.size = Pt(font_size)
run.font.name = font_name
run._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)
run.font.bold = bold

# 设置对齐
if alignment:
paragraph.alignment = alignment

# 设置行间距
paragraph.paragraph_format.line_spacing = line_spacing

# 设置首行缩进
if first_line_indent:
paragraph.paragraph_format.first_line_indent = first_line_indent

设置页面布局:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from docx.shared import Inches

def set_page_layout(doc,
orientation='portrait',
margin_top=Inches(1),
margin_bottom=Inches(1),
margin_left=Inches(1.25),
margin_right=Inches(1.25)):
"""
设置页面布局

Args:
doc: Document 对象
orientation: 页面方向 ('portrait' 纵向 / 'landscape' 横向)
margin_top/bottom/left/right: 页边距
"""
sections = doc.sections

for section in sections:
# 设置页边距
section.top_margin = margin_top
section.bottom_margin = margin_bottom
section.left_margin = margin_left
section.right_margin = margin_right

# 设置页面方向
if orientation == 'landscape':
section.orientation = WD_ORIENT.LANDSCAPE
# 交换宽高
new_width = section.page_height
section.page_height = section.page_width
section.page_width = new_width

3.2 OpenClaw 平台实现

OpenClaw 的 Word Skill 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from openclaw import Skill, Tool
from docx import Document
from docxtpl import DocxTemplate

class WordSkill(Skill):
name = "Word智能助手"
description = "自动化处理 Word 文档"

@Tool
def create_document(self, title: str, content: list, output: str) -> str:
"""创建 Word 文档"""
doc = Document()

# 添加标题
doc.add_heading(title, level=1)

# 添加内容
for item in content:
if isinstance(item, dict):
if item.get('type') == 'heading':
doc.add_heading(item['text'], level=item.get('level', 2))
elif item.get('type') == 'paragraph':
doc.add_paragraph(item['text'])
elif item.get('type') == 'table':
table = doc.add_table(
rows=len(item['data']),
cols=len(item['data'][0])
)
for i, row_data in enumerate(item['data']):
for j, cell_data in enumerate(row_data):
table.rows[i].cells[j].text = str(cell_data)
else:
doc.add_paragraph(str(item))

doc.save(output)
return f"文档已生成: {output}"

@Tool
def fill_template(self, template: str, data: dict, output: str) -> str:
"""填充 Word 模板"""
doc = DocxTemplate(template)
doc.render(data)
doc.save(output)
return f"模板已填充: {output}"

@Tool
def batch_fill(self, template: str, data_list: list, output_prefix: str) -> list:
"""批量填充模板"""
output_files = []
for i, data in enumerate(data_list):
output = f"{output_prefix}_{i+1}.docx"
self.fill_template(template, data, output)
output_files.append(output)
return output_files

四、Prompt 设计

4.1 系统 Prompt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
你是 Word 智能助手,专门帮助用户自动化处理 Word 文档。

你可以执行以下操作:
1. 文档生成:根据内容创建 Word 文档
2. 模板填充:使用模板批量生成文档
3. 格式调整:统一字体、段落、页面样式
4. 内容提取:提取文字、表格、图片
5. 批量处理:批量替换、转换、合并

工作流程:
1. 理解用户的文档处理需求
2. 询问必要的参数(模板、数据、格式要求等)
3. 确认操作内容
4. 执行处理
5. 返回处理结果和文件

注意事项:
- 保持文档格式一致性
- 处理前备份重要文档
- 批量处理时提供进度反馈
- 注意中文字体兼容性

4.2 意图识别示例

用户输入识别意图提取参数
"帮我生成一份合同"文档生成合同类型、关键信息
"用模板批量生成邀请函"邮件合并模板路径、收件人列表
"把这几个 Word 合并成一个"文档合并文件列表
"统一调整文档格式"格式调整文件路径、格式要求
"提取这个文档里的表格"内容提取文件路径、提取类型

五、实战案例

5.1 案例一:合同批量生成

场景:法务部门需要根据客户信息批量生成销售合同。

解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def batch_generate_contracts(customer_data, template_path):
"""
批量生成销售合同

Args:
customer_data: 客户数据列表
template_path: 合同模板路径
"""
contracts = []

for i, customer in enumerate(customer_data):
contract_data = {
'contract_no': f'HT2024{i+1:04d}',
'party_a': '我方公司名称',
'party_b': customer['company_name'],
'contact_person': customer['contact'],
'phone': customer['phone'],
'product': customer['product'],
'quantity': customer['quantity'],
'unit_price': customer['unit_price'],
'total_amount': customer['quantity'] * customer['unit_price'],
'delivery_date': customer['delivery_date'],
'payment_terms': customer['payment_terms'],
'sign_date': customer['sign_date']
}

output_path = f"contract_{customer['company_name']}.docx"
fill_template(template_path, contract_data, output_path)
contracts.append(output_path)

return contracts

5.2 案例二:报告自动生成

场景:需要根据数据自动生成分析报告。

解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def generate_report(data, analysis_result, output_path):
"""
自动生成分析报告

Args:
data: 原始数据
analysis_result: 分析结果
output_path: 输出路径
"""
doc = Document()

# 封面
doc.add_heading('数据分析报告', level=1)
doc.add_paragraph(f'生成日期:{datetime.now().strftime("%Y年%m月%d日")}')
doc.add_page_break()

# 目录
doc.add_heading('目录', level=1)
toc_items = [
'一、数据概述',
'二、关键指标分析',
'三、趋势分析',
'四、结论与建议'
]
for item in toc_items:
doc.add_paragraph(item)
doc.add_page_break()

# 正文
doc.add_heading('一、数据概述', level=1)
doc.add_paragraph(f'本次分析共涉及 {len(data)} 条数据记录。')

doc.add_heading('二、关键指标分析', level=1)
# 添加指标表格
metrics_table = [
['指标', '数值', '同比'],
['总销售额', f"¥{analysis_result['total_sales']:,.2f}", f"{analysis_result['sales_yoy']:+.1%}"],
['订单数量', str(analysis_result['order_count']), f"{analysis_result['order_yoy']:+.1%}"],
['客单价', f"¥{analysis_result['avg_order_value']:,.2f}", f"{analysis_result['aov_yoy']:+.1%}"]
]
add_table(doc, metrics_table)

doc.add_heading('三、趋势分析', level=1)
# 添加分析内容
for trend in analysis_result['trends']:
doc.add_heading(trend['title'], level=2)
doc.add_paragraph(trend['description'])

doc.add_heading('四、结论与建议', level=1)
for suggestion in analysis_result['suggestions']:
doc.add_paragraph(suggestion, style='List Bullet')

doc.save(output_path)
return output_path

六、实战练习

练习 1:合同生成器

创建一个 Skill,实现以下功能:

  1. 提供合同模板
  2. 接收客户信息(公司名称、联系人、金额等)
  3. 自动填充模板生成合同
  4. 保存为 Word 文档

练习 2:批量邀请函

创建一个 Skill,实现以下功能:

  1. 读取嘉宾名单(Excel 或 CSV)
  2. 使用邀请函模板
  3. 批量生成个性化邀请函
  4. 保存为单独的 Word 文件

练习 3:文档格式统一

创建一个 Skill,实现以下功能:

  1. 接收 Word 文档或文件夹
  2. 统一设置字体(正文宋体小四,标题黑体)
  3. 统一设置行间距(1.5倍)
  4. 统一设置页边距
  5. 保存修改后的文档

七、常见问题

Q1:中文字体显示异常怎么办?

解决方案

  • 明确设置中文字体名称
  • 使用 qn('w:eastAsia') 设置东亚字体
  • 确保系统安装了相应字体

Q2:如何保留原模板的样式?

解决方案

  • 使用 docxtpl 而不是直接操作 python-docx
  • 在模板中预定义好样式
  • 只填充变量内容,不修改样式

Q3:批量处理大量文档时内存不足?

解决方案

  • 分批处理,处理完一批保存一批
  • 及时关闭不再使用的文档对象
  • 考虑使用生成器模式

八、下节预告

下一讲我们将学习 OCR 文字识别 Skill 开发,包括:

  • 图片文字识别
  • PDF 扫描件识别
  • 表格识别与提取
  • 批量 OCR 处理

加入学习群

👉 加入AI编程学习交流群

点击加入


本讲是《AI Skills 从入门到实践》系列课程的第15讲。

🎓 AI 编程实战课程

想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!