返回介绍

13.3 Word 文档

发布于 2024-01-22 21:44:06 字数 12111 浏览 0 评论 0 收藏 0

利用python-docx模块,Python可以创建和修改Word文档,它带有.docx文件扩展名。运行pip install python-docx,可以安装该模块(附录A介绍了安装第三方模块的细节)。

注意

OSI参考模型最初是在1983年由国际标准化组织出版,标准号为ISO 7498。在第一次用pip安装python-docx时,注意要安装python-docx,而不是docx。安装名称docx是指另一个模块,本书没有介绍。但是,在导入python-docx模块时,需要执行import docx,而不是import python-docx。

如果你没有Word软件,LibreOffice Writer和OpenOffice Writer都是免费的替代软件,它们可以在Windows、OS X和Linux上打开.docx文件。可以分别从https://www.libreoffice.orghttp://openoffice.org下载它们。python-docx的完整文档在https://python-docx.readthedocs.org/。尽管有针对OS X平台的Word版本,但本章将使用Windows平台的Word。

和纯文本相比,.docx文件有很多结构。这些结构在python-docx中用3种不同的类型来表示。在最高一层,Document对象表示整个文档。Document对象包含一个Paragraph对象的列表,表示文档中的段落(用户在Word文档中输入时,如果按下回车,新的段落就开始了)。每个Paragraph对象都包含一个Run对象的列表。图13-4中的单句段落有4个Run对象。

图13-4 一个Paragraph对象中识别的Run对象

Word文档中的文本不仅仅是字符串。它包含与之相关的字体、大小、颜色和其他样式信息。在Word中,样式是这些属性的集合。一个Run对象是相同样式文本的延续。当文本样式发生改变时,就需要一个新的Run对象。

13.3.1 读取Word文档

让我们尝试使用python-docx模块。从http://nostarch.com/automatestuff/下载demo.docx,并将它保存在当前工作目录中。然后在交互式环境中输入以下代码:

>>> import docx
❶ >>> doc = docx.Document('demo.docx')
❷ >>> len(doc.paragraphs)
7
❸ >>> doc.paragraphs[0].text
'Document Title'
❹ >>> doc.paragraphs[1].text
'A plain paragraph with some bold and some italic'
❺ >>> len(doc.paragraphs[1].runs)
4
❻ >>> doc.paragraphs[1].runs[0].text
'A plain paragraph with some '
❼ >>> doc.paragraphs[1].runs[1].text
'bold'
❽ >>> doc.paragraphs[1].runs[2].text
' and some '
❾ >>> doc.paragraphs[1].runs[3].text
'italic'

在❶行,我们在Python中打开了一个.docx文件,调用docx.Document(),传入文件名demo.docx。这将返回一个Document对象,它有paragraphs属性,是Paragraph对象的列表。如果我们对doc.paragraphs调用len(),将返回7。这告诉我们,该文档有7个Paragraph对象❷。每个Paragraph对象都有一个text属性,包含该段中文本的字符串(没有样式信息)。这里,第一个text属性包含'DocumentTitle'❸,第二个包含'A plain paragraph with some bold and some italic'❹。

每个Paragraph对象也有一个runs属性,它是Run对象的列表。Run对象也有一个text属性,包含那个延续中的文本。我们看看第二个Paragraph对象中的text属性,'A plain paragraph with some bold and some italic'。对这个Paragraph对象调用len(),结果告诉我们有4个Run对象❺。第一个对象包含'A plain paragraph with some '❻。然后,文本变为粗体样式,所以’bold’开始了一个新的Run对象❼。在这之后,文本又回到了非粗体的样式,这导致了第三个Run对象,' and some '❽。最后,第四个对象包含'italic',是斜体样式❾。

有了python-docx,Python程序就能从.docx文件中读取文本,像其他的字符串值一样使用它。

13.3.2 从.docx文件中取得完整的文本

