我心中的王者:Python-第17章 使用Python处理Word文件

我心中的王者:Python-第17章 使用Python处理Word文件

Word是二进制(binary)文件,同时Word还有字体格式、色彩与版面配置等,所以它的处理方式比起文本文件(txt)要复杂。不过,读者不用担心,笔者将以实例一步一步讲解,相信读完本章读者也可以很轻松学会使用Python处理Word文件。

本章内容需要使用外部模块python-docx,读者可参考附录B下载此模块,尽管模块名称是python-docx,下载时指令是:

 pip install python-docx

程序导入使用import时是:

 import docx  # 这一点需留意,不是python-docx

17-1 从Python看Word文件结构

在python-docx模块内,将Word文件结构分成3层:

  • Document这是最高层代表整个Word文件。

  • Paragraph一个Word文件是由许多的段落所组成,在Python中整份文件的定义是Document,这些段落的定义就是Paragraph对象。我们使用Word编辑文件时,如果单击一次Enter键,会产生一个新的段落。在Python中一个段落代表一个Paragraph对象,所有段落以Paragraph对象列表(list)方式存在。

  • Run Word文件要考虑的有字号、字体样式、色彩等,我们将这些称作样式。一个Run对象所指的是Paragraph对象中相同样式的连续文字,如果文字发生样式变化,Python将以新的Run对象代表。

在这里插入图片描述

上图有6个Run。

17-2 读取Word文件内容

17-2-1 建立docx对象

