Python自动化办公:word文件操作教程

d07db2be141d3ef42cf73d3ae2bade5a.gif

在后台回复【阅读书籍】

即可获取python相关电子书~

Hi,我是山月。

之前给大家完整的介绍了用python操作excel的几个库:xlrd、xlwt、openpyxl。

山月也已经整理好了,还没有学习的伙伴们在后台回复【自动化办公】即可获取合集哦~

今天来给大家介绍一下python操作word的一个常用库:python-docx

安装:pip install python-docx

参考自官网:https://python-docx.readthedocs.io/en/latest/

01

基础介绍

1、打开/保存文档

python-docx可以打开一个新的文档,也可以打开一个已有的文档并对它进行修改。

新建文档:

from docx import Document
document = Document()  # 创建一个Document对象,同时也会创建一个空白文档
document.save('实例.docx') # 保存文档

打开已有文档:

document = Document('数据.docx') # 打开名为数据的word文档
document.save('实例.docx') # 保存文档

2、添加段落

在文档末尾添加新段落:

paragraph = document.add_paragraph('我要学Python!')

也可以把一个段落作为 "光标",在其正上方插入一个新段落:

prior_paragraph = paragraph.insert_paragraph_before('我是山月')

这样就可以在文档中间插入段落了。

3、添加标题

添加方法如下:

document.add_heading('标题')

默认情况下,会添加一个顶级标题,在 Word 中显示为“标题 1”。当你想要一个小节的标题时,只需将你想要的级别指定为 1 到 9 之间的整数:

document.add_heading('标题2', level=2)

如果指定级别为0,则会添加一个【标题】段落。

4、添加分页符

方法如下:

document.add_page_break()

5、添加表格

创建表格:

table = document.add_table(rows=2, cols=2)

通过行和列的索引(从零开始)来确定单元格:

cell = table.cell(0, 1)

往单元格里写入数据:

cell.text = '单元格'

如果想直接访问一行/一列的单元格的话,可以通过表的 .rows /.columns 属性来实现,每行/列都有一个 .cells 属性。

行/列上的 .cells 属性是可迭代的,我们可以通过索引来访问,也能直接通过for 循环来使用:

# 通过表的.rows属性获取第一行,通过行的.cells属性获取单元格
row = table.rows[0]
row.cells[0].text = '1'
row.cells[1].text = '2'

# 利用循环获取所有单元格数据
for row in table.rows:
    for cell in row.cells:
        print(cell.text)

使用 len()来计算表中的行数或列数:

row_count = len(table.rows)
col_count = len(table.columns)

在表的下方插入一行:

row = table.add_row()

设计表格样式:

table.style = 'Light Shading Accent 1'

可设置的表格样式名称:

f594aa5e6c09e9a39d83dda2d4709eaf.png

对应的word中的表格样式:

5ffe36a39a1dae69a4227a34edc4d6fa.png

6、添加图片

Word可以使用【插入】-【图片】菜单项将图像插入到文档中。以下是在 python-docx 中的操作方法:

document.add_picture('图片.png')

添加的图像默认以原始大小显示,但是可以通过指定宽度或高度来改变其大小,单位可以选择英寸inches 或厘米 centimeters:

from docx.shared import Inches
document.add_picture('image-filename.png', width=Inches(1.0))

如果只指定了宽度或高度的一个,python-docx 会自动计算另一个的正确缩放值。这样就可以保留纵横比,让图片不会被拉伸。

7、设置段落样式

可以在创建一个段落时设置一个段落样式:

document.add_paragraph('段落', style='List Bullet')

这两行相当于上面的那一行:

paragraph = document.add_paragraph('段落')
paragraph.style = 'List Bullet'

可设置的段落样式名称:

9c924a3840abeb3cfcf43b614593f7a5.png

8、设置粗体和斜体

段落包含了所有块级格式,如缩进、行高、制表符等。但字符级的格式化如粗体和斜体,是在运行(run)级别应用的。

一个段落中的所有内容都必须在一个运行中,但也可以有多个运行。

比如,一个中间有一个粗体字的段落需要三个运行:一个正常的运行;一个包含该字的粗体运行;另一个正常的运行用于粗体字后面的文字。

当通过.add_paragraph()方法添加一个段落时,它会另外运行一个段落。而使用段落上的.add_run()方法可以直接在运行中的段落后面添加内容:

