目录

一、环境安装

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 就能生成一个!!快

万水千山总是情,点个行不行