首先需建立Word文件(Document)的对象docx对象,可用Document( )方法建立,wdoc是自行取的名称,本书实例皆以wdoc为Document对象名称。

   wdoc = docx.Document(‘文件名')  # 建立docx对象wdoc

17-2-2 获得Paragraph和Run数量

可以使用len( )方法获得Paragraph数量。

   len(wdoc.paragraphs)  # wdoc是前一小节所建的docx对象

下列语法可以获得第n段Paragraph的Run数量。

 len(wdoc.paragraphs[n].runs)  # n是第几段或称Paragraph编号

17-2-3 列出Paragraph内容

可以使用下列语法打印第n段Paragraph内容。

  print(wdoc.paragraphs[n].text)

17-2-4 列出Paragraph内的Run内容

可以使用下列语法打印第n段Paragraph第m个Run内容。

  print(wdoc.paragraphs[n].runs[m].text)

17-2-5 读取和打印文件的应用

程序实例ch17_1.py:有一个Word文件data17_1.docx内容如下:

在这里插入图片描述

这个程序会做下列几件事:

  1. 第5行,列出Paragraph的数量,相当于段落的数量。

  2. 第6和7行,用循环打印各个Paragraph内容,相当于文件内容。

  3. 第9行,列出Paragraph 1的Run数量。

  4. 第10和11行,用循环打印Paragraph 1 Run内容。

  5. 第13行,列出Paragraph 2的Run数量。

  6. 第14和15行,用循环打印Paragraph 2 Run内容。

# ch17_1.py
import docx

wdoc = docx.Document('data17_1.docx')
print("段落数, 也可称Paragraph物件数量 = ", len(wdoc.paragraphs))
for i in range(0, len(wdoc.paragraphs)):
    print("paragraph %d = " % i, wdoc.paragraphs[i].text)

print("Paragraph 1的Run数量 = ", len(wdoc.paragraphs[1].runs))
for i in range(0, len(wdoc.paragraphs[1].runs)):
    print("Run %d = " % i, wdoc.paragraphs[1].runs[i].text)

print("Paragraph 2的Run数量 = ", len(wdoc.paragraphs[2].runs))
for i in range(0, len(wdoc.paragraphs[2].runs)):
    print("Run %d = " % i, wdoc.paragraphs[2].runs[i].text)

执行结果

段落数, 也可称Paragraph物件数量 =  5
paragraph 0 =  使用Python操作Word
paragraph 1 =  学习Python是一个很好的经验
paragraph 2 =  This book is published by Deep Stone.
paragraph 3 =  深石数字科技
paragraph 4 =  DeepStone is Deep Learning.
Paragraph 1的Run数量 =  5
Run 0 =  学习
Run 1 =  Python
Run 2 =  是一个
Run 3 =  很好的
Run 4 =  经验
Paragraph 2的Run数量 =  3
Run 0 =  This book is
Run 1 =   published by
Run 2 =   Deep Stone.

17-2-6 读取文件与适度编排输出

在操作Word文件时,也可以适度利用一些技巧,执行文件的编排。

程序实例ch17_2.py:这个程序主要是将所读取的Word文件,第一执行首行缩排2个字,第二段落间空一行输出。下列是data17_2.docx内容。
在这里插入图片描述

下列是程序内容。

# ch17_2.py
import docx

def getFile(fn):
    '''读取档案与适度编辑档案'''
    wdoc = docx.Document(fn)                # 建立Word档案物
    txt = []
    for paragraph in wdoc.paragraphs:
        print(paragraph.text)               # 输出文件所读取的Paragraph内容
        txt.append('    ' + paragraph.text) # 内缩同时将每一段Paragraph组成列表
    return '\n\n'.join(txt)                 # 将列表组成字符串同时段落隔行输出
print(getFile('data17_2.docx'))

执行结果

Word是二进制(binary)档案,同时Word还有字型格式、色彩与版面配置 … 等,所以它的处理方式比起文本文件(txt)要复杂。
本章内容需要使用外挂模块python-docx,读者可参考附录B下载此模块,尽管模块名称是python-docx,下载时指令是:
Word是二进制(binary)档案,同时Word还有字型格式、色彩与版面配置 … 等,所以它的处理方式比起文本文件(txt)要复杂。

本章内容需要使用外挂模块python-docx,读者可参考附录B下载此模块,尽管模块名称是python-docx,下载时指令是:

上述程序第8和9行是读取段落Paragraph内容后直接输出,可以得到前4行的输出结果。第8行至第10行是一个循环,第10行的功能是在段落Paragraph前方加上4个英文字符宽度,未来输出时会产生缩排2个中文字宽度的效果,第10行另外功能是将输出的段落Paragraph组成列表(list)。

程序第11行的join( )功能可以参考6-6-3小节,这个功能是将第10行建立的列表元素组织起来变成字符串,各字符串元素间使用‘\n\n\’分隔,这是2个换行符号,第一个‘\n’可以让下一个元素换行输出,第二个‘\n’就可以产生空一行输出的结果。

17-3 存储文件

save( )方法可以存储Document对象的文件,如果将建立Word文件与存储Word文件整个语法串连,整个语法如下:
在这里插入图片描述

程序实例ch17_3.docx:将文件data17_1.docx复制入out17_3.docx。

# ch17_3.py
import docx

wdoc = docx.Document('data17_1.docx')
wdoc.save('out17_3.docx')

执行结果 在目前文件夹可以建立与data17_1.docx相同内容的out17_3.docx。

17-4 建立文件内容

17-4-1 建立标题

可以使用下列add_heading( )方法建立文件标题内容。

wdoc.add_heading(‘content_of_heading')  # wdoc是自建的文件对象

上述预设会建立Heading 1的标题,Word的标题有1-9,如果想建立不同的标题可以使用第2个参数‘level=n’。

可以使用下列语法在建立文件标题内容同时设定标题格式。

   wdoc.add_heading(‘content_of_heading', level=n)  # wdoc是自建的文件对象

程序实例ch17_4.docx:建立Word标题的应用,这个程序会输出标题,同时将所建的Word文件存入out17_4.docx。

# ch17_4.py
import docx

wdoc = docx.Document()
wdoc.add_heading('明志科大')            # 预设是标题1格式
wdoc.add_heading('明志科大', level=2)   # 标题2格式
wdoc.add_heading('明志科大', level=3)   # 标题3格式
print(wdoc.paragraphs[0].text)
print(wdoc.paragraphs[1].text)
print(wdoc.paragraphs[2].text)
wdoc.save('out17_4.docx')

执行结果 下列是Python Shell窗口执行结果与out17_4.docx。

明志科大
明志科大
明志科大

由于Python Shell是文本模式的窗口,所以执行结果的输出看不出标题效果,但是若是用Word打开,可以看到标题效果,同时将插入点放在标题1字符串,可以在常用/样式看到标题1选项。
在这里插入图片描述

17-4-2 建立段落Paragraph内容

可以使用add_paragraph( )方法建立文件的段落(也可称Paragraph)内容。

ptr = wdoc.add_paragraph(‘paragraph_content')  # ptr是段落对象

上述ptr可以自行命名用于储存段落对象,这是可有可无的,但是如果有了这个段落对象,未来插入段落时可以将新段落插入此段落的前面,或是将Run内容插入此段落内。可以使用insert_paragraph_before( )方法,将段落插在上述ptr段落对象的前方,可参考程序实例ch17_5.py第9行。

程序实例ch17_5.docx:先插入2个段落,然后将新段落插在第一个段落的前面。

# ch17_5.py
import docx

wdoc = docx.Document()
ptr = wdoc.add_paragraph('我是第1段落')                     # 回传ptr段落物件
print(wdoc.paragraphs[0].text)
wdoc.add_paragraph('我是第2段落')                           # 不加回传也可以
print(wdoc.paragraphs[1].text)
prior_ptr = ptr.insert_paragraph_before('我是新的第1段落')  # 新段落插在ptr前面
print(wdoc.paragraphs[0].text)
wdoc.save('out17_5.docx')

执行结果 下列是Python Shell窗口执行结果与out17_5.docx。

我是第1段落
我是第2段落
我是新的第1段落

将插入点放在Paragraph[0]字符串,可以在常用/样式看到正文选项,正文选项是默认插入文件内容的样式(在17-6节,笔者会介绍插入Paragraph时同时处理样式)。
在这里插入图片描述

17-4-3 建立Run内容

Paragraph是由Run组成,当我们建立Paragraph成功后,未来若是想要在Paragraph内插入内容,可以使用add_run( )方法,此方法的语法格式如下:

  ptr.add_run(‘run_content')  # ptr是段落对象, 插入run内容

程序实例ch17_6.py:先建立一个段落,然后将Run加在这个段落内。

# ch17_6.py
import docx

wdoc = docx.Document()
ptr = wdoc.add_paragraph('我是第1段落') # 回传ptr段落物件
print(wdoc.paragraphs[0].text)          # 打印段落
ptr.add_run('第一个run内容')            # 将run加入ptr段落对象
ptr.add_run('第二个新run内容')          # 将run加入ptr段落对象
print(wdoc.paragraphs[0].text)          # 打印段落
wdoc.save('out17_6.docx')

执行结果 下列是Python Shell窗口执行结果与out17_6.docx。

我是第1段落
我是第1段落第一个run内容第二个新run内容

在这里插入图片描述

17-4-4 强制换页输出

下列add_page_break( )方法可以强制Word换页。

wdoc.add_page_break( )

未来如果有插入段落时,会在新一页出现。

程序实例ch17_7.docx:强制换页输出的应用。

# ch17_7.py
import docx

wdoc = docx.Document()
ptr = wdoc.add_paragraph('我是第1段落')     # 回传ptr段落物件
wdoc.add_paragraph('我是第2段落')           # 不加回传也可以
wdoc.add_page_break()                       # 插入换页      
wdoc.add_paragraph('我是新的页开始段落')    # 新段落插在新的一页
wdoc.save('out17_7.docx')

执行结果 下列是out17_7.docx第一页与第二页的结果。

在这里插入图片描述

17-4-5 插入图片

可以使用add_picture( )方法插入图片到Word文件内,如下所示:

 wdoc.add_picture(‘image_file')

如果插入图片时想要设定图片的宽度或高度,需导入docx.shared模块,然后就可以在add_picture( )方法内增加使用第2个参数width(宽度)或height(高度),然后用Inches( )英寸函数或Cm( )公分函数设定图片宽度。

 from docx.shared import Inches
 wdoc.add_picture(‘image_file', width=Inches(宽度值))

程序实例ch17_8.docx:插入图片的应用,图片宽度是1.0英寸。

# ch17_8.py
import docx
from docx.shared import Inches

wdoc = docx.Document()
wdoc.add_paragraph('晓波相片')     
wdoc.add_picture('晓波.jpg', width=Inches(1.0))
wdoc.save('out17_8.docx')

执行结果 下列是out17_8.docx内容。

在这里插入图片描述

17-5 建立表格

add_table( )方法可以建立表格。

 table = wdoc.add_table(rows=?, cols=?)  # 执行完后返回table表格对象

17-5-1 建立表格内容

建议可以一次处理一列的表格内容,如下所示:

 row = table.rows[0]
 row.cells[0].text = ‘表格(0, 0)内容'
 row.cells[1].text = ‘表格(0, 1)内容'

程序实例ch17_9.py:建立一个2 rows和2 cols的表格。

# ch17_9.py
import docx

wdoc = docx.Document()
table = wdoc.add_table(rows=2, cols=2)
row = table.rows[0]             # 建立row 0表格数据
row.cells[0].text = '书号'
row.cells[1].text = '我的著作'
row = table.rows[1]             # 建立row 1表格数据
row.cells[0].text = 'XA1711'
row.cells[1].text = 'HTML5+CSS3王者归来'
wdoc.save('out17_9.docx')

执行结果 下列是out17_9.docx内容。
在这里插入图片描述

17-5-2 插入表格列

可以使用add_row( )插入表格列。

程序实例ch17_10.py:重新设计ch17_9.py,插入表格列和输入表格列数据。

# ch17_10.py
import docx

wdoc = docx.Document()
table = wdoc.add_table(rows=2, cols=2)
row = table.rows[0]
row.cells[0].text = '书号'
row.cells[1].text = '我的著作'
row = table.rows[1]
row.cells[0].text = 'XA1711'
row.cells[1].text = 'HTML5+CSS3王者归来'
# 增加表格列和输入数据
new_row = table.add_row()   # 增加表格行          
new_row.cells[0].text = 'XA1774'
new_row.cells[1].text = 'Python王者归来'
wdoc.save('out17_10.docx')

执行结果 下列是out17_10.docx内容。
在这里插入图片描述

17-5-3 计算表格的rows和cols的长度

可以使用len( )函数计算表格的rows和cols的长度。

程序实例ch17_11.py:计算程序实例ch17_10.py所建表格的rows和cols的长度。

# ch17_11.py
import docx

wdoc = docx.Document()
table = wdoc.add_table(rows=2, cols=2)
row = table.rows[0]
row.cells[0].text = '书号'
row.cells[1].text = '我的著作'
row = table.rows[1]
row.cells[0].text = 'XA1711'
row.cells[1].text = 'HTML5+CSS3王者归来'
# 增加表格行和输入数据
new_row = table.add_row()                   # 增加表格行          
new_row.cells[0].text = 'XA1774'
new_row.cells[1].text = 'Python王者归来'
print('rows = ', len(table.rows))           # 计算和打印rows
print('cols = ', len(table.columns))        # 计算和打印cols

执行结果

rows =  3
cols =  2

17-5-4 打印表格内容

可以使用双层循环打印表格内容,细节可参考下列实例ch17_12.py第17至19行。

程序实例ch17_12.py:打印ch17_10.py所建的表格内容。

# ch17_12.py
import docx

wdoc = docx.Document()
table = wdoc.add_table(rows=2, cols=2)
row = table.rows[0]
row.cells[0].text = '书号'
row.cells[1].text = '我的著作'
row = table.rows[1]
row.cells[0].text = 'XA1711'
row.cells[1].text = 'HTML5+CSS3王者归来'
# 增加表格行和输入数据
new_row = table.add_row()                   # 增加表格行          
new_row.cells[0].text = 'XA1774'
new_row.cells[1].text = 'Python王者归来'
# 双层循环打印表格
for row in table.rows:
    for cell in row.cells:
        print(cell.text)

执行结果

书号
我的著作
XA1711
HTML5+CSS3王者归来
XA1774
Python王者归来

17-5-5 表格的样式

先前所打印的表格没有框线,可以使用table.style设定框线。

程序实例ch17_13.py:使用框线样式‘LightShading-Accent1’设定程序ch17_10.py所建立的表格。

# ch17_13.py
import docx

wdoc = docx.Document()
table = wdoc.add_table(rows=2, cols=2)
row = table.rows[0]
row.cells[0].text = '书号'
row.cells[1].text = '我的著作'
row = table.rows[1]
row.cells[0].text = 'XA1711'
row.cells[1].text = 'HTML5+CSS3王者归来'
# 增加表格行和输入数据
new_row = table.add_row()                   # 增加表格行          
new_row.cells[0].text = 'XA1774'
new_row.cells[1].text = 'Python王者归来'
table.style = 'LightShading-Accent1'        # 设定表格样式
wdoc.save('out17_13.docx')

执行结果 这个程序执行时有Warning信息,可以不必理会,下列是out17_13.docx内容。
在这里插入图片描述

如果打开表格样式表单将鼠标光标移至样式表单,可以看到各个样式表单名称,不过目前笔者写此书时的python-docx 0.86版本尚未支持中文样式表单。上述第16行是设定表格的样式,LightShading是浅色底纹,Accent1是辅色1,若是调整为Accent2,……,Accent6将有不同的结果。

17-6 Paragraph样式

Paragraph样式就是所谓的段落样式,下列是常见的Word样式内容。
在这里插入图片描述

上述list、listBullet、ListNumber如果是编号1可以省略编号,如果是编号2和3则可以标明。Heading则是由Heading1、……、Heading9所组成。我们在插入段落时,可以在add_paragraph( )方法内增加第2个参数“style=样式名称”,这样就可以在插入段落同时设定段落的样式,可参考下列程序第5行。

程序实例ch17_14.py:建立段落时,同时设定段落的样式。

# ch17_14.py
import docx

wdoc = docx.Document()
wdoc.add_paragraph('明志科大', style='ListNumber')    # ListNumber
wdoc.add_paragraph('长庚科大', style='ListNumber')    # ListNumber
wdoc.add_paragraph('长庚大学', style='ListNumber')    # ListNumber
wdoc.add_paragraph('明志科大', style='ListBullet')    # ListBullet
wdoc.add_paragraph('长庚科大', style='ListBullet')    # ListBullet
wdoc.add_paragraph('长庚大学', style='ListBullet')    # ListBullet
wdoc.save('out17_14.docx')

执行结果 执行时会有Warning消息。
在这里插入图片描述

17-7 Run的样式

Run的样式重点就是设定Run的文字(text)属性,下列是常见的属性。

   bold(粗体)  italic(斜体)  underline(下画线)  strike(删除线)

当我们建立一个Run对象时,会回传Run对象,此时若将此对象的样式设为True,相当于可以建立该Run对象的样式。整个细节读者可以参考第4-7行。

程序实例ch17_15.py:建立Run内容,然后设定此内容的属性为粗体(bold)与斜体(italic)的应用。

# ch17_15.py
import docx

wdoc = docx.Document()
ptr = wdoc.add_paragraph('我是第1段落')  # 回传ptr段落物件
run1 = ptr.add_run('我是粗体')           # 将run加入ptr段落对象
run1.bold = True                         # 设定粗体
run2 = ptr.add_run('我是斜体')           # 将run加入ptr段落对象
run2.italic = True                       # 设定斜体
wdoc.save('out17_15.docx')  

执行结果
在这里插入图片描述

17-8 综合应用——抢救CIA情报员

在16-7-2小节笔者有介绍这个范例,当时文字适用msg字符串方式表示,在真实的应用中所有文件皆是以Word方式表达,这一节将用读取Word文件方式重新设计ch16_37.py。

程序实例ch17_16.py:重新设计ch16_37.py,下列是data17_16.docx的内容。
在这里插入图片描述

下列是程序内容。

# ch17_16.py
import docx
import re

wdoc = docx.Document('data17_16.docx')
txt = docx.Document()
pattern = r'CIA (\w)\w*'                # 欲搜寻FBI + 空一格后的名字        
newstr = r'\1***'                       # 新字符串使用隐藏文字
txt.add_paragraph(re.sub(pattern,newstr,wdoc.paragraphs[0].text))
txt.save('out17_16.docx')

执行结果 下列是out17_16.docx的内容。

在这里插入图片描述

更多有关Python-docx的用法,读者可参考下列Python官方网页。

https://python-docx.readthedocs.io/en/latest/
在这里插入图片描述

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值