查看: 188|回复: 3

Python-docx实战:批量生成合同与提取简历信息的自动化方案

[复制链接]
发表于 4 小时前 | 显示全部楼层 |阅读模式
在办公自动化场景中,批量处理Word文档——无论是生成几十份合同模板、从几百份简历里提取关键信息,还是将表格数据导出为报告——都是高频需求。Python的python-docx库提供了读取、写入和格式修改的核心能力,结合pandas、正则表达式等工具,可以构建完整的Word文档自动化处理流程。

一、安装与基本操作
使用pip安装python-docx:
  1. pip install python-docx
复制代码
导入Document类即可操作文档:
  1. from docx import Document
  2. # 打开已有文档
  3. doc = Document("报告.docx")
  4. # 创建新文档
  5. doc2 = Document()
  6. doc2.save("新文档.docx")
复制代码

二、读取Word文档内容
python-docx支持读取段落、表格和标题。以下示例展示了如何提取文档中的各类信息:
  1. from docx import Document
  2. doc = Document("报告.docx")
  3. # 1. 读取所有非空段落
  4. print("=== 段落内容 ===")
  5. for i, para in enumerate(doc.paragraphs):
  6.     if para.text.strip():
  7.         print(f"段落{i}: {para.text.strip()}")
  8. # 2. 读取表格内容
  9. print("\n=== 表格内容 ===")
  10. for t_idx, table in enumerate(doc.tables):
  11.     print(f"\n--- 表格 {t_idx + 1} ---")
  12.     for r_idx, row in enumerate(table.rows):
  13.         cells = [cell.text for cell in row.cells]
  14.         print(f"第{r_idx + 1}行: {cells}")
  15. # 3. 读取标题(样式以Heading开头的段落)
  16. print("\n=== 标题 ===")
  17. for para in doc.paragraphs:
  18.     if para.style.name.startswith("Heading"):
  19.         print(f"[{para.style.name}] {para.text}")
复制代码
这个功能常用于批量读取简历等文档中的特定字段,如姓名、电话、学历等。

三、写入Word文档
1. 添加段落与格式
可以添加不同级别的标题、普通段落,并对文字进行颜色、字号、加粗等设置:
  1. from docx import Document
  2. from docx.shared import Pt, RGBColor
  3. from docx.enum.text import WD_ALIGN_PARAGRAPH
  4. doc = Document()
  5. doc.add_heading("工作报告", level=0)
  6. doc.add_heading("一、项目概况", level=1)
  7. doc.add_heading("1.1 项目背景", level=2)
  8. para = doc.add_paragraph("这是正文内容。")
  9. para.alignment = WD_ALIGN_PARAGRAPH.LEFT
  10. para2 = doc.add_paragraph()
  11. run = para2.add_run("红色加粗文字")
  12. run.bold = True
  13. run.font.size = Pt(14)
  14. run.font.color.rgb = RGBColor(255, 0, 0)
  15. run2 = para2.add_run(" 普通后续文字")
  16. run2.font.size = Pt(12)
  17. doc.save("输出文档.docx")
复制代码

2. 添加表格并设置列宽
创建表格、填充表头和数据,还可以逐列设定宽度:
  1. from docx import Document
  2. from docx.shared import Pt, Cm
  3. doc = Document()
  4. doc.add_heading("学生成绩表", level=1)
  5. table = doc.add_table(rows=3, cols=4, style="Table Grid")
  6. headers = ["姓名", "语文", "数学", "英语"]
  7. for i, h in enumerate(headers):
  8.     cell = table.rows[0].cells[i]
  9.     cell.text = h
  10.     for para in cell.paragraphs:
  11.         for run in para.runs:
  12.             run.bold = True
  13. data = [
  14.     ["张三", "85", "92", "78"],
  15.     ["李四", "90", "88", "95"],
  16. ]
  17. for r_idx, row_data in enumerate(data):
  18.     for c_idx, value in enumerate(row_data):
  19.         table.rows[r_idx + 1].cells[c_idx].text = value
  20. for row in table.rows:
  21.     row.cells[0].width = Cm(3)
  22.     row.cells[1].width = Cm(3)
  23.     row.cells[2].width = Cm(3)
  24.     row.cells[3].width = Cm(3)
  25. doc.save("成绩表.docx")
复制代码

3. 设置页边距
通过遍历sections可以调整页边距,单位使用Cm:
  1. from docx.shared import Cm
  2. doc = Document()
  3. for section in doc.sections:
  4.     section.top_margin = Cm(2.54)
  5.     section.bottom_margin = Cm(2.54)
  6.     section.left_margin = Cm(3.17)
  7.     section.right_margin = Cm(3.17)
