Python操纵Word神器——python-docx

文章目录

  • 简介
  • 安装
  • 初试
  • 基本概念
  • 快速上手
  • 使用文本
    • 块级与内联文本对象
    • 段落属性
      • 水平对齐
      • 缩进
      • 制表符
      • 段落间距
      • 行距
      • 分页
    • 字体格式
  • 使用分区
  • 使用页眉和页脚
  • 表格
  • 样式
  • 其他
  • 长度单位
  • 参考文献

简介

生成合同、报告等信息需要用到Word,

python-docx是一款用于创建和更新Microsoft Word (.docx)文件的库

python-docx-template是一款结合python-docxjinja2的库,将Word模板文件和jinja标记结合使用,便于生成更多文档。

使用场景
创建文档 python-docx
修改文档 python-docx-template

安装

1
pip install python-docx

本文版本

1
2
python-docx 0.8.10
python-pptx 0.6.18

初试

test.jpg
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from docx import Document
from docx.shared import Inches

document = Document()

document.add_heading('Document Title', level=0)  # 插入标题

paragraph = document.add_paragraph('A plain paragraph having some ')  # 插入段落
paragraph.add_run('bold').bold = True  # 正文
paragraph.add_run(' and some ')
paragraph.add_run('italic.').italic = True

document.add_heading('Heading, level 1', level=1)  # 插入标题 1
document.add_paragraph('Intense quote', style='Intense Quote')  # 插入段落,明显引用
document.add_paragraph('first item in unordered list', style='List Bullet')  # 插入段落,无序列表
document.add_paragraph('first item in ordered list', style='List Number')  # 插入段落,有序列表

document.add_picture('test.jpg', width=Inches(1.25))  # 插入图片

records = (
    (3, '101', 'Spam'),
    (7, '422', 'Eggs'),
    (4, '631', 'Spam, spam, eggs, and spam')
)

table = document.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)
    row_cells[1].text = id
    row_cells[2].text = desc

document.add_page_break()  # 插入分页

document.save('test.docx')  # 保存

效果
在这里插入图片描述

基本概念

主要对象

  • Document:Word文档对象
  • Paragraph:段落,一个回车一个段落
  • Run:节段,一个段落多个节段

在这里插入图片描述

快速上手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
from docx import Document
from docx.shared import Cm

'''新建文档'''
document = Document()

'''插入段落'''
paragraph = document.add_paragraph('段落1')
prior_paragraph = paragraph.insert_paragraph_before('段落0')  # 前插

'''插入标题'''
document.add_heading('The REAL meaning of the universe')  # 默认为标题 1
document.add_heading('The role of dolphins', level=2)

'''插入分页符'''
document.add_page_break()

'''插入表格'''
table = document.add_table(rows=2, cols=2)  # 2行2列的表格
cell = table.cell(0, 0)  # 第1行第1列的单元格
cell.text = '姓名'
cell = table.cell(0, 1)  # 第1行第2列的单元格
cell.text = '学号'
row = table.rows[1]  # 第2行
row.cells[0].text = '甲'
row.cells[1].text = '2015012755'
row = table.add_row()  # 插入一行
row = table.rows[2]  # 第3行
row.cells[0].text = '乙'
row.cells[1].text = '2015012756'

for row in table.rows:  # 遍历表格
    for cell in row.cells:
        print(cell.text, end=' ')
    print()

table = document.add_table(1, 3)
heading_cells = table.rows[0].cells
heading_cells[0].text = '姓名'
heading_cells[1].text = '语文'
heading_cells[2].text = '数学'
grades = (
    ('甲', 90, 80),
    ('乙', 80, 90),
    ('丙', 100, 100),
)
for name, chinese, math in grades:
    cells = table.add_row().cells
    cells[0].text = name
    cells[1].text = str(chinese)
    cells[2].text = str(math)

table.style = 'LightShading-Accent1'

'''插入图片'''
document.add_picture('test.jpg')
document.add_picture('test.jpg', width=Cm(4.0))  # 宽度为4cm

'''段落样式'''
document.add_paragraph('无序列表', style='ListBullet')  # 无序列表
paragraph = document.add_paragraph('无序列表')
paragraph.style = 'List Bullet'

