乐于分享
好东西不私藏

用Python批量生成Word报表:Pandas + python-docx实战指南

用Python批量生成Word报表:Pandas + python-docx实战指南

在日常办公中,我们经常遇到这样的场景:有一份Word合同报告模板,里面有很多占位符(如{姓名}、{金额}),同时有一张Excel表格存储了所有需要填充的数据。如果只有三五份文档,手动复制粘贴还能忍受;但如果有成百上千份,那简直就是工作者的噩梦。

今天,我们就用Python的pandas和python-docx库,写一个批量生成Word文档的小工具。即使你刚接触Pandas,也能轻松看懂并应用到实际工作中。

一、代码功能与使用场景

核心功能:读取一个Word模板文件(内含占位符,比如{姓名}、{部门}),再读取一个Excel数据文件(每行代表一份文档的填充数据),自动为Excel中的每一行生成一份填充好的Word文档,并以Excel中指定的file_name列作为文件名保存。

 适用场景:批量生成员工工资单、录用通知书批量生成合同、报价单、邀请函任何“模板+数据”的文档自动化需求

二、完整代码速览

from docx import Documentimport pandas as pd# 获取模板文件def getMbData(path):doc = Document(path)all_paragraphs = doc.paragraphsall_tables = doc.tablesreturn all_paragraphs, all_tables, doc# 获取Excel数据(待填充的真实数据)def getRealData(path):dr = pd.read_excel(path)return dr# 获取Excel数据的列名def getColumns(dr: pd.DataFrame):columns = dr.columnsreturn columns#生成文档def generaterFile(path_mb,path_data):dr = pd.read_excel(path_data)columns = getColumns(dr)for i in range(len(dr)):all_paragraphs, all_tables, doc = getMbData(path_mb)for j in columns:for paragraph in all_paragraphs:for run in paragraph.runs:run.text = run.text.replace(j, str(dr.loc[i, j]))for tab in all_tables:for row in tab.rows:for cell in row.cells:cell.text = cell.text.replace(j, str(dr.loc[i, j]))doc.save(f’./datafile/generate/{dr.loc[i, ‘file_name’]}.docx’)if __name__==’__main__’:generaterFile(‘./datafile/mb.docx’,’./datafile/data.xlsx’)

三、代码分块解析

1.导入必要的库

from docx import Document

import pandas as pd

 python-docx:用于读写Word文档。Document对象代表一个Word文件。

pandas:用于读取Excel表格,我们主要用它的DataFrame结构。 

2.读取Word模板函数

def getMbData(path):

doc= Document(path)

all_paragraphs= doc.paragraphs# 所有段落

all_tables= doc.tables# 所有表格

return all_paragraphs, all_tables, doc

这个函数的作用是打开Word模板,把里面的所有段落和所有表格分别提取出来。

为什么要区分段落和表格?因为Word中的文字可能出现在普通段落里,也可能出现在表格的单元格中。我们后面需要遍历这两部分才能做到全文替换。

3.读取Excel数据函数

def getRealData(path):

dr= pd.read_excel(path)

return dr

直接用pd.read_excel将Excel文件读成DataFrame。假设Excel长这样:

file_name 姓名 部门 金额

张三_工资单 张三 销售部 5000

李四_工资单 李四 技术部 7000 

file_name列用于生成最终文档的文件名,其余列对应Word模板中的占位符。

4.获取列名函数

def getColumns(dr: pd.DataFrame):

columns= dr.columns

return columns 

简单返回DataFrame的所有列名。这些列名就是Word模板中需要被替换的“标签”。

5.核心生成函数

def generaterFile(path_mb, path_data):

dr= pd.read_excel(path_data)

columns= getColumns(dr) 

fori in range(len(dr)):

#每一轮都要重新加载模板(保证模板不被上一轮修改)

all_paragraphs,all_tables, doc = getMbData(path_mb)        

forj in columns:

#替换段落中的占位符

forparagraph in all_paragraphs:

forrun in paragraph.runs:

run.text= run.text.replace(j, str(dr.loc[i, j]))            

#替换表格中的占位符

fortab in all_tables:

forrow in tab.rows:

forcell in row.cells:

cell.text= cell.text.replace(j, str(dr.loc[i, j]))        

#保存生成的文件

doc.save(f’./datafile/generate/{dr.loc[i,“file_name”]}.docx’)

逐层拆解:

外层循环for i in range(len(dr)):遍历Excel的每一行,每一行生成一份文档。

重新加载模板:每次循环都重新读取mb.docx,避免上一轮的修改污染下一轮。

内层循环for j in columns:遍历当前行的每一个列名(也就是占位符,比如{姓名})。

替换段落:doc.paragraphs获取所有段落;每个段落又有多个runs(具有相同格式的连续文本块)。这里对每个run的文本执行replace,把占位符替换成当前行的实际值。

替换表格:同理,遍历所有表格的所有行所有单元格,执行替换。

保存文件:文件名从当前行的file_name列取值,保存到./datafile/generate/目录下。

注意:代码中str(dr.loc[i, j])将Excel单元格的值转为字符串,避免数字、日期等类型报错。

四、运行结果展示

word模板文件中包含内容: 

尊敬的{部门}{姓名}:您本月的工资为{金额}元 

Excel中的真实数据为:

file_name 姓名 部门 金额

张三_工资单 张三 销售部 5000

李四_工资单 李四 技术部 7000 

在generate文件夹下会生成文件:

张三_工资单.docx

李四_工资单.docx

打开文件内容显示:

尊敬的{销售部}{张三}:您本月的工资为{5000}元

五、常见问题与注意事项

1.占位符没有替换成功?

检查占位符是否完全一致:Excel的列名必须和Word中的占位符文本一模一样(包括大小写、空格)。

检查Word中的占位符是否跨Run:例如{姓名}可能被拆成{、姓名、}三个run,导致替换失败。解决方案:手动在Word中将占位符选中,设置成同一格式(或重新输入),确保它在同一个run中。

2.替换后格式丢失怎么办?

run.text替换会保留run的原有格式(字体、大小、颜色等)。但如果占位符跨run,替换逻辑可能无法覆盖全。保险做法:整个段落整体替换(但会丢失段落内不同格式),本例按run替换是较安全的方式。

3.Excel中的日期变成奇怪的数字?

Excel存储日期为数字序列(如44810代表2022-09-01)。替换前需要用pd.to_datetime格式化。可在循环内添加:

value = dr.loc[i, j]

if isinstance(value, pd.Timestamp):

value = value.strftime(‘%Y-%m-%d’)

4.路径和文件夹不存在?

保存文件前,请确保./datafile/generate/目录已经存在,否则会报FileNotFoundError。可以在代码开头添加: 

import os

os.makedirs(‘./datafile/generate/’, exist_ok=True) 

六 总结

本文我们用不到50行代码,实现了一个自动批量生成Word文档的工具。核心思想很简单:

1用pandas读取结构化数据(Excel);

2用python-docx解析Word模板;

3遍历数据每一行,将模板中的占位符替换成真实数据;

4另存为新文档。

这个模式可以灵活迁移到任何“模板+数据”的场景,比如批量生成HTML邮件、PDF报告(先做Word再转PDF)等。掌握了Pandas的数据处理能力和python-docx的文档操作,办公自动化的大门就向你敞开了。

动手试一试吧!找一份你手头的Word模板和Excel数据,改改路径运行一下——你会惊讶于Python带来的效率提升。如果遇到问题,欢迎在评论区留言交流