每次月底写周报的时候,你是不是也对着空白的Word文档发愁?作为程序员,我过去常常花半小时复制粘贴各种数据,调整格式,最后还要检查错别字。直到发现了python-docx这个神器,现在我的周报都是自动生成的,连格式都不用调。
python-docx是Python中操作Word文档的第三方库,它能让我们用代码完成所有手动操作。安装非常简单,只需要一行命令:
bash复制pip install python-docx
这个库最厉害的地方在于,它不仅能创建新文档,还能修改现有文档。想象一下,公司要发100份内容相似但客户信息不同的合同,传统做法是打开100次Word,一个个复制粘贴。用python-docx,写个脚本10分钟就能搞定。
我最近就用它帮财务部门自动化了发票生成系统。原来需要3个人花一整天的工作,现在服务器自动运行脚本,5分钟就能生成500份带不同客户信息的标准发票,准确率100%。财务总监看到效果后,立刻批准了IT部门的预算申请。
让我们从最基础的开始 - 创建一个空白文档。这个操作虽然简单,但却是所有自动化文档的基础。
python复制from docx import Document
doc = Document()
doc.save('first_document.docx')
运行这段代码,你会在当前目录下得到一个名为first_document.docx的空Word文件。虽然看起来简单,但这已经完成了自动化文档的第一步。
在实际项目中,我建议使用绝对路径保存文件,这样可以避免找不到文件的尴尬。比如:
python复制doc.save(r'D:\reports\2023\Q3\report_20230801.docx')
文档有了,接下来就是填充内容。python-docx提供了非常直观的方法来添加各种内容。
添加标题就像调用一个方法那么简单:
python复制doc.add_heading('2023年第三季度销售报告', level=0)
doc.add_heading('1. 销售概况', level=1)
level参数控制标题级别,0是最大的标题,数字越大级别越低。这和Word中的"标题1"、"标题2"样式是对应的。
段落是文档的主要内容载体。python-docx提供了多种添加段落的方式:
python复制# 简单段落
doc.add_paragraph('本季度销售额同比增长15%。')
# 带样式的段落
doc.add_paragraph('主要增长点:', style='Heading3')
# 多段落组合
p = doc.add_paragraph()
p.add_run('重点客户:').bold = True
p.add_run('A公司、B集团、C国际')
我特别喜欢add_run方法,它允许你在同一个段落中使用不同的格式。比如上面例子中,"重点客户:"是加粗的,后面的客户名称是普通文本。
基础内容有了,现在来让它看起来更专业。python-docx可以精确控制字体、颜色、大小等各种文本属性。
python复制from docx.shared import Pt, RGBColor
paragraph = doc.add_paragraph()
run = paragraph.add_run('重要数据:')
run.font.name = '微软雅黑'
run.font.size = Pt(14)
run.font.color.rgb = RGBColor(255, 0, 0) # 红色
run.font.bold = True
这段代码会创建一个段落,其中"重要数据:"这几个字是加粗的14号红色微软雅黑字体。在实际项目中,我通常会把这些样式定义成函数,方便重复使用:
python复制def add_highlight_text(doc, text):
p = doc.add_paragraph()
r = p.add_run(text)
r.font.color.rgb = RGBColor(255, 0, 0)
r.font.bold = True
return p
报告中最常用的就是表格了。python-docx创建表格非常简单:
python复制# 创建一个3行4列的表格
table = doc.add_table(rows=3, cols=4)
# 填充表头
header_cells = table.rows[0].cells
header_cells[0].text = '季度'
header_cells[1].text = '销售额'
header_cells[2].text = '同比增长'
header_cells[3].text = '完成率'
# 填充数据
data_rows = [
['Q1', '¥1,200万', '5%', '85%'],
['Q2', '¥1,500万', '12%', '95%'],
['Q3', '¥1,800万', '15%', '105%']
]
for row in range(1, 3):
cells = table.rows[row].cells
for col in range(4):
cells[col].text = data_rows[row-1][col]
在实际项目中,数据通常来自数据库或API,我会用循环自动填充表格。比如从SQL查询结果生成表格:
python复制import sqlite3
conn = sqlite3.connect('sales.db')
cursor = conn.cursor()
cursor.execute('SELECT quarter, amount, growth, completion FROM sales_data')
table = doc.add_table(rows=1, cols=4)
# 添加表头...
for row_data in cursor:
row_cells = table.add_row().cells
for i in range(4):
row_cells[i].text = str(row_data[i])
现在我们把前面学的知识综合起来,实现一个真正的自动化周报系统。假设我们需要每周生成包含以下内容的报告:
首先,我们创建一个模板函数:
python复制def generate_weekly_report(name, week, tasks, issues, plans, metrics):
doc = Document()
# 标题
doc.add_heading(f'{name}的{week}周工作周报', level=0)
# 本周工作
doc.add_heading('1. 本周工作内容', level=1)
for task in tasks:
doc.add_paragraph(task, style='ListBullet')
# 遇到的问题
doc.add_heading('2. 遇到的问题', level=1)
for issue in issues:
doc.add_paragraph(issue, style='ListBullet')
# 下周计划
doc.add_heading('3. 下周计划', level=1)
for plan in plans:
doc.add_paragraph(plan, style='ListBullet')
# 数据表格
doc.add_heading('4. 关键指标', level=1)
table = doc.add_table(rows=1, cols=2)
table.style = 'LightShading-Accent1'
# 表头
header = table.rows[0].cells
header[0].text = '指标'
header[1].text = '值'
# 数据行
for metric, value in metrics.items():
row = table.add_row().cells
row[0].text = metric
row[1].text = str(value)
# 保存
filename = f'{week}_{name}_周报.docx'
doc.save(filename)
return filename
然后从数据库或输入获取数据:
python复制# 示例数据
report_data = {
'name': '张三',
'week': '2023年第32周',
'tasks': [
'完成了用户模块开发',
'修复了登录页面bug',
'参与了需求评审会议'
],
'issues': [
'测试环境不稳定',
'需求变更频繁'
],
'plans': [
'开始订单模块开发',
'优化系统性能'
],
'metrics': {
'任务完成率': '95%',
'Bug解决率': '90%',
'代码提交量': '3200行'
}
}
generate_weekly_report(**report_data)
另一个常见需求是批量生成内容相似但部分信息不同的文档,比如合同、证书等。python-docx非常适合这种场景。
假设我们要给100个学员生成培训证书,步骤如下:
首先,创建模板文件template.docx,包含类似这样的内容:
code复制证书
兹证明{{name}}同学已完成本中心{{course}}课程的学习,
成绩合格,特发此证。
发证日期:{{date}}
然后编写批量生成代码:
python复制from docx import Document
import pandas as pd
from datetime import datetime
# 读取学员数据
students = pd.read_excel('students.xlsx')
# 处理每个学员
for _, student in students.iterrows():
# 打开模板
doc = Document('template.docx')
# 替换占位符
for paragraph in doc.paragraphs:
paragraph.text = paragraph.text.replace('{{name}}', student['姓名'])
paragraph.text = paragraph.text.replace('{{course}}', student['课程'])
paragraph.text = paragraph.text.replace('{{date}}', datetime.now().strftime('%Y年%m月%d日'))
# 保存
doc.save(f'certificates/{student["学号"]}_{student["姓名"]}_证书.docx')
我在实际项目中做过类似的批量合同生成系统,原本需要法务团队3天时间手动修改的200份合同,现在只需要运行脚本等5分钟,效率提升了几百倍。
对于更复杂的文档,比如包含多种样式、页眉页脚、分节符等,我们需要更精细地控制模板。python-docx可以处理这些高级功能。
比如要在页眉添加公司logo:
python复制from docx import Document
doc = Document('template.docx')
section = doc.sections[0]
header = section.header
paragraph = header.paragraphs[0]
paragraph.text = "Acme公司机密文件"
run = paragraph.add_run()
run.add_picture('logo.png', width=Inches(1))
处理分节符和不同页眉:
python复制# 添加分节符
doc.add_section()
# 获取新节
new_section = doc.sections[1]
# 设置不同的页眉
new_header = new_section.header
new_header.paragraphs[0].text = "第二部分"
当处理大量文档时,性能变得很重要。以下是我总结的几个优化技巧:
python复制base_doc = Document('template.docx')
for data in large_dataset:
doc = Document() # 新建空白文档
# 复制base_doc的所有内容到新文档
for element in base_doc.element.body:
doc.element.body.append(element)
# 处理当前文档
process_document(doc, data)
doc.save(f'output/{data.id}.docx')
减少保存操作:只在最后保存一次文档
使用多线程/多进程:对于特别大的批量任务
python复制from concurrent.futures import ThreadPoolExecutor
def process_single(data):
doc = generate_document(data)
doc.save(f'output/{data.id}.docx')
with ThreadPoolExecutor(max_workers=8) as executor:
executor.map(process_single, large_dataset)
python复制import gc
for i in range(1000):
doc = generate_large_document(data[i])
doc.save(f'docs/doc_{i}.docx')
del doc # 显式删除
gc.collect() # 建议垃圾回收
我在处理10000+文档的批量任务时,这些优化技巧将运行时间从2小时缩短到了15分钟。