paragraph = document.add_paragraph('我是另外一个段落')
paragraph.add_run('这是直接在后面新增的内容')

run对象的.bold和.italic属性,可以用来设置加粗或斜体:

paragraph = document.add_paragraph('段落')
run = paragraph.add_run('加粗')
run.bold = True
paragraph.add_run('段落')

如果之后不需要对“运行”引用的话,可以直接在.add_run()的结果上设置粗体或斜体:

paragraph.add_run('加粗').bold = True

如果要从运行中建立段落的话,可以不用向.add_paragraph()提供文本:

paragraph = document.add_paragraph()
paragraph.add_run('段落')
paragraph.add_run('加粗').bold = True
paragraph.add_run('段落')

9、设置字符样式

除了设置段落级别的段落样式之外,Word还可以设置运行级别的字符样式。字符样式可以理解为字体,包括其字体、大小、颜色、粗体、斜体等。

可设置的字符样式名称:

351ff38191f3351629f5b1beb43fe094.png

可以在添加新运行的时候设置字符样式:

paragraph = document.add_paragraph('这是正常的文字,')
paragraph.add_run('这是emphasis格式文字', 'Emphasis')

也可以在创建运行后将样式应用到运行:

paragraph = document.add_paragraph('这是正常的文字,')
run = paragraph.add_run('这是emphasis格式文字')
run.style = 'Emphasis'

10、实例

下面我们来看一个具体的实例巩固一下上面的知识:

from docx import Document
from docx.shared import Inches

document = Document() # 创建一个Document对象,同时也会创建一个空白文档

# 添加段落和标题
document.add_heading('标题', 0)
p = document.add_paragraph('一个段落里可以有')
p.add_run('粗体').bold = True
p.add_run('和')
p.add_run('斜体').italic = True
document.add_heading('标题1', level=1)
document.add_paragraph('设置Intense quote段落样式', style='Intense Quote')
document.add_paragraph('设置成项目符号中的第一项的段落样式', style='List Bullet')
document.add_paragraph('设置成编号里的第一项的段落样式', style='List Number')

# 添加图片
document.add_picture('白敬亭.png', width=Inches(1.25))

# 表格数据
records = (
    (1, '山月', '学Python'),
    (2, '小红', '唱歌'),
    (3, '小兰', '跳舞')
)

# 添加表格
table = document.add_table(rows=1, cols=3)
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '编号'
hdr_cells[1].text = '姓名'
hdr_cells[2].text = '爱好'
for number, name, hobby in records:
    row_cells = table.add_row().cells
    row_cells[0].text = str(number)
    row_cells[1].text = name
    row_cells[2].text = hobby

table.style = 'Light Shading Accent 1'    # 设置表格样式
document.add_page_break() # 添加换页符
document.save('实例.docx') #保存文件

效果:

e2f3d9fab49b33928344ffecf7e64994.png

02

段落属性

段落有多种属性,可以用来设置在页面中的位置以及将其内容划分为单独行的方式。

一般来说,最好定义一个段落样式,将这些属性收集到一个组中,并将适当的样式应用于每个段落,而不是重复地将这些属性直接应用于每个段落。

这类似于级联样式表 (CSS) 如何与 HTML 一起工作。此处描述的所有段落属性都可以使用样式设置,也可以直接应用于段落。

段落的格式属性是通过使用段落的paragraph_format属性获得的ParagraphFormat对象来访问的。

1、对齐

可以使用WD_PARAGRAPH_ALIGNMENT 中的选项将段落的水平对齐方式设置为左对齐、居中对齐、右对齐或两端对齐 :

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
document = Document()
paragraph = document.add_paragraph()

paragraph_format = paragraph.paragraph_format
print(paragraph_format.alignment)   # --> None:表示对齐方式是从样式层次中继承的

paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
print(paragraph_format.alignment)   # --> CENTER (1)

WD_PARAGRAPH_ALIGNMENT的选项:

e201737372b677e0d494530a4512435a.png

2、缩进

缩进是指段落与页边之间的水平空间,一个段落可以在左边和右边分别缩进。

其中第一行可以与段落的其他部分有不同的缩进:首行缩进 first line indent(第一行缩进而其他行不缩进)、悬挂缩进hanging indent(段落的第一行不缩进但段落的其他行缩进)。

缩进是用一个长度(Length)值来指定的,常见长度(Length)值及其单位转换:

