>>> from helper import info; info()
页面更新时间: 2020-07-02 11:23:37
操作系统/OS: Linux-4.19.0-9-amd64-x86_64-with-debian-10.4 ;Python: 3.7.3
5.3. 微软DOCX文档¶
利用 python-docx
模块,Python可以创建和修改微软 DOCX
文档,它带有.docx文件扩展名。 运行 pip install python-docx
,可以安装该模块。
注意¶
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.org 和http://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 对象。
Word 文档中的文本不仅仅是字符串。它包含与之相关的
字体、大小、颜色和其他样式信息。在Word 中,样式是 这些属性的集合。一个
Run
对象是相同样式文本的 延续。当文本样式发生改变时,就需要一个新的
Run
对象。
读取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'
>>> for x in doc.paragraphs:
>>> print(x.text)
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
>>> doc.paragraphs[1].text
'A plain paragraph with some bold and some italic'
>>> len(doc.paragraphs[1].runs)
5
>>> doc.paragraphs[1].runs[0].text
'A plain paragraph with'
>>> doc.paragraphs[1].runs[1].text
' some '
>>> doc.paragraphs[1].runs[2].text
'bold'
>>> doc.paragraphs[1].runs[3].text
' and some '
在1行,我们在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文件中
读取文本,像其他的字符串值一样使用它。
从 DOCX 文件中取得完整的文本¶
如果你只关心Word文档中的文本,不关心样式信息, 就可以利用 getText()
函数。它接受一个.docx文件名,
返回其中文本的字符串。打开一个新的文件编辑器
窗口,输入以下代码,并保存为 readDocx.py
:
>>> 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
>>> readDocx.getText('demo.docx')
'Document TitlenA plain paragraph with some bold and some italicnHeading, level 1nIntense quotenfirst item in unordered listnfirst item in ordered listnn'
>>> 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 ‘:raw-latex:`\n`:raw-latex:`n `’.join(fullText)
可以看到,只需要几行代码,就可以写出函数,读取.docx文件, 根据需要返回它的内容字符串。
设置 Paragraph
和 Run
对象的样式¶
在Windows平台的Word中,你可以按下Ctrl-Alt-Shift-S, 显示样式窗口并查看样式,如图13-5所示。在OSX上, 可以点击View→Styles菜单项,查看样式窗口。
Word和其他文字处理软件利用样式,保持类似类型的文本
在视觉展现上一致,并易于修改。例如,也许你希望将
内容段落设置为11点,Times New Roman
,左对齐,
右边不对齐的文本。可以用这些设置创建一种样式,
将它赋给所有的文本段落。然后,如果稍后想改变文档中
所有内容段落的展现形式,只要改变这种样式,所有 段落都会自动更新。
图13-5在Windows平台上按下Ctrl-Alt-Shifl-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样式,以及打开的文件中已有的样式,不能创建新的 样式,但这一点在将来的模块版本中可能会改变。
创建带有非默认样式的Word文档¶
如果想要创建的Word文档使用默认样式以外的样式, 就需要打开一个空白Word文档,通过点击样式窗口 底部的New Style按钮,自己创建样式(图13-6展示 了Windows平台上的情形)。
图13-6新建样式按扭(左边)和“根据格式设置创 建新样式”对话框(右边)
这将打开“Creat New Style from Formatting”
对话框,在这里可以输入新样式。然后,回到交互 式环境,用
docx.Document()
打开这个空白
Word文档,利用它作为Word文档的基础。这种样式 的名称现在就可以被
python-docx
使用了。
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
_ParagraphStyle('Title') id: 140543097339632
>>> 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 ')
>>> 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')
/home/shaopp/.local/lib/python3.5/site-packages/docx/styles/styles.py:139: UserWarning: style lookup by style_id is deprecated. Use style name as key instead.
return self._get_style_id_from_style(self[style_name], style_type)
这里,我们使用了 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]
(https://python-docx.readthedocs.org/en/latest/user/styles.html),
你可以看到 python-docx
使用样式的更完整文档。
写入Word文档¶
在交互式环境中输入以下代码:
>>> import docx
>>> doc = docx.Document()
>>> doc.add_paragraph('Hello world')
<docx.text.paragraph.Paragraph at 0x7fd2bc24c7f0>
>>> 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.Paragraph at 0x7fd2bc24ca20>
>>> paraObjl = doc.add_paragraph('This is a second paragraph.')
>>> para0bj2 = doc.add_paragraph('This is a yet another paragraph.')
>>> paraObjl.add_run('This text is being added to the second paragraph.')
<docx.text.run.Run at 0x7fd2bc2397f0>
>>> doc.save('multipleParagraphs.docx')
得到的文本如图13-9所示。请注意,文本This text is being added to the
second paragraph.被添加到paraObjl
中的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')
<docx.text.paragraph.Paragraph at 0x7fd2bc227a90>
这一行添加了一段,文本是 Hello world!
,样式是`Title`` 。
添加标题¶
调用 add_heading()
将添加一个段落,并使用一种标题样式。
在交互式环境中输入以下代码:
>>> doc = docx.Document()
>>> doc.add_heading('Header 0', 0)
<docx.text.paragraph.Paragraph at 0x7fd2bc1f0be0>
>>> doc.add_heading('Header 1', 1)
<docx.text.paragraph.Paragraph at 0x7fd2bc1f0b38>
>>> doc.add_heading('Header 2', 2)
<docx.text.paragraph.Paragraph at 0x7fd2bc24c550>
>>> doc.add_heading('Header 3', 3)
<docx.text.paragraph.Paragraph at 0x7fd2bc24cac8>
>>> doc.add_heading('Header 4', 4)
<docx.text.paragraph.Paragraph at 0x7fd2bc1f60b8>
>>> 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文档
添加换行符和换页符¶
要添加换行符(而不是开始一个新的段落),可以在 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.Paragraph at 0x7fd2bc1f6400>
doc.paragraphs[0].runs[0].add_break(docx.text.WD_BREAK_PAGE) doc.add_paragraph(‘This is on the second page!’)
>>> doc.save('twoPage.docx')
这创建了一个两页的Word文档,第一页上是
This is on the first page!
,第二页上是
This is on the second page!
。虽然在文本
This is on the first page!
之后,第一页还
有大量的空间,但是我们在第一段的第一个Run
之后插入分页符,强制下一段落出现在新的页面中。
添加图像¶
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 at 0x7fd2bc1f4240>
第一个参数是一个字符串,表示图像的文件名。可选的 width
和 height
关键参数,将设置该图像在
文档中的宽度和高度。如果省略,宽度和高度将采用默认 即该图像的正常尺寸。
你可能愿意用熟悉的单位来指定图像的高度和宽度,诸如
英寸或厘米。所以在指定 width
和 height
关键字
参数时,可以使用docx_shared.Inches()
和 docx.shared.Cm()
函数。
小结¶
Word文档更可靠,可以用 python-docx
模块来读取。可以通过
Paragraph
和 Run
对象来操作Word文档中的文本。可以设置
这些对象的样式,尽管必须使用默认的样式,或文档中已有的样式。
可以添加新的段落、标题、换行换页符和图像,尽管只能在文档的 末尾。
在处理PDF和Word文档时有很多限制,这是因为这些格式的本意是 很好地展示给人看,而不是让软件易于解析。下一章将探讨存储 信息的另外两种常见格式:JSON和CSV文件。这些格式是设的。你会看到,Python处理这些格式要容易得多。
>>> import helper; helper.info()
页面更新时间: 2019-03-02 09:21:53
操作系统/OS: Linux-4.9.0-8-amd64-x86_64-with-debian-9.8
Python: 3.5.3