0%

python | python-docx

使用 python 写 word。因为,自己打算做 pdf_edit 有一个环节需要写 word ,所以,现在打算总结一下 python-docx 这个库的用法。


官方资料


python-docx


概念


安装

pip install python-docx

使用前,先了解几个概念:

  • Document: 是一个 Word 文档 对象,不同于 VBAWorksheet 的概念,Document 是独立的,打开不同的 Word 文档,就会有不同的 Document 对象,相互之间没有影响
  • Paragraph: 是段落,一个 Word 文档由多个段落组成,当在文档中输入一个回车键,就会成为新的段落,输入 shift + 回车,不会分段
  • Run 表示一个节段,每个段落由多个 节段 组成,一个段落中具有相同样式的连续文本,组成一个节段,所以一个 段落 对象有个 Run 列表

例如有一个 Word,内容是:

则 结构这样划分:

第二个 段落(paragraph),没有内容,所以 节段(run)为空


使用


添加标题

默认情况下添加的标题是最高一级的,即一级标题,通过参数 level 设定,范围是 1 ~ 9,也有 0 级别,表示的是段落标题:

1
2
3
4
5
6
# 添加一级标题
document.add_heading('我是一级标题')

decument.add_heading('我是二级标题', level=2)

decument.add_heading('我是段落标题', level=0)

添加换页

如果一个段落不满一页,需要分页时,可以插入一个分页符,直接调用会将分页符插入到最后一个段落之后:

1
2
3
4
5
6
7
# 文档最后插入分页
document.add_page_break()

# 特定段落分页
from docx.enum.text import WD_BREAK
paragraph = document.add_paragraph("独占一页") # 添加一个段落
paragraph.runs[-1].add_break(WD_BREAK.PAGE) # 在段落的最后一个节段后添加分页

表格操作

Word 文档中经常会用到表格,python-docx 如何添加和操作表格呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 添加一个 2×2 表格
table = document.add_table(rows=2, cols=2)

# 获取第一行第二列单元格
cell = table.cell(0, 1)

# 设置单元格文本
cell.text = '我是单元格文字'

# 表格的行
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!'

# 增加行
row = table.add_row()

更复杂点的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 表格数据
items = (
(7, '1024', '手机'),
(3, '2042', '笔记本'),
(1, '1288', '台式机'),
)

# 添加一个表格
table = document.add_table(1, 3)

# 设置表格标题
heading_cells = table.rows[0].cells
heading_cells[0].text = '数量'
heading_cells[1].text = '编码'
heading_cells[2].text = '描述'

# 将数据填入表格
for item in items:
cells = table.add_row().cells
cells[0].text = str(item[0])
cells[1].text = item[1]
cells[2].text = item[2]

修改表格某一些单元格里面的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 增加表格,这是表格头
table = document.add_table(rows=1, cols=4)
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'name'
hdr_cells[1].text = 'mse'
hdr_cells[2].text = 'psnr'
hdr_cells[3].text = 'ssim'

...

...
table.columns[1].cells[mse_index + 1].paragraphs[0].add_run('nice').font.color.rgb = RGBColor(0, 255, 0)
table.columns[2].cells[psnr_index + 1].paragraphs[0].add_run('nice').font.color.rgb = RGBColor(0, 255, 0)
table.columns[3].cells[ssim_index + 1].paragraphs[0].add_run('nice').font.color.rgb = RGBColor(0, 255, 0)
  • columns 为列
  • rows 是行

table.columns[1].cells[mse_index + 1].paragraphs[0].add_run('nice').font.color.rgb = RGBColor(0, 255, 0)

1 列的 第 mes_index + 1 个单元格,追加一个绿色的 nice.

添加图片

添加图片,即,为 Word 里 菜单中 插入 > 图片 插入的功能,插入图片为原始大小:

1
document.add_picture('image-filename.png')

插入时设置图片大小:

1
2
3
from docx.shared import Cm
# 设置图片的跨度为 10 厘米
document.add_picture('image-filename.png', width=Cm(10))

除了厘米,python-docx 还提供了 英寸(Inches),如设置 1英寸: Inches(1.0)

将图片插入一行

可以和表格配合使用

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
# 增加表格,这是表格头
table = document.add_table(rows=1, cols=8)
hdr_cells = table.rows[0].cells
# hdr_cells[0].text = 'gujia'
hdr_cells[0].text = 'pix'
hdr_cells[1].text = 'cycle'
hdr_cells[2].text = 'fet'
hdr_cells[3].text = 'zi'
hdr_cells[4].text = 'pix1'
hdr_cells[5].text = 'pix2'
hdr_cells[6].text = 'ours'
hdr_cells[7].text = 'target'