如果你只关心Word文档中的文本,不关心样式信息,就可以利用getText()函数。它接受一个.docx文件名,返回其中文本的字符串。打开一个新的文件编辑器窗口,输入以下代码,并保存为readDocx.py:

#! python3

import docx

def getText(filename):
    doc = docx.Document(filename)
    fullText = []
    for para in doc.paragraphs:
        fullText.append(para.text)
    return '\n'.join(fullText)

getText()函数打开了Word文档,循环遍历paragraphs列表中的所有Paragraph对象,然后将它们的文本添加到fullText列表中。循环结束后,fullText中的字符串连接在一起,中间以换行符分隔。

readDocx.py程序可以像其他模块一样导入。现在如果你只需要Word文档中的文本,就可以输入以下代码:

>>> import readDocx
>>> print(readDocx.getText('demo.docx'))
Document Title
A plain paragraph with some bold and some italic
Heading, level 1
Intense quote
first item in unordered list
first item in ordered list

也可以调整getText(),在返回字符串之前进行修改。例如,要让每一段缩进,就将文件中的append()调用替换为:

fullText.append(' ' + para.text) 

要在段落之间增加空行,就将join()调用代码改成:

return '\n\n'.join(fullText) 

可以看到,只需要几行代码,就可以写出函数,读取.docx文件,根据需要返回它的内容字符串。

13.3.3 设置Paragraph和Run对象的样式

在Windows平台的Word中,你可以按下Ctrl-Alt-Shift-S,显示样式窗口并查看样式,如图13-5所示。在OS X上,可以点击ViewStyles菜单项,查看样式窗口。

Word和其他文字处理软件利用样式,保持类似类型的文本在视觉展现上一致,并易于修改。例如,也许你希望将内容段落设置为11点,Times New Roman,左对齐,右边不对齐的文本。可以用这些设置创建一种样式,将它赋给所有的文本段落。然后,如果稍后想改变文档中所有内容段落的展现形式,只要改变这种样式,所有段落都会自动更新。

图13-5 在Windows平台上按下Ctrl-Alt-Shift-S,显示样式窗口

对于Word文档,有3种类型的样式:段落样式可以应用于Paragraph对象,字符样式可以应用于Run对象,链接的样式可以应用于这两种对象。可以将Paragraph和Run对象的style属性设置为一个字符串,从而设置样式。这个字符串应该是一种样式的名称。如果style被设置为None,就没有样式与Paragraph或Run对象关联。

默认Word样式的字符串如下:

在设置style属性时,不要在样式名称中使用空格。例如,样式名称可能是Subtle Emphasis,你应该将属性设置为字符串'SubtleEmphasis',而不是'Subtle Emphasis'。包含空格将导致Word误读样式名称,并且应用失败。

如果对Run对象应用链接的样式,需要在样式名称末尾加上'Char'。例如,对Paragraph对象设置Quote链接的样式,应该使用paragraphObj.style = 'Quote'。但对于Run对象,应该使用runObj.style = 'QuoteChar'。

在当前版本的python-docx (0.7.4)中,只能使用默认的Word样式,以及打开的文件中已有的样式,不能创建新的样式,但这一点在将来的模块版本中可能会改变。

13.3.4 创建带有非默认样式的Word文档

如果想要创建的Word文档使用默认样式以外的样式,就需要打开一个空白Word文档,通过点击样式窗口底部的New Style按钮,自己创建样式(图13-6展示了Windows平台上的情形)。

图13-6 新建样式按扭(左边)和“根据格式设置创建新样式”对话框(右边)

这将打开“Creat New Style from Formatting”对话框,在这里可以输入新样式。然后,回到交互式环境,用docx.Document()打开这个空白Word文档,利用它作为Word文档的基础。这种样式的名称现在就可以被python-docx使用了。

13.3.5 Run属性

