1. 简介
python-docx 是一个用于创建和更改 Microsoft Word (.docx) 文件的 Python 包。
1.1 安装
注意
python-docx 版本 0.3.0 及更高版本与以前的版本不兼容 API。
python-docx 托管在 PyPI 上,因此安装相对简单,仅取决于您安装了什么安装工具。
(1)pip 安装:
pip install python-docx
(2)可以使用 easy_install(尽管不推荐):
easy_install python-docx
(3)也可以通过从 PyPI 下载发行版、解压 tar 包并运行来手动安装它 setup.py:
tar xvzf python-docx-{version}.tar.gz
cd python-docx-{version}
python setup.py install
python-docx 依赖于 lxml 包。pip 和 easy_install 两者都将为您解决这些依赖关系,但如果您使用最后一种方法,您将需要自己安装它们。
依赖
Python 2.6、2.7、3.3 或 3.4
lxml >= 2.3.2
1.2 能做什么(一个 Demo)
from docx import Document
from docx.shared import Inches
doc = Document()
doc.add_heading('Document Title', 0)
pg = doc.add_paragraph('A plain paragraph having some ')
pg.add_run('bold').bold = True
pg.add_run(' and some ')
pg.add_run('italic.').italic = True
doc.add_heading('Heading, level 1', level=1)
doc.add_paragraph('Intense quote', style='Intense Quote')
doc.add_paragraph('first item in unordered list', style='List Bullet')
doc.add_paragraph('first item in ordered list', style='List Number')
doc.add_picture('./blogs/figures/run.jpeg', width=Inches(1.25))
records = (
(3, '101', 'Spam'),
(7, '422', 'Eggs'),
(4, '631', 'Spam, spam, eggs, and spam')
)
table = doc.add_table(rows=1, cols=3)
hdr_cells = table.rows[0].cells # 默认有一行
hdr_cells[0].text = 'Qty'
hdr_cells[1].text = 'Id'
hdr_cells[2].text = 'Desc'
for qty, id, desc in records:
row_cells = table.add_row().cells
row_cells[0].text = str(qty) # str
row_cells[1].text = id
row_cells[2].text = desc
doc.add_page_break()
doc.save('demo.docx')
(1)创建(打开)一个文档 document
创建一个 document 对象:
from docx import Document
document = Document()
这和在 Word 中使用默认设置创建一个新文档差不多。也可以打开并处理现有的 Word 文档(后面介绍)。
(2)添加段落(paragraph)
paragraph = document.add_paragraph('Lorem ipsum dolor sit amet.')
该方法在文档末尾添加新的段落,返回对新建段落的引用。利用该引用可以执行一些操作,比如在该段落前添加一个段落:
prior_paragraph = paragraph.insert_paragraph_before('Lorem ipsum')
(3)应用段落样式
可以在创建段落时应用段落样式:
document.add_paragraph('Lorem ipsum dolor sit amet.', style='ListBullet')
这使段落显示为项目符号。也可以在之后应用样式:
paragraph = document.add_paragraph('Lorem ipsum dolor sit amet.')
paragraph.style = 'List Bullet'
通常,样式名称与 Word 用户界面 (UI) 中的样式名称完全相同。
(4)应用粗体和斜体
在段落(paragraph
)中,具有相同格式的一段文本称为一个 run
。python-docx 在 run
级别应用字符级格式,例如粗体和斜体 。例如下图的段落需要五个 run
,图片来源:
当通过 .add_paragraph(text)
方法向文档添加 text
文本时,text
会被放入一个 run
中,样式默认。可以使用 .add_run()
方法向段落添加更多内容:
paragraph = document.add_paragraph('Lorem ipsum ')
paragraph.add_run('dolor sit amet.')
Run
对象有 .bold
和 .italic
等属性:
paragraph = document.add_paragraph('Lorem ipsum ')
run = paragraph.add_run('dolor')
run.bold = True
paragraph.add_run(' sit amet.')
这会产生如下所示的文本:
Lorem ipsum dolor sit amet.
.add_run()
返回所添加的 run
对象的引用,如果不需要对它进行其他操作,可以放弃该引用,直接在结果上设置粗体或斜体:
paragraph.add_run('dolor').bold = True
# is equivalent to:
run = paragraph.add_run('dolor')
run.bold = True
不必为 .add_paragraph()
方法提供文本,这可以使您的代码更简单:
paragraph = document.add_paragraph()
paragraph.add_run('Lorem ipsum ')
paragraph.add_run('dolor').bold = True
paragraph.add_run(' sit amet.')
(5)应用字符样式
除了 paragraph
级别的段落样式之外,Word 还有 run
级别的字符样式。一般来说,可以将字符样式视为指定字体,包括其字体、大小、颜色、粗体、斜体等。
添加新 run
时可以指定字符样式:
paragraph.add_run('text with emphasis.', 'Emphasis')
还可以在创建 run
后将样式应用到 run
:
run = paragraph.add_run('text with emphasis.')
run.style = 'Emphasis'
与段落样式一样,样式名称与 Word UI 中显示的名称相同。
(6)添加标题(heading)
document.add_heading('The REAL meaning of the universe')
默认情况下,这会添加一个顶级标题,就是 Word 中的“标题 1”。将参数 level
指定为 1 到 9 之间的整数,可得小节的标题:
document.add_heading('The role of dolphins', level=2)
如果指定级别为 0,则会添加“标题”段落。
(7)添加分页(page_break)
document.add_page_break()
(8)添加表格
table = document.add_table(rows=2, cols=2)
可以通过行列索引访问单元格(索引从零开始):
cell = table.cell(0, 1)
单元格可以放一些东西:
cell.text = 'parrot, possibly dead'
表的 .rows
属性提供对各行的访问,每行都有一个 .cells属性:
row = table.rows[1]
row.cells[0].text = 'Foo bar to you.'
row.cells[1].text = 'And a hearty foo bar to you too sir!'
.columns
与 .rows
同理,提供对各列的访问。可以直接在 for
循环中使用它们:
for row in table.rows:
for cell in row.cells:
print(cell.text)
row = table.add_row()
以增量方式添加行到表中:
# get table data -------------
items = (
(7, '1024', 'Plush kittens'),
(3, '2042', 'Furbees'),
(1, '1288', 'French Poodle Collars, Deluxe'),
)
# add table ------------------
table = document.add_table(1, 3)
# populate header row --------
heading_cells = table.rows[0].cells
heading_cells[0].text = 'Qty'
heading_cells[1].text = 'SKU'
heading_cells[2].text = 'Description'
# add a data row for each item
for qty, sku, desc in items:
cells = table.add_row().cells # 添加后直接返回了 cells
cells[0].text = str(qty)
cells[1].text = sku
cells[2].text = desc
Word 中有一组预先定义的表格样式,鼠标悬停在“设计”中的样式预览上可以看到样式的名字,删除其中的所有空格,可用于 python-docx
的 table
:
table.style = 'LightShading-Accent1'
# UserWarning: style lookup by style_id is deprecated. Use style name as key instead. 有人知道为什么吗?
(9)添加图片(picture)
document.add_picture('image-filename.png')
默认情况下,添加的图像以原始大小显示。可以指定其宽度或高度,单位 Inches
或 Cm
:
from docx.shared import Inches
document.add_picture('image-filename.png', width=Inches(1.0))
如果只指定宽和高的一个,python-docx
自动计算另一个的正确缩放值。
2. 具体功能介绍
2.1 处理文档
from docx import Document
document = Document()
document.save('test.docx')
这会从默认模板创建一个新文档,并将其保存到名为“test.docx”的文件中。所谓的“默认模板”其实就是一个没有内容的 Word 文件,和安装的 python-docx 包一起存放。它与 Word 文档的模板大致相同。
打开现有文档:
document = Document('existing-document-file.docx')`
注意
- 仅可以打开
.docx
文档,不支持doc
。- 并不是所有 Word 的功能都支持,如页眉页脚等功能尚在开发中。虽然无法操作它们,但 python-docx 依然能够加载和保存它们。
可以传递打开的文件或 StringIO/BytesIO 流对象来打开或保存文档,如下所示:
f = open('foobar.docx', 'rb')
document = Document(f)
f.close()
# or
with open('foobar.docx', 'rb') as f:
source_stream = StringIO(f.read())
document = Document(source_stream)
source_stream.close()
...
target_stream = StringIO()
document.save(target_stream)
## 使用文本
# 段落属性
### 水平对齐
左对齐、居中对齐、右对齐、两端对齐,使用枚举值 `WD_PARAGRAPH_ALIGNMENT` 中的值:
```python
>>> from docx.enum.text import WD_ALIGN_PARAGRAPH
>>> document = Document()
>>> paragraph = document.add_paragraph()
>>> paragraph_format = paragraph.paragraph_format
>>> paragraph_format.alignment
None # indicating alignment is inherited from the style hierarchy
>>> paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
>>> paragraph_format.alignment
CENTER (1)
2.2 使用文本
2.2.1 段落属性
(1)水平对齐
左对齐、居中对齐、右对齐、两端对齐,使用枚举值 WD_PARAGRAPH_ALIGNMENT
中的值:
>>> from docx.enum.text import WD_ALIGN_PARAGRAPH
>>> document = Document()
>>> paragraph = document.add_paragraph()
>>> paragraph_format = paragraph.paragraph_format
>>> paragraph_format.alignment
None # indicating alignment is inherited from the style hierarchy
>>> paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
>>> paragraph_format.alignment
CENTER (1)
(2) 缩进
段落可以在左侧和右侧分别缩进。还有首行缩进、悬挂缩进。
缩进是使用一个 Length
值指定的,例如 Inches
、Pt
或 Cm
。值 None
表示缩进值是从样式层次结构继承的。
>>> from docx.shared import Inches
>>> paragraph = document.add_paragraph()
>>> paragraph_format = paragraph.paragraph_format
>>> paragraph_format.left_indent
None # indicating indentation is inherited from the style hierarchy
>>> paragraph_format.left_indent = Inches(0.5)
>>> paragraph_format.left_indent
457200
>>> paragraph_format.left_indent.inches
0.5
右侧缩进的工作方式类似:
>>> from docx.shared import Pt
>>> paragraph_format.right_indent
None
>>> paragraph_format.right_indent = Pt(24)
>>> paragraph_format.right_indent
304800
>>> paragraph_format.right_indent.pt
24.0
首行缩进使用 first_line_indent
属性指定(负值表示悬挂缩进):
>>> paragraph_format.first_line_indent
None
>>> paragraph_format.first_line_indent = Inches(-0.25)
>>> paragraph_format.first_line_indent
-228600
>>> paragraph_format.first_line_indent.inches
-0.25
(3)制表位
段落或样式的制表位包含在 ParagraphFormat 属性,是一个 TabStops 对象:
>>> tab_stops = paragraph_format.tab_stops
>>> tab_stops
<docx.text.tabstops.TabStops object at 0x106b802d8>
使用 add_tab_stop()
方法添加新的制表位:
>>> tab_stop = tab_stops.add_tab_stop(Inches(1.5))
>>> tab_stop.position
1371600
>>> tab_stop.position.inches
1.5
默认是左对齐,但可以通过提供 WD_TAB_ALIGNMENT
枚举的成员来指定。前导字符默认为空格,但可以通过提供 WD_TAB_LEADER
枚举的成员来指定:
>>> from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER
>>> tab_stop = tab_stops.add_tab_stop(Inches(1.5), WD_TAB_ALIGNMENT.RIGHT, WD_TAB_LEADER.DOTS)
>>> print(tab_stop.alignment)
RIGHT (2)
>>> print(tab_stop.leader)
DOTS (1)
访问现有的制表位:
>>> tab_stops[0]
<docx.text.tabstops.TabStop object at 0x1105427e8>
(4)段落间距
space_before
和 space_after
属性控制后续段落之间的间距。两个段落之间的间距是第一段的 space_after
和第二段的 space_before
的最大值:
>>> paragraph_format.space_before, paragraph_format.space_after
(None, None) # inherited by default
>>> paragraph_format.space_before = Pt(18)
>>> paragraph_format.space_before.pt
18.0
>>> paragraph_format.space_after = Pt(12)
>>> paragraph_format.space_after.pt
12.0
(5)行距
行间距由属性 line_spacing
和 line_spacing_rule
控制。 line_spacing
是一个 Length
值、float
或 None
。Length
值表示绝对距离。float
表示行高的倍数。None
表示行距是继承的。line_spacing_rule
是 WD_LINE_SPACING
枚举的成员或 None
:
>>> from docx.shared import Length
>>> paragraph_format.line_spacing
None
>>> paragraph_format.line_spacing_rule
None
>>> paragraph_format.line_spacing = Pt(18)
>>> isinstance(paragraph_format.line_spacing, Length)
True
>>> paragraph_format.line_spacing.pt
18.0
>>> paragraph_format.line_spacing_rule
EXACTLY (4)
>>> paragraph_format.line_spacing = 1.75
>>> paragraph_format.line_spacing
1.75
>>> paragraph_format.line_spacing_rule
MULTIPLE (5)
(6)分页属性
四个段落属性:keep_together
、keep_with_next
、page_break_before
和 widow_control
控制段落在页面边界附近的行为方式。
keep_together
:整个段落出现在同一页面上,如果它会在两页之间被打破,则在段落之前发出分页符;keep_with_next
:将段落与后续段落保持在同一页上。例如,这可用于将节标题与节的第一段保持在同一页面上;page_break_before
:段落被放置在新页面的顶部。这可以用于章节标题以确保章节从新页面开始;widow_control
:分页以避免将段落的第一行或最后一行与段落的其余部分放在单独的页面上;
这四个属性都是三态的,可以取值 True
, False
或 None
。None
表示属性值是从样式层次结构继承的:
>>> paragraph_format.keep_together
None # all four inherit by default
>>> paragraph_format.keep_with_next = True
>>> paragraph_format.keep_with_next
True
>>> paragraph_format.page_break_before = False
>>> paragraph_format.page_break_before
False
2.2.2 应用字符格式
字符格式应用于 run
级别,比如字体、大小、粗体、斜体和下划线等。
Run object
有一个只读的 font
属性,值为一个 Font object
。这个 Font object
用于获取或设置 Run object
的字符格式。
可以像这样访问 run
的字体:
>>> from docx import Document
>>> document = Document()
>>> run = document.add_paragraph().add_run()
>>> font = run.font
字体和大小设置如下:
>>> from docx.shared import Pt
>>> font.name = 'Calibri'
>>> font.size = Pt(12)
许多 Font
属性是三态的。粗体和斜体是三态属性,全大写、删除线、上标和许多其他属性也是如此:
>>> font.bold, font.italic
(None, None)
>>> font.italic = True
>>> font.italic
True
>>> font.italic = False
>>> font.italic
False
>>> font.italic = None
>>> font.italic
None
下划线是一种特殊情况。它是三态属性和枚举值属性的混合体。True
表示单下划线,是最常见的。False
表示没有下划线,但如果不需要下划线,通常 None
是正确的选择。其他形式的下划线,例如双线或虚线,是使用 WD_UNDERLINE
枚举的成员指定的:
>>> font.underline
None
>>> font.underline = True
>>> # or perhaps
>>> font.underline = WD_UNDERLINE.DOT_DASH
(1) 字体颜色
每个 Font
对象都有一个 ColorFormat
对象。
将特定的 RGB 颜色应用于字体:
>>> from docx.shared import RGBColor
>>> font.color.rgb = RGBColor(0x42, 0x24, 0xE9)
还可以通过 MSO_THEME_COLOR_INDEX
枚举的成员将字体设置为主题颜色:
>>> from docx.enum.dml import MSO_THEME_COLOR
>>> font.color.theme_color = MSO_THEME_COLOR.ACCENT_1
可以将字体的颜色恢复为其默认(继承)值,方法是 将 rgb
or theme_color
设置为 None
:
>>> font.color.rgb = None
确定字体的颜色首先要确定其颜色类型:
>>> font.color.type
RGB (1)
>>> font.color.rgb
RGBColor(0x42, 0x24, 0xe9)
# or
>>> font.color.theme_color
ACCENT_1 (5)