复制代码

四、实战案例:批量生成劳动合同
典型场景是“模板 + 数据”批量输出文档。首先准备员工数据CSV文件(employees.csv):
  1. name,department,position,salary,start_date
  2. 张三,技术部,Java开发工程师,15000,2024-01-01
  3. 李四,产品部,产品经理,13000,2024-02-15
  4. 王五,市场部,市场专员,10000,2024-03-01
复制代码
然后创建Word模板,在需要填充的位置使用{{name}}、{{department}}等占位符。以下脚本读取CSV并批量生成合同:
  1. import pandas as pd
  2. from docx import Document
  3. from datetime import datetime
  4. import os
  5. def generate_contract(employee):
  6.     """根据员工数据生成劳动合同"""
  7.     doc = Document("合同模板.docx")
  8.    
  9.     replacements = {
  10.         "{{name}}": employee["name"],
  11.         "{{department}}": employee["department"],
  12.         "{{position}}": employee["position"],
  13.         "{{salary}}": str(employee["salary"]),
  14.         "{{start_date}}": employee["start_date"],
  15.         "{{today}}": datetime.now().strftime("%Y年%m月%d日"),
  16.     }
  17.    
  18.     for para in doc.paragraphs:
  19.         for key, value in replacements.items():
  20.             if key in para.text:
  21.                 for run in para.runs:
  22.                     if key in run.text:
  23.                         run.text = run.text.replace(key, value)
  24.    
  25.     output_dir = "合同输出"
  26.     os.makedirs(output_dir, exist_ok=True)
  27.     filename = f"{output_dir}/{employee['name']}_劳动合同.docx"
  28.     doc.save(filename)
  29.     print(f"已生成: {filename}")
  30. # 批量生成
  31. df = pd.read_csv("employees.csv")
  32. for _, emp in df.iterrows():
  33.     generate_contract(emp)
复制代码