row_cells = table.add_row().cells
# cell0 = row_cells[0].paragraphs[0].add_run()
# cell0.add_picture(gujia_img, width=Inches(0.8))
cell1 = row_cells[0].paragraphs[0].add_run()
cell1.add_picture(pix_img, width=Inches(0.8))
cell2 = row_cells[1].paragraphs[0].add_run()
cell2.add_picture(cycle_img, width=Inches(0.8))
cell2 = row_cells[2].paragraphs[0].add_run()
cell2.add_picture(fet_img, width=Inches(0.8))
cell3 = row_cells[3].paragraphs[0].add_run()
cell3.add_picture(zi_img, width=Inches(0.8))
cell4 = row_cells[4].paragraphs[0].add_run()
cell4.add_picture(pix1_img, width=Inches(0.8))
cell5 = row_cells[5].paragraphs[0].add_run()
cell5.add_picture(pix2_img, width=Inches(0.8))
cell6 = row_cells[6].paragraphs[0].add_run()
cell6.add_picture(ours_img, width=Inches(0.8))
cell7 = row_cells[7].paragraphs[0].add_run()
cell7.add_picture(target_img, width=Inches(0.8))

样式

样式可以针对整体文档(document)、段落(paragraph)、节段(run),月具体,样式优先级越高

在设置粗体和斜体之前,我们先简单了解一下 段落 里的运行机制。段落包含很多块级的格式,比如缩进、行高、制表符等。每一个小片段叫做一个 run ,可以对 run 设置粗体和斜体等属性。
我们可以设置如下:

1
2
3
4
5
6
paragraph = document.add_paragraph()
paragraph.add_run('这是一个带有')
paragraph.add_run('粗体').bold = True
paragraph.add_run('和')
paragraph.add_run('斜体').italic = True
paragraph.add_run('的段落。')

设置字体属性

run 设置字体、大小、颜色下划线等,更多属性请移步 Font ,如下:

from docx.shared import RGBColor,Pt
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
#all_caps       =>  全部大写字母
#bold => 加粗
#color => 字体颜色
#complex_script => 是否为“复杂代码”
#cs_bold => “复杂代码”加粗
#cs_italic => “复杂代码”斜体
#double_strike => 双删除线
#emboss => 文本以凸出页面的方式出现
#hidden => 隐藏
#imprint => 印记
#italic => 斜体
#name => 字体
#no_proof => 不验证语法错误
#outline => 显示字符的轮廓
#shadow => 阴影
#small_caps => 小型大写字母
#snap_to_grid => 定义文档网格时对齐网络
#strike => 删除线
#subscript => 下标
#superscript => 上标
#underline => 下划线

paragraph = document.add_paragraph()
paragraph.add_run('这是一个带有')
paragraph.add_run('颜色').font.color.rgb = RGBColor(54, 95, 145)
paragraph.add_run('的')
paragraph.add_run('大字').font.size = Pt(36) # 字体大小设置,和word里面的字号相对应

设置字符样式

除了设置段落样式外,还可以设置一组字符样式,比如字体、大小、颜色、粗体、斜体等,如下:

自定义样式 Emphasis

1
2
3
4
5
6
7
8
paragraph = document.add_paragraph('这是一个带有')
paragraph.add_run('自定义样式', 'Emphasis')
paragraph.add_run('的段落')

paragraph = document.add_paragraph('这是一个带有 ')
run = paragraph.add_run('自定义样式')
run.style = 'Emphasis'
paragraph.add_run('的段落')

段落样式

段落样式包括:对齐、列表样式、行间距、缩进、背景色等,可以在添加段落时设定,也可以在添加之后设置:

1
2
3
4
5
6
# 添加一个段落,设置为无序列表样式
document.add_paragraph('我是个无序列表段落', style='List Bullet')

# 添加段落后,通过 style 属性设置样式
paragraph = document.add_paragraph('我也是个无序列表段落')
paragraph.style = 'List Bullet'

文字样式

在前面 python-docx 文档结构图可以看到,段落中,不同样式的内容,被划分成多个 节段(Run),文字样式是通过 节段(Run)来设置的

1
2
3
4
5
6
7
8
9
# 设置加粗/斜体
paragraph = document.add_paragraph('添加一个段落')
# 设置 节段文字为加粗
run = paragraph.add_run('添加一个节段')
run.bold = True

# 设置 节段文字为斜体
run = paragraph.add_run('我是斜体的')
run.italic = True

设置字体

设置字体稍微复杂些,例如设置一段文字为 宋体:

1
2
3
4
paragraph = document.add_paragraph('我的字体是 宋体')
run = paragraph.runs[0]
run.font.name = '宋体'
run._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
请我喝杯咖啡吧~