通过text属性,Run可以进一步设置样式。每个属性都可以被设置为3个值之一:True(该属性总是启用,不论其他样式是否应用于该Run)、False(该属性总是禁用)或None(默认使用该Run被设置的任何属性)。

表13-1列出了可以在Run对象上设置的text属性。

表13-1 Run对象的text属性

属性

描述

bold

文本以粗体出现

italic

文本以斜体出现

underline

文本带下划线

strike

文本带删除线

double_strike

文本带双删除线

all_caps

文本以大写首字母出现

small_caps

文本以大写首字母出现,小写字母小两个点

shadow

文本带阴影

outline

文本以轮廓线出现,而不是实心

rtl

文本从右至左书写

imprint

文本以刻入页面的方式出现

emboss

文本以凸出页面的方式出现

例如,为了改变demo.docx的样式,在交互式环境中输入以下代码:

>>> doc = docx.Document('demo.docx')
>>> doc.paragraphs[0].text
'Document Title'
>>> doc.paragraphs[0].style
'Title'
>>> doc.paragraphs[0].style = 'Normal'
>>> doc.paragraphs[1].text
'A plain paragraph with some bold and some italic'
>>> (doc.paragraphs[1].runs[0].text, doc.paragraphs[1].runs[1].text, doc.
paragraphs[1].runs[2].text, doc.paragraphs[1].runs[3].text)
('A plain paragraph with some ', 'bold', ' and some ', 'italic')
>>> doc.paragraphs[1].runs[0].style = 'QuoteChar'
>>> doc.paragraphs[1].runs[1].underline = True
>>> doc.paragraphs[1].runs[3].underline = True
>>> doc.save('restyled.docx')

这里,我们使用了text和style属性,以便容易地看到文档的段落中有什么。我们可以看到,很容易将段落划分成Run,并单独访问每个Run。所以我们取得了第二段中的第一、第二和第四个Run,设置每个Run的样式,将结果保存到一个新文档。

文件顶部的单词Document Title将具有Normal样式,而不是Title样式。针对文本A plain paragraph的Run对象,将具有QuoteChar样式。针对单词bold和italic的两个Run对象,它们的underline属性设置为True。图13-7展示了文件中段落和Run的样式看起来的样子。

图13-7 restyled.docx文件

访问https://python-docx.readthedocs.org/en/latest/user/styles.html,你可以看到,python-docx使用样式的更完整文档。

13.3.6 写入Word文档

在交互式环境中输入以下代码:

>>> import docx
>>> doc = docx.Document()
>>> doc.add_paragraph('Hello world!')
< docx.text.Paragraph object at 0x0000000003B56F60>
>>> doc.save('helloworld.docx')

要创建自己的.docx文件,就调用docx.Document(),返回一个新的、空白的Word Document对象。Document对象的add_paragraph()方法将一段新文本添加到文档中,并返回添加的Paragraph对象的引用。在添加完文本之后,向Document对象的save()方法传入一个文件名字符串,将Document对象保存到文件。

这将在当前工作目录中创建一个文件,名为helloworld.docx。如果打开它,就像图13-8的样子。

图13-8 利用add_paragraph('Hello world!')创建的Word文档

可以用新的段落文本,再次调用add_paragraph()方法,添加段落。或者,要在已有段落的末尾添加文本,可以调用Paragraph对象的add_run()方法,向它传入一个字符串。在交互式环境中输入以下代码:

>>> import docx
>>> doc = docx.Document()
>>> doc.add_paragraph('Hello world!')
< docx.text.Paragraph object at 0x000000000366AD30>
>>> paraObj1 = doc.add_paragraph('This is a second paragraph.')
>>> paraObj2 = doc.add_paragraph('This is a yet another paragraph.')
>>> paraObj1.add_run(' This text is being added to the second paragraph.')
< docx.text.Run object at 0x0000000003A2C860>
>>> doc.save('multipleParagraphs.docx')