0b61e58f747d21d0295f544c80992cc3.png

如果缩进是负值,会使段落与页边距重叠。

None的值表示缩进值是从样式层次结构中继承的。将None指定给一个缩进属性,可以删除任何直接应用的缩进设置,并恢复从样式层次结构的继承性。

from docx import Document
from docx.shared import Inches
document = Document()

paragraph = document.add_paragraph()
paragraph_format = paragraph.paragraph_format

print(paragraph_format.left_indent)    # --> None  指示缩进是从样式层次结构继承的

paragraph_format.left_indent = Inches(0.5)
print(paragraph_format.left_indent)    # --> 457200
print(paragraph_format.left_indent.inches) # --> 0.5

右侧缩进的方法一样:

from docx import Document
from docx.shared import Pt
document = Document()

paragraph = document.add_paragraph()
paragraph_format = paragraph.paragraph_format

print(paragraph_format.right_indent) # --> None

paragraph_format.right_indent = Pt(24)
print(paragraph_format.right_indent) # --> 304800
print(paragraph_format.right_indent.pt) # --> 24.0

首行的缩进使用 first_line_indent 属性指定,如果值为正值表示首行缩进,负值则表示悬挂缩进:

from docx import Document
from docx.shared import Inches
document = Document()
paragraph_format = paragraph.paragraph_format

print(paragraph_format.first_line_indent)    # --> None 

paragraph_format.first_line_indent = Inches(-0.25)
print(paragraph_format.first_line_indent)       # --> -228600
print(paragraph_format.first_line_indent.inches)       # --> -0.25

3、制表位

制表位是指在水平标尺上的位置,可以用来设置文字缩进的距离或一栏文字开始之处。

制表位的三要素包括制表位位置、制表位对齐方式和制表位的前导字符。

段落或样式的制表位可以用paragraph_format对象的 tab_stops 属性访问:

paragraph_format = paragraph.paragraph_format
tab_stops = paragraph_format.tab_stops
print(tab_stops) # -->>  <docx.text.tabstops.TabStops object at 0x0000018B95E35948>

可以使用 add_tab_stop() 方法添加一个新的制表位:

paragraph_format = paragraph.paragraph_format
tab_stops = paragraph_format.tab_stops

tab_stop = tab_stops.add_tab_stop(Inches(1.5))
print(tab_stop.position)   # -->>  1371600
print(tab_stop.position.inches)   # -->>  1.5

制表位的对齐默认为左对齐,但可以通过 WD_TAB_ALIGNMENT 的选项来设置。前导字符默认为空格,可以通过 WD_TAB_LEADER的选项来设置:

from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_TAB_ALIGNMENT, WD_TAB_LEADER
document = Document()
paragraph = document.add_paragraph()
paragraph_format = paragraph.paragraph_format
tab_stops = paragraph_format.tab_stops
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)
document.save('实例.docx') #保存文件

WD_TAB_ALIGNMENT的选项:

6276712c1c2fd2789d9cc2f6c7f7bfe8.png

WD_TAB_LEADER的选项:

cf5eb730aa77b60f674ee4bf552d5faa.png

可以使用序列TabStops 上的索引访问现有的制表位:

tab_stops[0]   # -->  <docx.text.tabstops.TabStop object at 0x000002005C935B48>

4、段落间距 

可以通过space_before属性来控制段落前的间距,通过space_after 属性来控制段落后的间距。

在页面排版过程中,段落间的间距是被折叠的,这意味着两个段落之间的间距是第一段的断后距和第二段的断前距的最大值。

段落间距设置为长度值,通常使用 Pt(磅):

from docx import Document
from docx.shared import Pt
document = Document()

paragraph = document.add_paragraph()
paragraph_format = paragraph.paragraph_format

print(paragraph_format.space_before, paragraph_format.space_after)  # -->>  None None

paragraph_format.space_before = Pt(18)
print(paragraph_format.space_before.pt)  # -->>  18.0

paragraph_format.space_after = Pt(12)
print(paragraph_format.space_after.pt)  # -->>  12.0

5、行间距

行间距是段落中每行之间的距离,行距可以指定为绝对距离或相对于行高(本质上是所用字体的磅值)。

典型的绝对距离是18磅,典型的相对行高是2倍行距(2.0行高),默认的行距是单倍行距(1.0行高)。