'''加粗斜体'''
paragraph = document.add_paragraph('正文')
run = paragraph.add_run('加粗')  # 分步
run.bold = True
paragraph.add_run('正文')

paragraph = document.add_paragraph('正文')
paragraph.add_run('加粗').bold = True  # 一步到位
paragraph.add_run('斜体').italic = True

'''字符样式'''
paragraph = document.add_paragraph('正文')
run = paragraph.add_run('强调')  # 分步
run.style = 'Emphasis'

paragraph = document.add_paragraph('正文')
paragraph.add_run('强调', style='Emphasis')  # 一步到位

document.save('test.docx')  # 保存

使用文本

块级与内联文本对象

段落Paragraph是Word中的主要块级对象

块级对象在它所包含的文本的左右边界之间流动,每当文本超出右边界时就添加一行

对于段落来说,边界通常是页边距。若页面是列布局,边界是列边界,如果段落在表格单元格内,边界是单元格边界

表格也是块级对象

内联对象是块级对象内容的一部分。例如,出现在黑体的单词或全大写的句子。最常见的内联对象是run。块容器中的所有内容都在内联对象中。通常,一个段落包含一个或多个run,每个run包含段落的一部分文本

块级对象的属性指定位置,比如段落前后的缩进。

内联对象的属性通常指定内容,比如字体、字体大小、粗体和斜体。

段落属性

段落的格式ParagraphFormat通过Paragraph.paragraph_format获取

水平对齐

在这里插入图片描述
水平对齐枚举 WD_PARAGRAPH_ALIGNMENT

水平对齐
左对齐 LEFT
居中 CENTER
右对齐 RIGHT
两端对齐 JUSTIFY
分散对齐 DISTRIBUTE
1
2
3
4
5
6
7
8
9
10
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

document = Document()
paragraph = document.add_paragraph('居中')
paragraph_format = paragraph.paragraph_format  # 获取段落的格式属性
print(paragraph_format.alignment)  # None
paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 水平对齐设为居中
print(paragraph_format.alignment)  # CENTER (1)
document.save('test.docx')  # 保存

缩进

在这里插入图片描述
缩进是指段落与容器边缘(通常是页边距)之间的水平空间,段落可以在左右两边分别缩进。

第一行缩进比其他部分缩进要大。第一行缩进较少用悬挂缩进。

缩进是由Length指定的,如Inches、Pt、Cm

缩进可使用负值。若使用None则删除现有缩进,并继承上级缩进

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from docx import Document
from docx.shared import Cm

document = Document()
paragraph = document.add_paragraph('缩进')
paragraph_format = paragraph.paragraph_format
print(paragraph_format.left_indent)  # None

paragraph_format.left_indent = Cm(2.0)  # 左缩进设为2厘米
paragraph_format.right_indent = Cm(2.0)  # 右缩进设为2厘米
paragraph_format.first_line_indent = Cm(2.0)  # 首行缩进设为2厘米

print(paragraph_format.left_indent)  # 720090
print(paragraph_format.left_indent.cm)  # 2.00025
document.save('test.docx')  # 保存

制表符

制表符决定后面的文本开始的位置

段落或样式的制表符TabStops通过ParagraphFormat.tab_stops获取

制表符对齐枚举 WD_TAB_ALIGNMENT,默认为左对齐

制表符前导字符枚举 WD_TAB_LEADER,默认为空格

已有的制表符可通过下标访问

1
2
3
4
5
6
7
8
9
10
11
12
13
from docx import Document
from docx.shared import Cm
from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER

document = Document()
paragraph = document.add_paragraph('\t制表符')
paragraph_format = paragraph.paragraph_format
tab_stops = paragraph_format.tab_stops
tab_stop = tab_stops.add_tab_stop(Cm(5.0))  # 插入制表符
print(tab_stop.position)  # 1800225
print(tab_stop.position.cm)  # 5.000625
tab_stop = tab_stops.add_tab_stop(Cm(5.0), alignment=WD_TAB_ALIGNMENT.RIGHT, leader=WD_TAB_LEADER.DOTS)  # 右对齐,前导字符为点
document.save('test.docx')  # 保存

详细阅读

  1. TabStops
  2. TabStop

段落间距

在这里插入图片描述