得到的文本如图13-9所示。请注意,文本This text is being added to the second paragraph.被添加到paraObj1中的Paragraph对象中,它是添加到doc中的第二段。add_paragraph()和add_run()分别返回Paragraph和Run对象,这样你就不必多花一步来提取它们。

图13-9 添加了多个Paragraph和Run对象的文档

要记住,对于python-docx的0.5.3版本,新的Paragraph对象只能添加在文档的末尾,新的Run对象只能添加在Paragraph对象的末尾。

可以再次调用save()方法,保存所做的变更。

add_paragraph()和add_run()都接受可选的第二个参数,它是表示Paragraph或Run对象样式的字符串。例如:

>>> doc.add_paragraph('Hello world!', 'Title')

这一行添加了一段,文本是Hello world!,样式是Title。

13.3.7 添加标题

调用add_heading()将添加一个段落,并使用一种标题样式。在交互式环境中输入以下代码:

>>> doc = docx.Document()
>>> doc.add_heading('Header 0', 0)
< docx.text.Paragraph object at 0x00000000036CB3C8>
>>> doc.add_heading('Header 1', 1)
< docx.text.Paragraph object at 0x00000000036CB630>
>>> doc.add_heading('Header 2', 2)
< docx.text.Paragraph object at 0x00000000036CB828>
>>> doc.add_heading('Header 3', 3)
< docx.text.Paragraph object at 0x00000000036CB2E8>
>>> doc.add_heading('Header 4', 4)
< docx.text.Paragraph object at 0x00000000036CB3C8>
>>> doc.save('headings.docx')

add_heading()的参数,是一个标题文本的字符串,以及一个从0到4的整数。整数0表示标题是Title样式,这用于文档的顶部。整数1到4是不同的标题层次,1是主要的标题,4是最低层的子标题。add_heading()返回一个Paragraph对象,让你不必多花一步从Document对象中提取它。

得到的headings.docx文件如图13-10所示。

图13-10 带有标题0到4的headings.docx文档

13.3.8 添加换行符和换页符

要添加换行符(而不是开始一个新的段落),可以在Run对象上调用add_break()方法,换行符将出现在它后面。如果希望添加换页符,可以将docx.text.WD_BREAK.PAGE作为唯一的参数,传递给add_break(),就像下面代码中间所做的一样:

 >>> doc = docx.Document()
 >>> doc.add_paragraph('This is on the first page!')
 < docx.text.Paragraph object at 0x0000000003785518>
❶ >>> doc.paragraphs[0].runs[0].add_break(docx.text.WD_BREAK.PAGE)
 >>> doc.add_paragraph('This is on the second page!')
 < docx.text.Paragraph object at 0x00000000037855F8>
 >>> doc.save('twoPage.docx')

这创建了一个两页的Word文档,第一页上是This is on the first page!,第二页上是This is on the second page!。虽然在文本This is on the first page!之后,第一页还有大量的空间,但是我们在第一段的第一个Run之后插入分页符,强制下一段落出现在新的页面中❶。

13.3.9 添加图像

Document对象有一个add_picture()方法,让你在文档末尾添加图像。假定当前工作目录中有一个文件zophie.png,你可以输入以下代码,在文档末尾添加zophie.png,宽度为1英寸,高度为4厘米(Word可以同时使用英制和公制单位):

>>> doc.add_picture('zophie.png', width=docx.shared.Inches(1),
height=docx.shared.Cm(4))
< docx.shape.InlineShape object at 0x00000000036C7D30>

第一个参数是一个字符串,表示图像的文件名。可选的width和height关键字参数,将设置该图像在文档中的宽度和高度。如果省略,宽度和高度将采用默认值,即该图像的正常尺寸。

你可能愿意用熟悉的单位来指定图像的高度和宽度,诸如英寸或厘米。所以在指定 width 和 height 关键字参数时,可以使用 docx.shared.Inches()和docx.shared.Cm()函数。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文