
第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日' }
|
模板示例:
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日'} ]
|
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,实现以下功能:
- 提供合同模板
- 接收客户信息(公司名称、联系人、金额等)
- 自动填充模板生成合同
- 保存为 Word 文档
练习 2:批量邀请函
创建一个 Skill,实现以下功能:
- 读取嘉宾名单(Excel 或 CSV)
- 使用邀请函模板
- 批量生成个性化邀请函
- 保存为单独的 Word 文件
练习 3:文档格式统一
创建一个 Skill,实现以下功能:
- 接收 Word 文档或文件夹
- 统一设置字体(正文宋体小四,标题黑体)
- 统一设置行间距(1.5倍)
- 统一设置页边距
- 保存修改后的文档
七、常见问题
Q1:中文字体显示异常怎么办?
解决方案:
- 明确设置中文字体名称
- 使用
qn('w:eastAsia') 设置东亚字体 - 确保系统安装了相应字体
Q2:如何保留原模板的样式?
解决方案:
- 使用
docxtpl 而不是直接操作 python-docx - 在模板中预定义好样式
- 只填充变量内容,不修改样式
Q3:批量处理大量文档时内存不足?
解决方案:
- 分批处理,处理完一批保存一批
- 及时关闭不再使用的文档对象
- 考虑使用生成器模式
八、下节预告
下一讲我们将学习 OCR 文字识别 Skill 开发,包括:
- 图片文字识别
- PDF 扫描件识别
- 表格识别与提取
- 批量 OCR 处理
加入学习群
👉 加入AI编程学习交流群

本讲是《AI Skills 从入门到实践》系列课程的第15讲。
🎓 AI 编程实战课程
想系统学习 AI 编程?程序员晚枫的 AI 编程实战课 帮你从零上手!