space_before、space_after分别控制段前、段后间距

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from docx import Document
from docx.shared import Pt

document = Document()
paragraph = document.add_paragraph('段落间距1')
paragraph = document.add_paragraph('段落间距2')
paragraph_format = paragraph.paragraph_format
print(paragraph_format.space_before)  # None
print(paragraph_format.space_after)  # None

paragraph_format.space_before = Pt(18)
paragraph_format.space_after = Pt(12)
print(paragraph_format.space_before.pt)  # 18.0
print(paragraph_format.space_after.pt)  # 12.0

paragraph = document.add_paragraph('段落间距3')
document.save('test.docx')  # 保存

行距

在这里插入图片描述
行距由line_spacing和line_spacing_rule共同控制。

line_spacing取Length或floatNone,默认行距为1.0。

line_spacing_rule取枚举WD_LINE_SPACING或None

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from docx import Document
from docx.shared import Pt

document = Document()
paragraph = document.add_paragraph('行距1')
paragraph_format = paragraph.paragraph_format
print(paragraph_format.line_spacing)  # None
print(paragraph_format.line_spacing_rule)  # None

paragraph_format.line_spacing = Pt(18)
print(paragraph_format.line_spacing.pt)  # 18.0
print(paragraph_format.line_spacing_rule)  # EXACTLY (4)

paragraph = document.add_paragraph('行距2')
paragraph_format.line_spacing = 1.75  # 多倍行距,1.75
print(paragraph_format.line_spacing)  # 1.75
print(paragraph_format.line_spacing_rule)  # MULTIPLE (5)

document.save('test.docx')  # 保存

分页

在这里插入图片描述

分页属性控制段落在页面边界附近的行为

  • keep_together孤行控制。整个段落显示在同一页,如果段落跨两页出现,则在该段之前发出换行符。
  • keep_with_next与下段同页。将一段与下一段保持在同一页。可以保证节标题与节的第一段在同一页上。
  • page_break_before段中不分页。段落在新页的顶部。可以保证章节标题从新的页面开始。
  • widow_control段前分页。将一页分开,以避免将该段的首行或最后一行放在与该段其他部分分开的另一页上。

这四个属性都是三态的,可以取值TrueFalseNone

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from docx import Document

document = Document()
paragraph = document.add_paragraph('分页1' * 400)
paragraph_format = paragraph.paragraph_format
print(paragraph_format.page_break_before)  # None
paragraph_format.keep_together = False  # 孤行控制
paragraph_format.keep_with_next = False  # 与下段同页
paragraph_format.page_break_before = True  # 段中不分页
paragraph_format.widow_control = False  # 段前分页
print(paragraph_format.page_break_before)  # True

paragraph = document.add_paragraph('分页2' * 100)
paragraph_format = paragraph.paragraph_format
paragraph_format.keep_together = False  # 孤行控制
paragraph_format.keep_with_next = False  # 与下段同页
paragraph_format.page_break_before = True  # 段中不分页
paragraph_format.widow_control = False  # 段前分页
document.save('test.docx')  # 保存

字体格式

在这里插入图片描述

字体格式应用在Run层面,包括字体款式、大小、粗体、斜体、下划线

Run对象提供了只读属性font来获取对应的Font对象,用于设置具体的字体格式

字体 属性
all_caps 全部大写字母
bold 加粗
color 颜色,通过RGBColor(r, g, b)赋值
complex_script 将字符视为脚本
cs_bold 脚本字符加粗
cs_italic 脚本字符斜体
double_strike 双删除线
emboss 浮雕
hidden 隐藏
highlight_color 高亮显示的颜色,通过WD_COLOR_INDEX赋值
imprint 压印
italic 斜体
math Open XML Math来处理WML
name 字体名称
no_proof 检查拼写和语法时不报错
outline 轮廓
rtl 从右到左
shadow 阴影
size 大小
small_caps 小写显示为大写,同时字体大小小两点
snap_to_grid
spec_vanish
strike 删除线
subscript 下标
superscript 上标
underline 下划线
web_hidden
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from docx import Document
from docx.shared import Pt
from docx.shared import RGBColor
from docx.enum.text import WD_COLOR_INDEX