行间距由 line_spacing 和 line_spacing_rule 属性的交互控制。

  • line_spacing 可以是长度值、(小)浮点数或无:长度值表示绝对距离;浮点数表示行高数;None 表示行距是继承的。

  • line_spacing_rule 是 WD_LINE_SPACING的选项或None。

from docx import Document
from docx.shared import Length
from docx.shared import Pt
document = Document()

paragraph = document.add_paragraph()
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(isinstance(paragraph_format.line_spacing, Length))    # >>> True
print(paragraph_format.line_spacing.pt)    # >>> 18.0
print(paragraph_format.line_spacing_rule)    # >>> EXACTLY (4)

paragraph_format.line_spacing = 1.75
print(paragraph_format.line_spacing)    # >>> 1.75
print(paragraph_format.line_spacing_rule)    # >>> MULTIPLE (5)

WD_LINE_SPACING的选项:

3a2dd977917b823e19b1da0d5b2128b6.png

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 表示属性值是从样式层次结构继承的;True 表示该属性“开启”;False 表示该属性“关闭”。

print(paragraph_format.keep_together)    # >>> None

paragraph_format.keep_with_next = True
print(paragraph_format.keep_with_next)    # >>> True

paragraph_format.page_break_before = False
print(paragraph_format.page_break_before)    # >>> False

03

设置字符格式

字符格式应用于运行级别,字符格式包括字体和大小、粗体、斜体和下划线。

可以像这样访问运行的字体:

from docx import Document
document = Document()
run = document.add_paragraph().add_run()
font = run.font

字符、段落和表格样式也可以指定字符格式,以应用于具有该样式的内容。比如可以像这样访问样式的字体:

from docx import Document
document = Document()
style = document.styles['Normal']
font = style.font

字体和大小设置:

from docx.shared import Pt
font.name = 'Calibri'
font.size = Pt(12)

字体的许多属性(如粗体、斜体、全大写、删除线、上标)也是三态的,可以采用值 True、False 和 None。

font.bold, font.italic # >>> None None

font.italic = True
font.italic  # >>> True

font.italic = False
font.italic # >>> False

font.italic = None
font.italic # >>> None

1、下划线

下划线是一种特殊的情况。它是三态属性和枚举值属性的混合体。 

True 表示单下划线,是最常见的, False 表示没有下划线。如果不需要下划线的话一般设置 None。

其他形式的下划线,例如双线或虚线,是使用 WD_UNDERLINE的选项指定的:

font.underlinec # >>> None

font.underline = True
 font.underline = WD_UNDERLINE.DOT_DASH

WD_UNDERLINE的选项:

92d2687c7a5ea25f3d1a7b6a91c98d1e.png

2、字体颜色

每个 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

MSO_THEME_COLOR_INDEX选项:

bd3ba288be07e0ebe2c85ed2ec24fe21.png

通过将 None 分配给 ColorFormat 的 rgb 或 theme_color 属性,可以将字体的颜色恢复为其默认(继承)值:

font.color.rgb = None

确定字体的颜色首先要确定其颜色类型:

font.color.type

type 属性的值可以是 MSO_COLOR_TYPE 的选项或 None。

  • MSO_COLOR_TYPE.RGB 表示它是 RGB 颜色。

  • MSO_COLOR_TYPE.THEME 表示主题颜色。

  • MSO_COLOR_TYPE.AUTO 表示其值由应用程序自动确定,通常设置为黑色。

  • None 表示不应用颜色,颜色继承自样式层次;这是最常见的情况。

04

设置节

Word 支持节的概念,即具有相同页面布局设置(如页边距和页面方向)的文档的一个分区。

这就是为什么一个文档可以包含一些纵向布局的页面的同时包含其他横向布局的页面。

大多数 Word 文档默认只有一个节,而且大多数文档没有理由更改默认边距或其他页面布局。但是想更改页面布局时,需要了解节才能完成它。

1、访问节

Document 对象上的sections 属性提供对文档节的访问:

from docx import Document

document = Document()
sections = document.sections

print(sections) # >>>  <docx.section.Sections object at 0x0000019D404702E8>
print(len(sections)) # >>>1

section = sections[0]
print(section) # >>>  <docx.section.Section object at 0x0000019D4042D208>

for section in sections:
    print(section.start_type)   # >>>  NEW_PAGE (2)

2、添加新节

Document.add_section() 方法可以在文档末尾开始一个新节。调用此方法后添加的段落和表格将出现在新的节中:

from docx import Document
from docx.enum.section import WD_SECTION

document = Document()

current_section = document.sections[-1]  # 文档的最后一节
print(current_section.start_type)# >>> NEW_PAGE (2)

new_section = document.add_section(WD_SECTION.ODD_PAGE)
print(new_section.start_type) # >>> ODD_PAGE (4)

3、节属性

Section 对象有 11 个属性,可以查找和设置页面布局。

1)节开始类型

Section.start_type 描述了节的起始位置:

from docx import Document
from docx.enum.section import WD_SECTION

document = Document()
section = document.sections[-1]
print(section.start_type)   #>>> NEW_PAGE (2)
section.start_type = WD_SECTION.ODD_PAGE
print(section.start_type)   #>>> ODD_PAGE (4)

start_type 的值是 WD_SECTION_START 中的选项:

b2cf2a7eca8700751dadd6a4de7fd23c.png

2)页面尺寸和方向

Section 上有三个属性可以设置页面的尺寸和方向,三个可以一起使用,例如,将节的方向从纵向更改为横向:

from docx import Document
from docx.enum.section import WD_ORIENT

document = Document()
section = document.sections[-1]

print(section.orientation, section.page_width, section.page_height)    #-->> PORTRAIT (0) 7772400 10058400

new_width, new_height = section.page_height, section.page_width
section.orientation = WD_ORIENT.LANDSCAPE
section.page_width = new_width
section.page_height = new_height

print(section.orientation, section.page_width, section.page_height) #-->> LANDSCAPE (1) 10058400 7772400

3)页边距

Section上有七个属性可以设置文本在页面上出现位置的各种边缘间距。

from docx import Document
from docx.enum.section import WD_ORIENT
from docx.shared import Inches

document = Document()
section = document.sections[-1]

print(section.left_margin, section.right_margin)  #--> 1143000 1143000
print(section.top_margin, section.bottom_margin)  #--> 914400 914400  
print(section.gutter)  #--> 0
print(section.header_distance, section.footer_distance)  #--> 457200 457200 

section.left_margin = Inches(1.5)
section.right_margin = Inches(1)
print(section.left_margin, section.right_margin)  #--> 1371600 914400

05

设置页眉和页脚

Word 支持页眉header和页脚footer。

页眉是出现在每页上边距区域的文本,与文本主体分开,通常传达上下文信息,例如文档标题、作者、创建日期或页码。

文档中的页眉在不同的页面之间是相同的,只有很小的内容差异,例如节标题或页码的变化。页眉也称为运行头。

页脚在各方面都类似于页眉,只是它出现在页面底部。

1、访问节的页眉/页脚

页眉header 和页脚footer是链接到节的,这就允许每个节可以有不同的页眉和/页脚。例如,横向部分的页眉可能比纵向部分更宽。

每个节对象都有一个 .header/.footer 属性,提供对该部分的 _Header /_Footer对象的访问:

from docx import Document
document = Document()
section = document.sections[0]

header = section.header
print(header) #-->  <docx.section._Header object at 0x00000204FF91FD68>

footer = section.footer
print(footer) #-->  <docx.section._Footer object at 0x0000024021180438>

_Header /_Footer对象始终存在于 section.header/ section.footer上,即使没有为该节定义页眉/页脚。

_Header.is_linked_to_previous / _Footer.is_linked_to_previous表示存在实际的页眉/页脚定义:

print(header.is_linked_to_previous) #-->True
print(footer.is_linked_to_previous) #-->True

新文档没有页眉/页脚(在它包含的单个节上),因此 .is_linked_to_previous 在这种情况下为 True。

2、添加页眉/页脚

只需编辑 _Header  / _Footer 对象的内容,就可以将页眉/页脚添加到新文档中。

_Header  / _Footer 对象的内容和Document 对象一样可以进行编辑。请注意,与新文档一样,新页眉/页脚已经包含一个(空)段落:

from docx import Document

document = Document()
section = document.sections[0]

header = section.header
paragraph = header.paragraphs[0]
paragraph.text = "页眉内容"

footer = section.footer
paragraph = footer.paragraphs[0]
paragraph.text = "页脚内容"

document.save('实例.docx') #保存文件

效果:

65701db55c70359d9098766c19a2f465.png

另外注意,添加内容(甚至只是访问 header.paragraphs/footer.paragraphs)的行为添加了页眉/页脚定义并更改了 .is_linked_to_previous 的状态:

print(header.is_linked_to_previous)   # >>> False
print(footer.is_linked_to_previous)   # >>> False

3、添加分区页眉/页脚内容

一个具有多个区域的页眉通常是通过精心放置的制表符来完成的。居中和右对齐的 区域所需的制表符是Word中页眉和页脚样式的一部分。

插入的制表符 ("\t") 用于分隔左对齐、居中和右对齐的页眉/页脚内容:

from docx import Document

document = Document()
section = document.sections[0]
header = section.header

paragraph = header.paragraphs[0]
paragraph.text = "居左页眉\t居中页眉\t居右页眉"
paragraph.style = document.styles["Header"] # 可省略


footer = section.footer
paragraph = footer.paragraphs[0]
paragraph.text = "居左页脚\t居中页脚\t居右页脚"
paragraph.style = document.styles["Footer"] # 可省略

document.save('实例.docx') # 保存文件

效果:

6e971b4474c8a079d532808afe1a3512.png

4、删除页眉/页脚

可以通过将 True 分配给其 .is_linked_to_previous 属性来删除不需要的页眉/页脚 :

header.is_linked_to_previous = True
footer.is_linked_to_previous = True

5、添加页眉/页脚定义

通过将 False 分配给其 .is_linked_to_previous 属性,可以为缺少的部分提供显式页眉/页脚定义:

print(header.is_linked_to_previous) # >>> True
header.is_linked_to_previous = False
print(header.is_linked_to_previous)# >>> False

print(footer.is_linked_to_previous) # >>> True
footer.is_linked_to_previous = False
print(footer.is_linked_to_previous)# >>> False

新添加的页眉/页脚定义包含一个空段落。

注意:

  • 在已经具有页眉定义的页眉上将 False 分配给 .is_linked_to_previous 不会执行任何操作。

  • 如果第2节的页眉继承自第1节,那编辑第2节的页眉时,实际上是改变了第1节页眉的内容。除非你首先明确地为第2节的.is_linked_to_previous属性赋值为False,否则不会为第2节添加一个新的页眉定义。

06

样式

Word 中的样式是一组可以一次性应用于文档元素的规范。 Word 具有段落样式、字符样式、表格样式和编号定义。它们分别应用于段落、文本、表格和列表。

1、标识属性

样式具有三个标识属性,名称name、style_id 和类型 type。

  1. 每个样式的名称属性是固定的、唯一的标识符,用于访问目的。

  2. 样式的 style_id 在内部用于将内容对象(例如段落)设置为其样式的键。然而,这个值是由 Word 自动生成的,不能保证在保存过程中保持稳定。通常,样式 id 只需从本地化样式名称中删除空格即可形成,但也有例外。 python-docx 的用户通常应该避免使用样式 id,除非他们对所涉及的内部结构有信心。

  3. 样式的类型是在创建时设置的,不能更改。

2、样式类型

1)内置样式 built-in style

Word中内置的276种预设样式之一,如 "Heading 1"。

样式定义存储在 .docx 包的 styles.xml 部分中,但内置样式定义存储在 Word 应用程序本身中,并且在实际使用之前不会写入 styles.xml。

一个内置的样式可以是定义的或潜在的。一个尚未定义的内置样式被称为潜在样式。

定义的和潜在的内置样式都可以作为选项出现在Word的样式面板和样式库中。

2)自定义样式 custom style

也称为用户定义样式,在 Word 文档中定义的任何非内置样式的样式。请注意,自定义样式不能是潜在样式。

3)潜在样式 latent style

文档中没有定义的内置样式在该文档中称为潜在样式。

根据文档的 LatentStyles 对象中的设置,潜在样式可以作为选项出现在 Word 用户界面中。

潜在样式定义基本上是一个存根样式定义,除了样式名称外,它最多具有五个行为属性,通过为每个行为属性定义默认值可以节省额外的空间。

因此,只有那些与默认值不同的样式需要被定义,而符合所有默认值的样式则不需要潜伏样式定义。

4)推荐样式列表 recommended style list

当从 "列表:"下拉框中选择 "推荐 "时,出现在样式工具箱或面板中的一个样式列表。

5)样式库 Style Gallery

出现在Word用户界面功能区的示例样式的选择,可以通过点击其中的一个来应用。

6)行为属性

