目录

一、结构

二、常用的API介绍

三、实例展示

展示一

展示二


        最近接到一个需求——把数据库里的数据做成表格,然后形成一本书,打印出来送给客户。由于系统目前没有自动导出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

他们直接的一些相互关系,可以用一张结构图来表示:

python自动生成word报告 python 生成word_数据

run对象是Python-docx的最基本的单位,例如每一个段落有一个run对象,每一行有一个run对象;每一个表格对象有一个run对象,每一个单元格有一个run对象。通过这个run对象我们就可以精准的控制文档中不同内容、不同粒度的样式,包括字体大小和颜色等。

基本word生成步骤:

1、document = Document() 
2、document.add_*....
3、document.save(path)

二、常用的API介绍

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')

文档效果:

python自动生成word报告 python 生成word_数据_02

 

展示二

如下图,要从数据库中查询数据并且做成如下排版的格式,每个页面2个表格,同时还要把数据进行分类,添加2级标题。

python自动生成word报告 python 生成word_分页_03

实现其实很简单,遍历的生成表格,在每一类数据之前添加标题,每生成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和其他的一些注意的点,