document = Document()
paragraph = document.add_paragraph()
run = paragraph.add_run('Hello World!')
font = run.font
font.name = 'Calibri'  # 款式
font.size = Pt(12)  # 大小
font.bold = True  # 加粗
font.italic = True  # 倾斜
font.underline = True  # 下划线
font.color.rgb = RGBColor(255, 0, 0)  # 颜色

paragraph = document.add_paragraph()
run = paragraph.add_run('Hello World!')
font = run.font
font.highlight_color = WD_COLOR_INDEX.YELLOW  # 高亮

document.save('test.docx')  # 保存

使用分区

Word支持Section概念,即具有相同页面布局设置的文档为一个分区。

大多数Word文档只有一个默认的部分,但当需要改变页面布局时,要用到Section

Working with Sections

使用页眉和页脚

Working with Headers and Footers

表格

涉及类有:

  • Table类
  • _Cell类
  • _Row类
  • _Column类
  • _Rows类
  • _Columns类

样式

在这里插入图片描述
在这里插入图片描述
样式名称对应英文的名称,将Word设为英文即可见,设置方法见下文。

标题样式 add_heading('xxx', level=x)

标题 level
标题 0
标题 1 1
标题 2 2
标题 3 3
标题 4 4

段落样式 add_paragraph('xxx', style='xxx')

段落样式 style
正文 None
标题 Title
副标题 Subtitle
无间隔 No Spacing
引用 Quote
明显引用 Intense Quote
列出段落 List Paragraph
无序列表 List Bullet
有序列表 List Number

字符样式 add_run('xxx', style='xxx')

样式 style
正文 None
加粗 add_run('加粗').bold = True
倾斜 add_run('倾斜').italic = True
不明显强调 Subtle Emphasis
强调 Emphasis
明显强调 Intense Emphasis
要点 Strong
不明显参考 Subtle Reference
明显参考 Intense Reference
书籍标题 Book Title

表格样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from docx import Document

document = Document()

'''标题样式'''
document.add_heading('标题', level=0)
document.add_heading('标题 1', level=1)
document.add_heading('标题 2', level=2)
document.add_heading('标题 3', level=3)
document.add_heading('标题 4', level=4)
document.add_heading('标题 5', level=5)
document.add_page_break()

'''段落样式'''
document.add_paragraph('正文', style=None)
document.add_paragraph('标题', style='Title')
document.add_paragraph('副标题', style='Subtitle')
document.add_paragraph('无间隔', style='No Spacing')
document.add_paragraph('引用', style='Quote')
document.add_paragraph('明显引用', style='Intense Quote')
document.add_paragraph('列出段落', style='List Paragraph')
document.add_paragraph('无序列表', style='List Bullet')
document.add_paragraph('有序列表', style='List Number')
document.add_page_break()

'''字符样式'''
paragraph = document.add_paragraph()
paragraph.add_run('正文')
paragraph.add_run('加粗').bold = True
paragraph.add_run('倾斜').italic = True
paragraph.add_run('不明显强调', style='Subtle Emphasis')
paragraph.add_run('强调', style='Emphasis')
paragraph.add_run('明显强调', style='Intense Emphasis')
paragraph.add_run('要点', style='Strong')
paragraph.add_run('不明显参考', style='Subtle Reference')
paragraph.add_run('明显参考', style='Intense Reference')
paragraph.add_run('书籍标题', style='Book Title')
document.save('test.docx')

效果
在这里插入图片描述

详细阅读

  1. 样式大全

其他

1. Word切换为英文界面

文件 → 选项 → 语言 →选中【英语】 → 设为默认值 → 重启Word
在这里插入图片描述
若没有该选项则需要下载 Office 2013 英语语言包

长度单位

均继承Length类

单位 类名 换算
Inches 英寸 2.54cm
Cm 厘米 1cm
Mm 毫米 0.1cm
Pt 点或磅 0.0376cm
Twips 1/20pt,1/567cm

参考文献

  1. python-docx Documentation
  2. Microsoft Word 帮助和学习
  3. add add_chart for docx using chart from python-pptx
  4. Jinja Documentation
  5. Word 神器 python-docx
  6. Python 操纵 word 有什么好用的类库?
  7. Office 2013 各国语言版以及语言包汇总下载
  8. 计算机常用长度单位