样式的属性分为两类,行为属性和格式属性。其中行为属性控制样式出现在Word用户界面中的时间和位置。

样式有五个行为属性:

  • 隐藏 hidden

  • 使用时不隐藏 unhide_when_used

  • 优先级 priority

  • 快速样式 quick_style

  • 锁定 locked

除priority 属性采用整数值外,其他四个样式行为属性是三态的,可以取值 True(打开)、False(关闭)或 None(继承)。

这五个行为属性会影响样式列表和样式库中样式。

  • 如果一个样式的 hidden 属性为 False(默认值),它就会出现在推荐列表中。

  • 如果样式未隐藏且其 quick_style 属性为 True,则它也会出现在样式库中。

  • 如果隐藏样式的 unhide_when_used 属性为 True,则其隐藏属性在第一次使用时设置为 False。

  • 样式列表和样式库中的样式按优先级 priority 排序,然后按字母顺序排列相同优先级的样式。

  • 如果样式的锁定locked属性为 True 并且为文档打开了格式限制,则该样式将不会出现在任何列表或样式库中,并且不能应用于内容。

比如以下代码将导致“Body Text”段落样式首先出现在样式库中:

from docx import Document
document = Document()
style = document.styles['Body Text']

style.hidden = False
style.quick_style = True
style.priorty = 1

而此代码将从样式库中删除“Normal”段落样式,但允许它保留在推荐列表中:

style = document.styles['Normal']

style.hidden = False
style.quick_style = False

3、访问样式

使用 Document.styles 属性可以访问样式:

document = Document()
styles = document.styles
print(styles) #>>   <docx.styles.styles.Styles object at 0x000001432A6EB8D0>

Styles 对象可以按以名称定义的样式的字典式访问:

print(styles['Normal']) #>>  _ParagraphStyle('Normal') id: 2612711224152

Styles 对象也是可迭代的。通过使用 BaseStyle 上的标识属性,可以生成已定义样式的各种子集。

例如,此代码将生成已定义段落样式的列表:

from docx import Document
from docx.enum.style import WD_STYLE_TYPE

document = Document()
styles = document.styles

paragraph_styles = [s for s in styles if s.type == WD_STYLE_TYPE.PARAGRAPH]

for style in paragraph_styles:
    print(style.name)

4、应用样式

Paragraph、Run 和 Table 对象各有一个样式属性,将样式对象分配给此属性会应用该样式:

from docx import Document
document = Document()

paragraph = document.add_paragraph()
print(paragraph.style)  # _ParagraphStyle('Normal') id: 2493830027136
print(paragraph.style.name) #'Normal'

paragraph.style = document.styles['Heading 1']
print(paragraph.style.name) # 'Heading 1'

也可以直接指定样式名称:

paragraph.style = 'List Bullet'
print(paragraph.style)   #  _ParagraphStyle('List Bullet') id: 1843658186312
print(paragraph.style.name)  #  'List Bullet'

样式也可以在创建时使用样式对象或其名称进行设置:

paragraph = document.add_paragraph(style='Body Text')
print(paragraph.style.name) # 'Body Text'

body_text_style = document.styles['Body Text']
paragraph = document.add_paragraph(style=body_text_style)
print(paragraph.style.name) #'Body Text'

5、添加或删除样式

可以通过指定名称和样式类型将新样式添加到文档中:

from docx import Document
from docx.enum.style import WD_STYLE_TYPE
document = Document()

styles = document.styles
style = styles.add_style('Citation', WD_STYLE_TYPE.PARAGRAPH)
print(style.name)   # 'Citation'
print(style.type)   # PARAGRAPH (1)

使用 base_style 属性来指定新样式应该继承格式设置的样式:

from docx import Document
from docx.enum.style import WD_STYLE_TYPE
document = Document()
styles = document.styles
style = styles.add_style('Citation', WD_STYLE_TYPE.PARAGRAPH)

print(style.base_style) # None
style.base_style = styles['Normal']
print(style.base_style) # _ParagraphStyle('Normal') id: 1539328207336
print(style.base_style.name)    # 'Normal'

调用delete() 方法可从文档中删除样式:

from docx import Document
document = Document()

styles = document.styles

print(len(styles))  # 164
styles['Normal'].delete()
print(len(styles))  # 163

注意:通过Style.delete() 方法从文档中删除样式的定义,不会影响应用该样式的文档中的内容。