五、实战案例:从多份简历提取信息
遍历文件夹中的.docx简历,利用正则表达式提取姓名、手机号、邮箱、毕业院校等信息,并汇总输出到Excel:
  1. from docx import Document
  2. import re
  3. import os
  4. def extract_resume_info(docx_path):
  5.     """从简历Word文档提取关键信息"""
  6.     doc = Document(docx_path)
  7.     full_text = "\n".join([p.text for p in doc.paragraphs])
  8.     info = {}
  9.    
  10.     # 姓名通常在首行
  11.     lines = [p.text.strip() for p in doc.paragraphs if p.text.strip()]
  12.     if lines:
  13.         info["姓名"] = lines[0]
  14.    
  15.     # 手机号:11位数字,以1开头
  16.     phone = re.search(r"1[3-9]\d{9}", full_text)
  17.     info["手机号"] = phone.group() if phone else ""
  18.    
  19.     # 邮箱
  20.     email = re.search(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", full_text)
  21.     info["邮箱"] = email.group() if email else ""
  22.    
  23.     # 毕业院校(包含“大学”或“学院”)
  24.     schools = re.findall(r"[一-龥]+(?:大学|学院)", full_text)
  25.     info["毕业院校"] = schools[0] if schools else ""
  26.    
  27.     return info
  28. # 批量处理
  29. resume_dir = "简历文件夹"
  30. results = []
  31. for filename in os.listdir(resume_dir):
  32.     if filename.endswith(".docx"):
  33.         filepath = os.path.join(resume_dir, filename)
  34.         try:
  35.             info = extract_resume_info(filepath)
  36.             info["文件名"] = filename
  37.             results.append(info)
  38.             print(f"已处理: {filename}")
  39.         except Exception as e:
  40.             print(f"处理失败 {filename}: {e}")
  41. import pandas as pd
  42. df = pd.DataFrame(results)
  43. df.to_excel("简历汇总.xlsx", index=False)
  44. print(f"共处理 {len(results)} 份简历,结果已导出到 简历汇总.xlsx")
复制代码

六、常用格式设置
python-docx支持丰富的格式控制:
  1. from docx.shared import Pt, Cm, Inches, RGBColor
  2. from docx.enum.text import WD_ALIGN_PARAGRAPH
  3. from docx.enum.table import WD_TABLE_ALIGNMENT
  4. # 字体设置
  5. run.font.name = "微软雅黑"
  6. run.font.size = Pt(12)
  7. run.bold = True
  8. run.italic = True
  9. run.font.color.rgb = RGBColor(0, 0, 0)
  10. # 段落设置
  11. para.alignment = WD_ALIGN_PARAGRAPH.CENTER
  12. para.paragraph_format.space_before = Pt(12)
  13. para.paragraph_format.space_after = Pt(12)
  14. para.paragraph_format.line_spacing = 1.5
  15. para.paragraph_format.first_line_indent = Cm(0.74)
  16. # 表格设置
  17. table.alignment = WD_TABLE_ALIGNMENT.CENTER
  18. cell.vertical_alignment = 1  # 垂直居中
复制代码

七、常见问题与解决方案
1. python-docx不支持.doc格式
.doc是旧版Word格式,python-docx只能处理.docx。可以先用Word手动另存为.docx,或使用win32com在Windows下转换:
  1. import win32com.client
  2. word = win32com.client.Dispatch("Word.Application")
  3. doc = word.Documents.Open("旧文档.doc")
  4. doc.SaveAs("新文档.docx", FileFormat=16)  # 16 = wdFormatDocumentDefault
  5. doc.Close()
  6. word.Quit()
复制代码

2. 图片操作
插入图片:
  1. from docx.shared import Inches
  2. doc.add_picture("图表.png", width=Inches(5))
复制代码
提取文档中的图片需解压docx文件:
  1. import zipfile
  2. import os
  3. with zipfile.ZipFile("文档.docx", "r") as z:
  4.     for name in z.namelist():
  5.         if name.startswith("word/media/"):
  6.             z.extract(name, "提取的图片/")
复制代码

八、与其他库搭配使用
python-docx常与pandas、matplotlib、python-pptx、PDFPlumber等配合,构建自动化报告流程。典型流程是:pandas读取数据 → matplotlib生成图表 → docx插入图表和文本。示例:
  1. import pandas as pd
  2. from docx import Document
  3. from docx.shared import Inches
  4. import matplotlib.pyplot as plt
  5. df = pd.read_excel("销售数据.xlsx")
  6. summary = df.groupby("月份")["金额"].sum()
  7. plt.figure(figsize=(8, 4))
  8. summary.plot(kind="bar")
  9. plt.title("月度销售汇总")
  10. plt.savefig("chart.png")
  11. doc = Document()
  12. doc.add_heading("月度销售报告", level=0)
  13. doc.add_paragraph(f"本月总销售额: {summary.sum():.2f} 元")
  14. doc.add_picture("chart.png", width=Inches(5))
  15. doc.save("销售报告.docx")
复制代码

总结
python-docx的核心能力集中在读取内容、写入内容、修改格式。日常办公中80%的Word自动化需求都可以通过这些基础操作满足:批量生成依赖模板和数据替换,批量提取依赖遍历文件夹和正则表达式,批量转换则是读取数据、转换格式后输出。做好Word模板的排版,是保证生成文档质量的关键第一步。
回复

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: Python-docx实战:批量生成合同与提取简历信息的自动化方案

这篇教程写得很详细,python-docx 的段落、表格、格式控制都讲到了,对批量生成合同和提取简历的场景非常实用。特别是读取表格和通过样式筛选标题的代码,可以直接拿来改。想问一下,如果合同模板里有很多占位符(比如 {姓名}、{金额}),用 python-docx 做替换时有没有比较高效的处理思路?是直接遍历段落和表格去替换字符串,还是配合其他库来做?期待后续能分享一下模板变量替换的经验。
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: Python-docx实战:批量生成合同与提取简历信息的自动化方案

感谢楼主分享这么详细的教程!python-docx 确实是做 Word 自动化的利器,我把你这几段代码的逻辑理了一遍,感觉上班时批量填合同、从简历里扒信息都能直接套用,非常实用。特别是读取表格和段落的部分,配合 pandas 做数据清洗应该很顺畅。 有个小疑问想请教:添加表格时如果数据量比较大(比如几百行),直接用 `add_table` 性能会不会下降?有没有什么批量写入的优化技巧?比如先建一行再逐 row 追加,或者用 `add_row` 循环插入?期待楼主进一步指点。
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: Python-docx实战:批量生成合同与提取简历信息的自动化方案

感谢分享!这套方案很实用,特别是表格读写和格式设置的部分,正好解决了我批量处理合同模板时遇到的痛点。想请教一下,如果要把从简历里提取的信息自动填充到合同对应占位符中,用python-docx结合正则表达式一般怎么设计匹配逻辑?另外,生成大量文档时有没有遇到内存占用过高的情况?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-29 14:00 , Processed in 0.042006 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部