环境安装 使用Python操作word大部分情况都是写操作,也有少许情况会用到读操作,在本次教程中都会进行讲解,本次课程主要用到以下4个库,请大家提前安装。 
升级pip(便于安装最新库) python -m pip install -U pip setuptoolspython-docx(我们大部分操作都是使用此库) 安装方法:
pip install python-docx使用方法:
from  docx import  Documentfrom  docx.shared import  Inches官方文档:
https://python-docx.readthedocs.io/en/latest/index.html
win32com(主要用作doc转docx格式转换用) 安装方法:
pip install pypiwin32使用方法:
import  win32comfrom  win32com.client import  Dispatch, constants官方文档:
https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word?view=word-pia
mailmerge(用作按照模板生成大量同类型文档) 安装方法:
pip install docx-mailmerge使用方法:
from  mailmerge import  MailMerge官方文档:
https://pypi.org/project/docx-mailmerge/
matplotlib(Python 的绘图库,本期简单讲解,后期会有专门的课程) 安装方法:
pip install matplotlib使用方法:
import  matplotlib.pyplot as  plt官方文档:
https://matplotlib.org/3.2.2/tutorials/introductory/sample_plots.html
Python-docx 新建文档 示例代码1:
from  docx import  Document'new.docx' )效果如下:
示例代码 0.1 Python-docx新建文档.py:
from  docx import  Documentdef  GenerateNewWord (filename) :if  __name__ == "__main__" :"大家好!我们今天开始学习word文档自动化" )"我们先来直接生成一个名为‘new.docx’的文档" )'new.docx' )"没错,里面什么都没有" )# 我是华丽的分隔符 "我们使用函数生成一个word文档试试" )'使用函数生成的文档.docx' 效果如下:
Python-docx 编辑已存在文档 我们很多时候需要在已存在的word文档上添加自己的内容,那么我们赶紧看看应该怎样操作吧~
旧文档:
示例代码:
from  docx import  Document'exist.docx' )'new.docx' )也许你会说,没有没搞错,就这三句话?是的,就这三句,你就完成了旧文档的复制,如果你想修改,直接添加内容就行了呢!
效果如下:
win32com 将 doc 转为 docx 旧文档:
示例代码:
import  osfrom  win32com import  client as  wcdef  TransDocToDocx (oldDocName,newDocxName) :"我是 TransDocToDocx 函数" )# 打开word应用程序 'Word.Application' )# 打开 旧word 文件 # 保存为 新word 文件,其中参数 12 表示的是docx文件 12 )# 关闭word文档 "生成完毕!" )if  __name__ == "__main__" :# 获取当前目录完整路径 "当前路径为:" ,currentPath)# 获取 旧doc格式word文件绝对路径名 '旧doc格式文档.doc' )"docFilePath = " , docName)# 设置新docx格式文档文件名 '新生成docx格式文档.docx' )效果如下:
win32com 操作 word 打开新的word文档并添加内容 示例代码:
import  win32comfrom  win32com.client import  Dispatch, constantsimport  os# 创建新的word文档 def  funOpenNewFile () :'Word.Application' )# 或者使用下面的方法,使用启动独立的进程: # word = DispatchEx('Word.Application') # 如果不声明以下属性,运行的时候会显示的打开word 1   # 0:后台运行 1:前台运行(可见) 0   # 不显示,不警告 # 创建新的word文档 # 在文档开头添加内容 0 , 0 )'Hello word\n' )# 在文档末尾添加内容 'Bye word\n' )# 在文档i指定位置添加内容 0 0 , i)"what's up, bro?\n" )# doc.Save()  # 保存 "\\funOpenNewFile.docx" )  # 另存为 # 关闭 word 文档 # 关闭 office if  __name__ == '__main__' :"当前文件路径名:" ,os.getcwd())"调用funOpenNewFile()" )效果如下:
打开已存在word文档并添加内容 前提条件:
示例代码:
import  win32comfrom  win32com.client import  Dispatch, constantsimport  os# 打开已存在的word文件 def  funOpenExistFile () :'Word.Application' )# 或者使用下面的方法,使用启动独立的进程: # word = DispatchEx('Word.Application') # 如果不声明以下属性,运行的时候会显示的打开word 1   # 0:后台运行 1:前台运行(可见) 0   # 不显示,不警告 "\\3.1 win32com测试.docx" ) # 打开一个已有的word文档 # 在文档开头添加内容 0 , 0 )'Hello word\n' )# 在文档末尾添加内容 'Bye word\n' )# 在文档i指定位置添加内容 0 0 , i)"what's up, bro?\n" )# doc.Save()  # 保存 "\\funOpenExistFile.docx" )  # 另存为 # 关闭 word 文档 # 关闭 office if  __name__ == '__main__' :"当前文件路径名:" ,os.getcwd())"调用funOpenExistFile()" )效果如下:
转换word为pdf 示例代码:
import  win32comfrom  win32com.client import  Dispatch, constantsimport  os# 生成Pdf文件 def  funGeneratePDF () :"Word.Application" )0   # 后台运行,不显示 0   # 不警告 "\\3.3 win32com转换word为pdf等格式.docx" ) # 打开一个已有的word文档 "\\3.3 win32com转换word为pdf等格式.pdf" , 17 
# txt=4, html=10, docx=16, pdf=17 if  __name__ == '__main__' :效果如下:
Python-docx 操作 word 官方文档:(最权威指南,没有之一)
https://python-docx.readthedocs.io/en/latest/
Python-docx官方例程 前提条件:
示例代码:
from  docx import  Documentfrom  docx.shared import  Inches'Document Title' , 0 )'A plain paragraph having some ' )'bold' ).bold = True ' and some ' )'italic.' ).italic = True 'Heading, level 1' , level=1 )'Intense quote' , style='Intense Quote' )'first item in unordered list' , style='List Bullet' 'first item in ordered list' , style='List Number' 'countrygarden.png' , width=Inches(1.25 ))3 , '101' , 'Spam' ),7 , '422' , 'Eggs' ),4 , '631' , 'Spam, spam, eggs, and spam' )1 , cols=3 )0 ].cells0 ].text = 'Qty' 1 ].text = 'Id' 2 ].text = 'Desc' for  qty, id, desc in  records:0 ].text = str(qty)1 ].text = id2 ].text = desc'4.1 Python-docx官方例程.docx' )最终效果:
Python-docx官方例程解析 from  docx import  Document导入英寸单位操作(可用于指定图片大小、表格宽高等) from  docx.shared import  Inchesdocument = Document()document = Document('exist.docx' )document.add_heading('Document Title' , 0 )段落在 Word 中是基本内容。它们用于正文文本,也用于标题和项目列表(如项目符号)。
p = document.add_paragraph('A plain paragraph having some ' )p.add_run('bold' ).bold = True    # 添加粗体文字 ' and some ' )     # 添加默认格式文字 'italic.' ).italic = True   # 添加斜体文字 等级1-9 也就是标题1-标题9,我们可以在旧文档中将标题格式设置好,使用Python-docx打开旧文档,再添加相应等级标题即可。
document.add_heading('Heading, level 1' , level=1 )样式详情:
https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html#understanding-styles
document.add_paragraph('Intense quote' , style='Intense Quote' )# 以下两句的含义等同于上面一句 'Intense quote' )'Intense Quote' document.add_paragraph( 'first item in unordered list' , style='List Bullet' )document.add_paragraph( 'first item in ordered list' , style='List Number' )第一个参数为图片路径,需要正确无误
第二个参数为图片大小,单位英寸
document.add_picture('countrygarden.png' , width=Inches(1.25 ))table = document.add_table(rows=1 , cols=3 )hdr_cells = table.rows[0 ].cells0 ].text = 'Qty' 1 ].text = 'Id' 2 ].text = 'Desc' for  qty, id, desc in  records:0 ].text = str(qty)1 ].text = id2 ].text = desctable.style = 'LightShading-Accent1' document.add_page_break()document.save('4.1 Python-docx官方例程.docx' )Python-docx 表格样式设置 表格样式设置代码:
from  docx import  *3 , 3 , style="Medium Grid 1 Accent 1" )0 ].cells0 ].text = '第一列内容' 1 ].text = '第二列内容' 2 ].text = '第三列内容' "demo.docx" )遍历所有样式: 
from  docx.enum.style import  WD_STYLE_TYPEfrom  docx import  Document# 生成所有表样式 for  s in  styles:if  s.type == WD_STYLE_TYPE.TABLE:"表格样式 :  "  + s.name)3 , 3 , style=s)0 ].cells0 ].text = '第一列内容' 1 ].text = '第二列内容' 2 ].text = '第三列内容' "\n" )'4.3 所有表格样式.docx' )效果如下(大家按照喜欢的样式添加即可):
docx&matplotlib 自动生成数据分析报告 最终效果 数据获取 我们这里使用xlrd作为数据获取所使用的库,简单回顾一下:
import  xlrd'./3_1 xlrd 读取 操作练习.xlsx' )# 通过sheet名查找:xlsx.sheet_by_name("sheet1") # 通过索引查找:xlsx.sheet_by_index(3) 0 )# 获取单个表格值 (2,1)表示获取第3行第2列单元格的值 2 , 1 )"第3行2列值为" ,value)# 获取表格行数 "表格一共有" ,nrows,"行" )# 获取第4列所有值(列表生成式) 3 )) for  i in  range(1 , nrows)]"第4列所有的值:" ,name_list)表格内容:
编写数据获取代码:
我们这里只获取用户姓名和,分数,并将它们保存到列表中,看代码。
 def  GetExcelInfo () :"开始获取表格内容信息" )# 打开指定文档 '学生成绩表格.xlsx' )# 获取sheet 0 )# 获取表格行数 "一共 " ,nrows," 行数据" )# 获取第2列,和第4列 所有值(列表生成式),从第2行开始获取 1 )) for  i in  range(1 , nrows)]3 )) for  i in  range(1 , nrows)]# 返回名字列表和分数列表 return  nameList,scoreList获取结果:
柱状图生成 我们先将获取的姓名和成绩使用 字典 数据结构关联起来,再对其排序:
# 将名字和分数列表合并成字典(将学生姓名和分数关联起来) "dictionary:" ,scoreDictionary)# 对字典进行值排序,高分在前,reverse=True 代表降序排列 lambda  x: x[1 ], reverse=True )"scoreOrder" ,scoreOrder)效果如下:
# 合成的字典使用 matplotlib 生成柱状图:
# 生成学生成绩柱状图(使用matplotlib) # 会生成一张名为"studentScore.jpg"的图片 def  GenerateScorePic (scoreList) :# 解析成绩列表,生成横纵坐标列表 0 ]) for  studentInfo in  scoreList]1 ]) for  studentInfo in  scoreList]"xNameList" ,xNameList)"yScoreList" ,yScoreList)# 设置字体格式 'font.sans-serif' ] = ['SimHei' ]  # 用黑体显示中文 # 设置绘图尺寸 10 ,5 ))# 绘制图像 '学生成绩' , color='steelblue' , alpha=0.8 )# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式 for  x1, yy in  scoreList:1 , str(yy), ha='center' , va='bottom' , fontsize=16 , rotation=0 )# 设置标题 "学生成绩柱状图" )# 为两条坐标轴设置名称 "学生姓名" )"学生成绩" )# 显示图例 # 坐标轴旋转 90 )# 设置底部比例,防止横坐标显示不全 0.25 )# 保存为图片 "studentScore.jpg" )# 直接显示 效果如下:
生成最终报告 代码如下:
# 开始生成报告 def  GenerateScoreReport (scoreOrder,picPath) :# 新建一个文档 # 设置标题 '数据分析报告' , 0 )# 添加第一名的信息 "分数排在第一的学生姓名为: " )0 ][0 ]).bold = True " 分数为: " )0 ][1 ])).italic = True # 添加总体情况信息 "共有: " )True " 名学生参加了考试,学生考试的总体情况: " )# 添加考试情况表格 1 , cols=2 )'Medium Grid 1 Accent 1' 0 ].cells0 ].text = '学生姓名' 1 ].text = '学生分数' for  studentName,studentScore in  scoreOrder:0 ].text = studentName1 ].text = str(studentScore)# 添加学生成绩柱状图 6 ))'学生成绩报告.docx' )完整代码 import  xlrdimport  matplotlibimport  matplotlib.pyplot as  pltfrom  docx import  Documentfrom  docx.shared import  Inches# 获取学习成绩信息 def  GetExcelInfo () :"开始获取表格内容信息" )# 打开指定文档 '学生成绩表格.xlsx' )# 获取sheet 0 )# 获取表格行数 "一共 " ,nrows," 行数据" )# 获取第2列,和第4列 所有值(列表生成式),从第2行开始获取 1 )) for  i in  range(1 , nrows)]3 )) for  i in  range(1 , nrows)]# 返回名字列表和分数列表 return  nameList,scoreList# 生成学生成绩柱状图(使用matplotlib) # 会生成一张名为"studentScore.jpg"的图片 def  GenerateScorePic (scoreList) :# 解析成绩列表,生成横纵坐标列表 0 ]) for  studentInfo in  scoreList]1 ]) for  studentInfo in  scoreList]"xNameList" ,xNameList)"yScoreList" ,yScoreList)
 'font.sans-serif' ] = ['SimHei' ]  # 用黑体显示中文 # 设置绘图尺寸 10 ,5 ))# 绘制图像 '学生成绩' , color='steelblue' , alpha=0.8 )# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式 for  x1, yy in  scoreList:1 , str(yy), ha='center' , va='bottom' , fontsize=16 , rotation=0 )# 设置标题 "学生成绩柱状图" )# 为两条坐标轴设置名称 "学生姓名" )"学生成绩" )# 显示图例 # 坐标轴旋转 90 )# 设置底部比例,防止横坐标显示不全 0.25 )# 保存为图片 "studentScore.jpg" )# 直接显示 # 开始生成报告 def  GenerateScoreReport (scoreOrder,picPath) :# 新建一个文档 # 设置标题 '数据分析报告' , 0 )# 添加第一名的信息 "分数排在第一的学生姓名为: " )0 ][0 ]).bold = True " 分数为: " )0 ][1 ])).italic = True # 添加总体情况信息 "共有: " )True " 名学生参加了考试,学生考试的总体情况: " )# 添加考试情况表格 1 , cols=2 )'Medium Grid 1 Accent 1' 0 ].cells0 ].text = '学生姓名' 1 ].text = '学生分数' for  studentName,studentScore in  scoreOrder:0 ].text = studentName1 ].text = str(studentScore)# 添加学生成绩柱状图 6 ))'学生成绩报告.docx' )if  __name__ == "__main__" :# 调用信息获取方法,获取用户信息 # print("nameList:",nameList) # print("ScoreList:",scoreList) # 将名字和分数列表合并成字典(将学生姓名和分数关联起来) # print("dictionary:",scoreDictionary) # 对字典进行值排序,高分在前,reverse=True 代表降序排列 lambda  x: x[1 ], reverse=True )# print("scoreOrder",scoreOrder) # 将进行排序后的学生成绩列表生成柱状图 # 开始生成报告 "studentScore.jpg" "任务完成,报表生成完毕!" )Python-docx 修改旧 word 文档 回顾:打开旧文档,并另存为新文档 我们这里就拿上一节生成的学生成绩报告作为示例:
from  docx import  Documentif  __name__ == "__main__" :'6 学生成绩报告.docx' )# 在这里进行操作,此处忽略 '修改后的报告.docx' )读取word文档的内容 示例代码:
from  docx import  Documentif  __name__ == "__main__" :'6 学生成绩报告.docx' )# 读取 word 中所有内容 for  p in  document.paragraphs:"paragraphs:" ,p.text)# 读取 word 中所有一级标题 for  p in  document.paragraphs:if  p.style.name == 'Heading 1' :"Heading 1:" ,p.text)# 读取 word 中所有二级标题 for  p in  document.paragraphs:if  p.style.name == 'Heading 2' :"Heading 2:" , p.text)# 读取 word 中所有正文 for  p in  document.paragraphs:if  p.style.name == 'Normal' :"Normal:" , p.text)'修改后的报告.docx' ) 效果如下:
读取docx中表格内容 示例代码:
from  docx import  Documentif  __name__ == "__main__" :'6 学生成绩报告.docx' )# 读取表格内容 for  tb in  document.tables:for  i,row in  enumerate(tb.rows):for  j,cell in  enumerate(row.cells):'' for  p in  cell.paragraphs:f'第{i} 行,第{j} 列的内容{text} ' )'修改后的报告.docx' )效果如下:
修改word中的内容 示例代码:
from  docx import  Documentif  __name__ == "__main__" :'6 学生成绩报告.docx' )# 修改 word 中所有内容 for  p in  document.paragraphs:"修改后的段落内容" # 修改表格内容 for  tb in  document.tables:for  i,row in  enumerate(tb.rows):for  j,cell in  enumerate(row.cells):'' for  p in  cell.paragraphs:"第" ,str(i),"行" ,str(j),"列" )f'第{i} 行,第{j} 列的内容{text} ' )'6.4 修改后的报告.docx' )效果如下:
 docx-mailmerge 自动生成万份劳动合同 创建合同模板 生成1份证明 示例代码:
from  mailmerge import  MailMerge'薪资证明模板.docx' '唐星' ,'1010101010' ,'2020' ,'99999' ,'嵌入式软件开发工程师' )'生成的1份证明.docx' )效果如下:
哈哈哈哈!!月入10万,走向人生巅峰~
生成10000份证明 示例代码:
from  mailmerge import  MailMergefrom  datetime import  datetime# 生成单份合同 def  GenerateCertify (templateName,newName) :# 打开模板 # 替换内容 '唐星' ,'1010101010' ,'2020' ,'99999' ,'嵌入式软件开发工程师' )# 保存文件 if  __name__ == "__main__" :'薪资证明模板.docx' # 获得开始时间 # 开始生成 for  i in  range(10000 ):f'./10000份证明/薪资证明{i} .docx' # 获取结束时间 # 计算时间差 "生成10000份合同一共用时: " ,str(allSeconds)," 秒" )"程序结束!" )效果如下:
只花了89秒,平均不到 0.01 就能生成一个!!快