目录
一、环境安装
1、升级pip
2、python-docx
3、win32com
4、mailmerge
5、matplotlib
二、Python-docx 新建文档
三、Python-docx 编辑已存在文档
四、win32com 将 doc 转为 docx
五、win32com 操作 word
1、打开新的word文档并添加内容
2、打开已存在word文档并添加内容
3、转换word为pdf
六、Python-docx 操作 word
1、Python-docx官方例程
2、Python-docx官方例程解析
导入库操作
导入英寸单位操作
新建一个文档
加载旧文档
添加标题段落
添加段落操作
在指定段落上添加内容
添加标题操作
添加指定样式段落
添加无序列表操作
添加有序列表操作
添加图片操作
新建表格操作
填充标题行操作
为每组内容添加数据行并填充
设置标题样式操作
添加分页符操作
保存当前文档操作
Python-docx 表格样式设置
七、docx&matplotlib 自动生成数据分析报告
1、数据获取
2、柱状图生成
3、生成最终报告
八、Python-docx 修改旧 word 文档
1、读取word文档的内容
2、读取docx中表格内容
3、修改word中的内容
九、docx-mailmerge 自动生成万份劳动合同
1、创建合同模板
添加内容框架
创建一个域
设置域名
依次全部添加
2、生成1份证明
3、生成10000份证明
一、环境安装
使用Python操作word大部分情况都是写操作,也有少许情况会用到读操作,在本次教程中都会进行讲解,本次课程主要用到以下4个库,请大家提前安装。
1、升级pip
便于安装最新库
python-mpipinstall-Upipsetuptools
2、python-docx
我们大部分操作都是使用此库
安装方法:
pipinstallpython-docx
使用方法:
fromdocximportDocumentfromdocx.sharedimportInches
官方文档:
https://python-docx.readthedocs.io/en/latest/index.html
3、win32com
主要用作doc转docx格式转换用
安装方法:
pipinstallpypiwin32
使用方法:
importwin32comfromwin32com.clientimportDispatch,constants
官方文档:
https://docs.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word” />4、mailmerge
用作按照模板生成大量同类型文档
安装方法:
pipinstalldocx-mailmerge
使用方法:
frommailmergeimportMailMerge
官方文档:
https://pypi.org/project/docx-mailmerge/
5、matplotlib
Python 的绘图库,本期简单讲解,后期会有专门的课程
安装方法:
pipinstallmatplotlib
使用方法:
importmatplotlib.pyplotasplt
官方文档:
https://matplotlib.org/3.2.2/tutorials/introductory/sample_plots.html
二、Python-docx 新建文档
示例代码1:
fromdocximportDocumentdocument=Document()document.save('new.docx')
效果如下:
示例代码 0.1 Python-docx新建文档.py:
fromdocximportDocumentdefGenerateNewWord(filename):document=Document()document.save(filename)if__name__=="__main__":print("大家好!我们今天开始学习word文档自动化")print("我们先来直接生成一个名为‘new.docx’的文档")document=Document()document.save('new.docx')print("没错,里面什么都没有")#我是华丽的分隔符print("我们使用函数生成一个word文档试试")newname='使用函数生成的文档.docx'GenerateNewWord(newname)
效果如下:
三、Python-docx 编辑已存在文档
我们很多时候需要在已存在的word文档上添加自己的内容,那么我们赶紧看看应该怎样操作吧~
旧文档:
fromdocximportDocumentdocument=Document('exist.docx')document.save('new.docx')
也许你会说,没有没搞错,就这三句话?是的,就这三句,你就完成了旧文档的复制,如果你想修改,直接添加内容就行了呢!
效果如下:
四、win32com 将 doc 转为 docx
旧文档:
示例代码:
importosfromwin32comimportclientaswcdefTransDocToDocx(oldDocName,newDocxName):print("我是TransDocToDocx函数")#打开word应用程序word=wc.Dispatch('Word.Application')#打开旧word文件doc=word.Documents.Open(oldDocName)#保存为新word文件,其中参数12表示的是docx文件doc.SaveAs(newDocxName,12)#关闭word文档doc.Close()word.Quit()print("生成完毕!")if__name__=="__main__":#获取当前目录完整路径currentPath=os.getcwd()print("当前路径为:",currentPath)#获取旧doc格式word文件绝对路径名docName=os.path.join(currentPath,'旧doc格式文档.doc')print("docFilePath=",docName)#设置新docx格式文档文件名docxName=os.path.join(currentPath,'新生成docx格式文档.docx')TransDocToDocx(docName,docxName)
效果如下:
五、win32com 操作 word
1、打开新的word文档并添加内容
示例代码:
importwin32comfromwin32com.clientimportDispatch,constantsimportos#创建新的word文档deffunOpenNewFile():word=Dispatch('Word.Application')#或者使用下面的方法,使用启动独立的进程:#word=DispatchEx('Word.Application')#如果不声明以下属性,运行的时候会显示的打开wordword.Visible=1#0:后台运行1:前台运行(可见)word.DisplayAlerts=0#不显示,不警告#创建新的word文档doc=word.Documents.Add()#在文档开头添加内容myRange1=doc.Range(0,0)myRange1.InsertBefore('Helloword\n')#在文档末尾添加内容myRange2=doc.Range()myRange2.InsertAfter('Byeword\n')#在文档i指定位置添加内容i=0myRange3=doc.Range(0,i)myRange3.InsertAfter("what'sup,bro" />
效果如下:
2、打开已存在word文档并添加内容
前提条件:
示例代码:
importwin32comfromwin32com.clientimportDispatch,constantsimportos#打开已存在的word文件deffunOpenExistFile():word=Dispatch('Word.Application')#或者使用下面的方法,使用启动独立的进程:#word=DispatchEx('Word.Application')#如果不声明以下属性,运行的时候会显示的打开wordword.Visible=1#0:后台运行1:前台运行(可见)word.DisplayAlerts=0#不显示,不警告doc=word.Documents.Open(os.getcwd()+"\\3.1win32com测试.docx")#打开一个已有的word文档#在文档开头添加内容myRange1=doc.Range(0,0)myRange1.InsertBefore('Helloword\n')#在文档末尾添加内容myRange2=doc.Range()myRange2.InsertAfter('Byeword\n')#在文档i指定位置添加内容i=0myRange3=doc.Range(0,i)myRange3.InsertAfter("what'sup,bro" />
效果如下:
3、转换word为pdf
示例代码:
importwin32comfromwin32com.clientimportDispatch,constantsimportos#生成Pdf文件deffunGeneratePDF():word=Dispatch("Word.Application")word.Visible=0#后台运行,不显示word.DisplayAlerts=0#不警告doc=word.Documents.Open(os.getcwd()+"\\3.3win32com转换word为pdf等格式.docx")#打开一个已有的word文档doc.SaveAs(os.getcwd()+"\\3.3win32com转换word为pdf等格式.pdf",17)#txt=4,html=10,docx=16,pdf=17doc.Close()word.Quit()if__name__=='__main__':funGeneratePDF()
效果如下:
六、Python-docx 操作 word
官方文档:(最权威指南,没有之一)
https://python-docx.readthedocs.io/en/latest/
1、Python-docx官方例程
前提条件:
示例代码:
fromdocximportDocumentfromdocx.sharedimportInchesdocument=Document()document.add_heading('DocumentTitle',0)p=document.add_paragraph('Aplainparagraphhavingsome')p.add_run('bold').bold=Truep.add_run('andsome')p.add_run('italic.').italic=Truedocument.add_heading('Heading,level1',level=1)document.add_paragraph('Intensequote',style='IntenseQuote')document.add_paragraph('firstiteminunorderedlist',style='ListBullet')document.add_paragraph('firstiteminorderedlist',style='ListNumber')document.add_picture('countrygarden.png',width=Inches(1.25))records=((3,'101','Spam'),(7,'422','Eggs'),(4,'631','Spam,spam,eggs,andspam'))table=document.add_table(rows=1,cols=3)hdr_cells=table.rows[0].cellshdr_cells[0].text='Qty'hdr_cells[1].text='Id'hdr_cells[2].text='Desc'forqty,id,descinrecords:row_cells=table.add_row().cellsrow_cells[0].text=str(qty)row_cells[1].text=idrow_cells[2].text=descdocument.add_page_break()document.save('4.1Python-docx官方例程.docx')
最终效果:
2、Python-docx官方例程解析
导入库操作
fromdocximportDocument
导入英寸单位操作
可用于指定图片大小、表格宽高等
fromdocx.sharedimportInches
新建一个文档
document=Document()
加载旧文档
用于修改或添加内容
document=Document('exist.docx')
添加标题段落
document.add_heading('DocumentTitle',0)
添加段落操作
段落在 Word 中是基本内容。它们用于正文文本,也用于标题和项目列表(如项目符号)。
p=document.add_paragraph('Aplainparagraphhavingsome')
在指定段落上添加内容
p.add_run('bold').bold=True#添加粗体文字p.add_run('andsome')#添加默认格式文字p.add_run('italic.').italic=True#添加斜体文字
添加标题操作
等级1-9 也就是标题1-标题9,我们可以在旧文档中将标题格式设置好,使用Python-docx打开旧文档,再添加相应等级标题即可。
document.add_heading('Heading,level1',level=1)
添加指定样式段落
样式详情:
https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html#understanding-styles
document.add_paragraph('Intensequote',style='IntenseQuote')#以下两句的含义等同于上面一句p=document.add_paragraph('Intensequote')p.style='IntenseQuote'
添加无序列表操作
document.add_paragraph('firstiteminunorderedlist',style='ListBullet')
添加有序列表操作
document.add_paragraph('firstiteminorderedlist',style='ListNumber')
添加图片操作
第一个参数为图片路径,需要正确无误
第二个参数为图片大小,单位英寸
document.add_picture('countrygarden.png',width=Inches(1.25))
新建表格操作
table=document.add_table(rows=1,cols=3)
填充标题行操作
hdr_cells=table.rows[0].cellshdr_cells[0].text='Qty'hdr_cells[1].text='Id'hdr_cells[2].text='Desc'
为每组内容添加数据行并填充
forqty,id,descinrecords:row_cells=table.add_row().cellsrow_cells[0].text=str(qty)row_cells[1].text=idrow_cells[2].text=desc
设置标题样式操作
table.style='LightShading-Accent1'
添加分页符操作
document.add_page_break()
保存当前文档操作
document.save('4.1Python-docx官方例程.docx')
Python-docx 表格样式设置
表格样式设置代码:
fromdocximport*document=Document()table=document.add_table(3,3,style="MediumGrid1Accent1")heading_cells=table.rows[0].cellsheading_cells[0].text='第一列内容'heading_cells[1].text='第二列内容'heading_cells[2].text='第三列内容'document.save("demo.docx")
遍历所有样式:
fromdocx.enum.styleimportWD_STYLE_TYPEfromdocximportDocumentdocument=Document()styles=document.styles#生成所有表样式forsinstyles:ifs.type==WD_STYLE_TYPE.TABLE:document.add_paragraph("表格样式:"+s.name)table=document.add_table(3,3,style=s)heading_cells=table.rows[0].cellsheading_cells[0].text='第一列内容'heading_cells[1].text='第二列内容'heading_cells[2].text='第三列内容'document.add_paragraph("\n")document.save('4.3所有表格样式.docx')
效果如下(大家按照喜欢的样式添加即可):
七、docx&matplotlib 自动生成数据分析报告
最终效果
1、数据获取
我们这里使用xlrd作为数据获取所使用的库,简单回顾一下:
importxlrdxlsx=xlrd.open_workbook('./3_1xlrd读取操作练习.xlsx')#通过sheet名查找:xlsx.sheet_by_name("sheet1")#通过索引查找:xlsx.sheet_by_index(3)table=xlsx.sheet_by_index(0)#获取单个表格值(2,1)表示获取第3行第2列单元格的值value=table.cell_value(2,1)print("第3行2列值为",value)#获取表格行数nrows=table.nrowsprint("表格一共有",nrows,"行")#获取第4列所有值(列表生成式)name_list=[str(table.cell_value(i,3))foriinrange(1,nrows)]print("第4列所有的值:",name_list)
表格内容:
编写数据获取代码:
我们这里只获取用户姓名和,分数,并将它们保存到列表中,看代码。
#获取学习成绩信息defGetExcelInfo():print("开始获取表格内容信息")#打开指定文档xlsx=xlrd.open_workbook('学生成绩表格.xlsx')#获取sheetsheet=xlsx.sheet_by_index(0)#获取表格行数nrows=sheet.nrowsprint("一共",nrows,"行数据")#获取第2列,和第4列所有值(列表生成式),从第2行开始获取nameList=[str(sheet.cell_value(i,1))foriinrange(1,nrows)]scoreList=[int(sheet.cell_value(i,3))foriinrange(1,nrows)]#返回名字列表和分数列表returnnameList,scoreList
获取结果:
2、柱状图生成
我们先将获取的姓名和成绩使用 字典 数据结构关联起来,再对其排序:
#将名字和分数列表合并成字典(将学生姓名和分数关联起来)scoreDictionary=dict(zip(nameList,scoreList))print("dictionary:",scoreDictionary)#对字典进行值排序,高分在前,reverse=True代表降序排列scoreOrder=sorted(scoreDictionary.items(),key=lambdax:x[1],reverse=True)print("scoreOrder",scoreOrder)
效果如下:
#合成的字典dictionary:{'DillonMiller':41,'LauraRobinson':48,'GabrillaRogers':28,'CarlosChen':54,'LeonardHumphrey':44,'JohnHall':63,'MirandaNelson':74,'JessicaMorgan':34,'AprilLawrence':67,'CindyBrown':52,'CassandraFernan':29,'AprilCrawford':91,'JenniferArias':61,'PhilipWalsh':58,'ChristinaHillP':14,'JustinDunlap':56,'BrianLynch':84,'MichaelBrown':68}#排序后,再次转换成列表scoreOrder[('AprilCrawford',91),('BrianLynch',84),('MirandaNelson',74),('MichaelBrown',68),('AprilLawrence',67),('JohnHall',63),('JenniferArias',61),('PhilipWalsh',58),('JustinDunlap',56),('CarlosChen',54),('CindyBrown',52),('LauraRobinson',48),('LeonardHumphrey',44),('DillonMiller',41),('JessicaMorgan',34),('CassandraFernan',29),('GabrillaRogers',28),('ChristinaHillP',14)]
使用 matplotlib 生成柱状图:
#生成学生成绩柱状图(使用matplotlib)#会生成一张名为"studentScore.jpg"的图片defGenerateScorePic(scoreList):#解析成绩列表,生成横纵坐标列表xNameList=[str(studentInfo[0])forstudentInfoinscoreList]yScoreList=[int(studentInfo[1])forstudentInfoinscoreList]print("xNameList",xNameList)print("yScoreList",yScoreList)#设置字体格式matplotlib.rcParams['font.sans-serif']=['SimHei']#用黑体显示中文#设置绘图尺寸plt.figure(figsize=(10,5))#绘制图像plt.bar(x=xNameList,height=yScoreList,label='学生成绩',color='steelblue',alpha=0.8)#在柱状图上显示具体数值,ha参数控制水平对齐方式,va控制垂直对齐方式forx1,yyinscoreList:plt.text(x1,yy+1,str(yy),ha='center',va='bottom',fontsize=16,rotation=0)#设置标题plt.title("学生成绩柱状图")#为两条坐标轴设置名称plt.xlabel("学生姓名")plt.ylabel("学生成绩")#显示图例plt.legend()#坐标轴旋转plt.xticks(rotation=90)#设置底部比例,防止横坐标显示不全plt.gcf().subplots_adjust(bottom=0.25)#保存为图片plt.savefig("studentScore.jpg")#直接显示plt.show()
效果如下:
3、生成最终报告
代码如下:
#开始生成报告defGenerateScoreReport(scoreOrder,picPath):#新建一个文档document=Document()#设置标题document.add_heading('数据分析报告',0)#添加第一名的信息p1=document.add_paragraph("分数排在第一的学生姓名为:")p1.add_run(scoreOrder[0][0]).bold=Truep1.add_run("分数为:")p1.add_run(str(scoreOrder[0][1])).italic=True#添加总体情况信息p2=document.add_paragraph("共有:")p2.add_run(str(len(scoreOrder))).bold=Truep2.add_run("名学生参加了考试,学生考试的总体情况:")#添加考试情况表格table=document.add_table(rows=1,cols=2)table.style='MediumGrid1Accent1'hdr_cells=table.rows[0].cellshdr_cells[0].text='学生姓名'hdr_cells[1].text='学生分数'forstudentName,studentScoreinscoreOrder:row_cells=table.add_row().cellsrow_cells[0].text=studentNamerow_cells[1].text=str(studentScore)#添加学生成绩柱状图document.add_picture(picPath,width=Inches(6))document.save('学生成绩报告.docx')
完整代码
importxlrdimportmatplotlibimportmatplotlib.pyplotaspltfromdocximportDocumentfromdocx.sharedimportInches#获取学习成绩信息defGetExcelInfo():print("开始获取表格内容信息")#打开指定文档xlsx=xlrd.open_workbook('学生成绩表格.xlsx')#获取sheetsheet=xlsx.sheet_by_index(0)#获取表格行数nrows=sheet.nrowsprint("一共",nrows,"行数据")#获取第2列,和第4列所有值(列表生成式),从第2行开始获取nameList=[str(sheet.cell_value(i,1))foriinrange(1,nrows)]scoreList=[int(sheet.cell_value(i,3))foriinrange(1,nrows)]#返回名字列表和分数列表returnnameList,scoreList#生成学生成绩柱状图(使用matplotlib)#会生成一张名为"studentScore.jpg"的图片defGenerateScorePic(scoreList):#解析成绩列表,生成横纵坐标列表xNameList=[str(studentInfo[0])forstudentInfoinscoreList]yScoreList=[int(studentInfo[1])forstudentInfoinscoreList]print("xNameList",xNameList)print("yScoreList",yScoreList)#设置字体格式matplotlib.rcParams['font.sans-serif']=['SimHei']#用黑体显示中文#设置绘图尺寸plt.figure(figsize=(10,5))#绘制图像plt.bar(x=xNameList,height=yScoreList,label='学生成绩',color='steelblue',alpha=0.8)#在柱状图上显示具体数值,ha参数控制水平对齐方式,va控制垂直对齐方式forx1,yyinscoreList:plt.text(x1,yy+1,str(yy),ha='center',va='bottom',fontsize=16,rotation=0)#设置标题plt.title("学生成绩柱状图")#为两条坐标轴设置名称plt.xlabel("学生姓名")plt.ylabel("学生成绩")#显示图例plt.legend()#坐标轴旋转plt.xticks(rotation=90)#设置底部比例,防止横坐标显示不全plt.gcf().subplots_adjust(bottom=0.25)#保存为图片plt.savefig("studentScore.jpg")#直接显示plt.show()#开始生成报告defGenerateScoreReport(scoreOrder,picPath):#新建一个文档document=Document()#设置标题document.add_heading('数据分析报告',0)#添加第一名的信息p1=document.add_paragraph("分数排在第一的学生姓名为:")p1.add_run(scoreOrder[0][0]).bold=Truep1.add_run("分数为:")p1.add_run(str(scoreOrder[0][1])).italic=True#添加总体情况信息p2=document.add_paragraph("共有:")p2.add_run(str(len(scoreOrder))).bold=Truep2.add_run("名学生参加了考试,学生考试的总体情况:")#添加考试情况表格table=document.add_table(rows=1,cols=2)table.style='MediumGrid1Accent1'hdr_cells=table.rows[0].cellshdr_cells[0].text='学生姓名'hdr_cells[1].text='学生分数'forstudentName,studentScoreinscoreOrder:row_cells=table.add_row().cellsrow_cells[0].text=studentNamerow_cells[1].text=str(studentScore)#添加学生成绩柱状图document.add_picture(picPath,width=Inches(6))document.save('学生成绩报告.docx')if__name__=="__main__":#调用信息获取方法,获取用户信息nameList,scoreList=GetExcelInfo()#print("nameList:",nameList)#print("ScoreList:",scoreList)#将名字和分数列表合并成字典(将学生姓名和分数关联起来)scoreDictionary=dict(zip(nameList,scoreList))#print("dictionary:",scoreDictionary)#对字典进行值排序,高分在前,reverse=True代表降序排列scoreOrder=sorted(scoreDictionary.items(),key=lambdax:x[1],reverse=True)#print("scoreOrder",scoreOrder)#将进行排序后的学生成绩列表生成柱状图GenerateScorePic(scoreOrder)#开始生成报告picPath="studentScore.jpg"GenerateScoreReport(scoreOrder,picPath)print("任务完成,报表生成完毕!")
八、Python-docx 修改旧 word 文档
回顾:打开旧文档,并另存为新文档
我们这里就拿上一节生成的学生成绩报告作为示例:
fromdocximportDocumentif__name__=="__main__":document=Document('6学生成绩报告.docx')#在这里进行操作,此处忽略document.save('修改后的报告.docx')
1、读取word文档的内容
示例代码:
fromdocximportDocumentif__name__=="__main__":document=Document('6学生成绩报告.docx')#读取word中所有内容forpindocument.paragraphs:print("paragraphs:",p.text)#读取word中所有一级标题forpindocument.paragraphs:ifp.style.name=='Heading1':print("Heading 1:",p.text)#读取word中所有二级标题forpindocument.paragraphs:ifp.style.name=='Heading2':print("Heading 2:",p.text)#读取word中所有正文forpindocument.paragraphs:ifp.style.name=='Normal':print("Normal:",p.text)document.save('修改后的报告.docx')
效果如下:
2、读取docx中表格内容
示例代码:
fromdocximportDocumentif__name__=="__main__":document=Document('6学生成绩报告.docx')#读取表格内容fortbindocument.tables:fori,rowinenumerate(tb.rows):forj,cellinenumerate(row.cells):text=''forpincell.paragraphs:text+=p.textprint(f'第{i}行,第{j}列的内容{text}')document.save('修改后的报告.docx')
效果如下:
3、修改word中的内容
示例代码:
fromdocximportDocumentif__name__=="__main__":document=Document('6学生成绩报告.docx')#修改word中所有内容forpindocument.paragraphs:p.text="修改后的段落内容"#修改表格内容fortbindocument.tables:fori,rowinenumerate(tb.rows):forj,cellinenumerate(row.cells):text=''forpincell.paragraphs:p.text=("第",str(i),"行",str(j),"列")print(f'第{i}行,第{j}列的内容{text}')document.save('6.4修改后的报告.docx')
效果如下:
九、docx-mailmerge 自动生成万份劳动合同
1、创建合同模板
添加内容框架
创建一个域
设置域名
依次全部添加
2、生成1份证明
示例代码:
frommailmergeimportMailMergetemplate='薪资证明模板.docx'document=MailMerge(template)document.merge(name='唐星',id='1010101010',year='2020',salary='99999',job='嵌入式软件开发工程师')document.write('生成的1份证明.docx')
效果如下:
哈哈哈哈!!月入10万,走向人生巅峰~
3、生成10000份证明
示例代码:
frommailmergeimportMailMergefromdatetimeimportdatetime#生成单份合同defGenerateCertify(templateName,newName):#打开模板document=MailMerge(templateName)#替换内容document.merge(name='唐星',id='1010101010',year='2020',salary='99999',job='嵌入式软件开发工程师')#保存文件document.write(newName)if__name__=="__main__":templateName='薪资证明模板.docx'#获得开始时间startTime=datetime.now()#开始生成foriinrange(10000):newName=f'./10000份证明/薪资证明{i}.docx'GenerateCertify(templateName,newName)#获取结束时间endTime=datetime.now()#计算时间差allSeconds=(endTime-startTime).secondsprint("生成10000份合同一共用时:",str(allSeconds),"秒")print("程序结束!")
效果如下:
只花了89秒,平均不到 0.01 就能生成一个!!快
万水千山总是情,点个行不行。