文档中未定义样式的内容使用该内容对象的默认样式,例如在段落的情况下为“Normal”。

6、定义段落格式

段落样式和表格样式都允许指定段落格式。这些样式通过其 paragraph_format 属性提供对 ParagraphFormat 对象的访问。

下面是一个示例,说明如何创建具有 1/4 英寸悬挂缩进、上方 12 磅间距和孤行控制的段落样式:

from docx.enum.style import WD_STYLE_TYPE
from docx.shared import Inches, Pt
document = Document()
style = document.styles.add_style('Indent', WD_STYLE_TYPE.PARAGRAPH)
paragraph_format = style.paragraph_format

paragraph_format.left_indent = Inches(0.25)
paragraph_format.first_line_indent = Inches(-0.25)
paragraph_format.space_before = Pt(12)
paragraph_format.widow_control = True

7、使用特定段落的样式属性

段落样式具有 next_paragraph_style 属性,该属性指定在该样式的段落之后插入的新段落的样式。

一般当样式在一个序列中只出现一次时最有用,例如标题。在这种情况下,段落样式可以在完成标题后自动设置回正文样式。

对于正文段落,后续段落应采用与当前段落相同的样式。如果未指定下一个段落样式,则默认通过应用相同的样式。

下面是如何将Heading 1样式的下一段样式更改为正文文本的示例:

from docx import Document
document = Document()
styles = document.styles

styles['Heading 1'].next_paragraph_style = styles['Body Text']

可以通过设置None 或样式本身来恢复默认行为:

from docx import Document
document = Document()
styles = document.styles
styles['Heading 1'].next_paragraph_style = styles['Body Text']

heading_1_style = styles['Heading 1']
print(heading_1_style.next_paragraph_style.name)    #>>>  'Body Text'

heading_1_style.next_paragraph_style = heading_1_style
print(heading_1_style.next_paragraph_style.name)    #>>>  'Heading 1'

heading_1_style.next_paragraph_style = None
print(heading_1_style.next_paragraph_style.name)    #>>>  'Heading 1'

8、使用潜在样式

1)访问文档中的潜在样式

文档中的潜在样式可从样式对象访问:

document = Document()
latent_styles = document.styles.latent_styles

LatentStyles对象支持len()、迭代和按样式名称的字典式访问:

from docx import Document
document = Document()
latent_styles = document.styles.latent_styles

print(len(latent_styles))   # 137

latent_quote = latent_styles['Quote']
print(latent_quote)  # <docx.styles.latent._LatentStyle object at 0x000001F89C8404A8>
print(latent_quote.priority)   # 29

latent_style_names = [ls.name for ls in latent_styles]
print(latent_style_names)

2)更改潜在样式默认值

LatentStyles 对象还提供对当前文档中内置样式的默认行为属性的访问。

这些默认值为_LatentStyle定义的没有定义的属性以及没有明确的潜在样式定义的内置样式的所有行为属性提供值。

print(latent_styles.default_to_locked) #>>>False
latent_styles.default_to_locked = True
print(latent_styles.default_to_locked) #>>> True

3)添加潜在样式定义

可以使用 LatentStyles 上的 add_latent_style() 方法添加新的潜在样式。

此代码为内置样式“List Bullet”添加了一个新的潜在样式,将其设置为出现在样式库中:

from docx import Document
document = Document()
latent_styles = document.styles.latent_styles

latent_style = latent_styles.add_latent_style('List Bullet')
latent_style.hidden = False
latent_style.priority = 2
latent_style.quick_style = True

4)删除潜在样式定义

可以通过调用其 delete() 方法来删除潜在样式定义:

latent_styles['Light Grid'].delete()

好啦,今天的内容就到这。

已经到底啦~(≧▽≦*)/~

d30271059e0d1eb4c8d0749baa9d1857.png 往 期 推 荐 50cdb0af1651d2a74c671cf0d526054a.png

Python自动化办公:openpyxl教程(基础)

2022-01-18

69991325493dcf2b59459c5cdf9f0152.png

如何用Python做日历?

2022-01-10

235041ebb84e2104affa8305231856ac.png

Python实战:个人贷款计算器

2022-01-14

0ddc496f80aa534e83e625914224b288.png

6d7d28d2fc1f82171d3404c5be2b8f63.gif

您的“点赞”、“在看”和 “分享”是我们产出的动力。

  • 30
    点赞
  • 214
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值