赞
踩
目录
最近接到一个需求——把数据库里的数据做成表格,然后形成一本书,打印出来送给客户。由于系统目前没有自动导出word或者excel类似的功能,只能自己去实现。这个任务的要点在于,表格的形成,然后是多个表格排版在一起。在没有接触过怎么用python自动生成word和PDF文件,这个完全就不知道工作量。后面在网上找资料,发现用python-docx就能实现这个功能,而且代码量很少。当然例如pydf2和Reportlab也能实现PDF,画图也有专门的库pyecharts等。这里主要就是简单总结一下python-docx自动生成word文档相关的内的内容,算作入门,用以复习使用。
python-docx把一个word文档视为一个Document()对象,然后根据内容的形式分为一些子类。
标题:add_heading,分为一二三四级等标题;
段落:paragraph,add_paragraph;
表格:table,add_table;
图片:picture,add_picture
他们直接的一些相互关系,可以用一张结构图来表示:
run对象是Python-docx的最基本的单位,例如每一个段落有一个run对象,每一行有一个run对象;每一个表格对象有一个run对象,每一个单元格有一个run对象。通过这个run对象我们就可以精准的控制文档中不同内容、不同粒度的样式,包括字体大小和颜色等。
基本word生成步骤:
1、document = Document()
2、document.add_*....
3、document.save(path)
1、创建、打开一个文档对象
- document = Document()#创建一个文档
- document = Document(path)#从path路径打开一个已存在的文档
2、设置标题
注意level参数,控制标题的级别
document.add_heading(text=u'关于python-docx的使用说明',level=1)
3、添加段落文本
这里的style参数用来控制文本的风格格式等,类似前段css样式。当然也可以通过run、add_run()的方式来实现。
- document.add_paragraph(text='首先..........其次。。。。。。。。再次。。。。。。。。。', style=None)
-
- document.add_paragraph(text='首先..........其次。。。。。。。。再次。。。。。。。。。', style=None)
- run1 = document.add_paragraph( style=None).add_run(text='首先..........其次。。。。。。。。再次。。。。。。。。。')
- run1.font.size = Pt(16) # 设置大小为16磅
- run1.font.color.rgb = RGBColor(0, 255, 0) # 设置为蓝色 这个可以查找RGB颜色对照表
4、添加表格
这里涉及到表格的行列坐标,以及合并。合并的时候是采用行列坐标来确定单元格的位置,merge函数来实现。单元格:table.cell(row,column)。
- table = document.add_table(rows=5, cols=5, style='Table Grid')
- # 单元格合并
- table.cell(0, 0).merge(table.cell(0, 4)) #第一行合并
- table.cell(1, 0).merge(table.cell(2, 2)) #第二行的123列和第3行的123列合并
5、添加图片
add_picture(image_path_or_stream, width=None, height=None),参数分别是图片路径,宽度和高度等。如下,一个函数搞定。
document.add_picture('qianyixue.jpeg')
但是要排版居中的话就有点麻烦,这里需要先引用一个paragraph,然后用它的居中属性来控制:
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
- # 添加图片并且居中
- paragraph = document.add_paragraph()
- # 图片居中设置
- paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
- run = paragraph.add_run("")
- run.add_picture('qianyixue.jpeg')
6、分页符
add_page_break() #增加分页符
这里有的时候排版需要这个分页符的功能
下面看一效果,随便添加的几个文档要素。代码入下:
- from docx import Document
- from docx.shared import Pt,Inches
- from docx.shared import RGBColor
- from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
-
- if __name__ == '__main__':
- document = Document()
- title = document.add_heading(text=u'关于python-docx的使用说明',level=1)
- #标题居中
- title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
- document.add_paragraph(text='首先..........其次。。。。。。。。再次。。。。。。。。。', style=None)
- run1 = document.add_paragraph( style=None).add_run(text='首先..........其次。。。。。。。。再次。。。。。。。。。')
- run1.font.size = Pt(16) # 设置大小为11磅
- run1.font.color.rgb = RGBColor(0, 255, 0) # 设置为蓝色 这个可以查找RGB颜色对照表
- #添加表格
- table = document.add_table(rows=5, cols=5, style='Table Grid')
- # 单元格合并
- table.cell(0, 0).merge(table.cell(0, 4)) #第一行合并
- table.cell(1, 0).merge(table.cell(2, 2)) #第二行的123列和第3行的123列合并
- table.cell(0, 0).add_paragraph('这是第一行')
- table.cell(1, 0).add_paragraph('第二行和第3行合并')
- #换行
- document.add_paragraph('\n')
- #添加图片
- document.add_picture('qianyixue.jpeg', width=Inches(4))
-
- # 添加图片并且居中
- paragraph = document.add_paragraph()
- # 图片居中设置
- paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
- run = paragraph.add_run("")
- run.add_picture('qianyixue.jpeg',width=Inches(4))
- #保存word文档
- document.save('test.docx')

文档效果:
如下图,要从数据库中查询数据并且做成如下排版的格式,每个页面2个表格,同时还要把数据进行分类,添加2级标题。
实现其实很简单,遍历的生成表格,在每一类数据之前添加标题,每生成2个table就换页;每一类数据完成了也换页。
关键代码如下:
- document = Document()
- fill_save_table(document, patent_data_list, secondary_headlines, new_IpcNums, save_file_docx)
- print('生成word文档完成!')
-
-
-
- def fill_save_table(document,patent_data_list,secondary_headlines, new_IpcNums,path):
-
-
- for secondary_headline,new_IpcNum in tqdm(list(zip(secondary_headlines, new_IpcNums)),desc='生成word表格'):
- run = document.add_heading('',level=2).add_run(secondary_headline)
- run.font.size = Pt(16) # 设置大小为11磅
- run.font.color.rgb = RGBColor(0,0,0) #设置为黑色
- for i in range(new_IpcNum):
- produce_table(document)
- document.add_paragraph('')
- if (i + 1) % 2 == 0 and (i + 1) != new_IpcNum:
- document.add_page_break()
- document.add_page_break()
-
- #保存document文档
- document.save(path)
-
-
- #打开document文档
- document = Document(path)
-
- tables = document.tables
- for table,ele in tqdm(list(zip(tables,patent_data_list)),desc='把数据填充到表格中:'):
- #填充数据
- table.cell(0,0).add_paragraph(ele[0])
- table.cell(0, 1).add_paragraph(ele[1])
- table.cell(0, 4).add_paragraph(ele[2])
- table.cell(0, 6).add_paragraph(ele[3])
- table.cell(0, 7).add_paragraph(ele[4])
-
- table.cell(1, 0).add_paragraph(ele[5])
- table.cell(1, 1).add_paragraph(ele[6])
- table.cell(1, 3).add_paragraph(ele[7])
- table.cell(1, 4).add_paragraph(ele[8])
- table.cell(1, 6).add_paragraph(ele[9])
- table.cell(1, 7).add_paragraph(ele[10])
-
- table.cell(2, 0).add_paragraph(ele[11])
- table.cell(2, 1).add_paragraph(ele[12])
-
- document.save(path)
-
-
-
-
- def produce_table(document):
- table = document.add_table(rows=3,cols=10,style='Table Grid')
- #单元格合并
- table.cell(0, 1).merge(table.cell(0, 3))
- table.cell(0,4).merge(table.cell(0, 5))
- table.cell(0, 7).merge(table.cell(0, 9))
-
- table.cell(1, 1).merge(table.cell(1, 2))
- table.cell(1, 4).merge(table.cell(1, 5))
- table.cell(1, 7).merge(table.cell(1, 9))
-
- table.cell(2, 1).merge(table.cell(2, 9))

写在最后,以上内容其实很简单,当然写的也很粗糙,关于API和其他的一些注意的点,可以参考这一篇博客:python-docx中文文档使用小结
参考文章:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。