【python-docx 06】理解word样式

Word中的样式是什么?

将word文件的后缀名改为.zip解压后就可以在word文件夹中找到一个名为document.xml的xml文件。里面包含了word的结构和所有文本内容。其中style.xml就是样式文件。
在这里插入图片描述

当类似元素的格式一致时,文档会更加直观。为了实现这种一致性,专业文档设计人员开发了一个样式表,用于定义文档元素类型并指定每个元素的格式。

例如,也许主干段落字体设置在9pt Times Roman中,线高11 pt,左齐右齐,右边粗糙。当这些规范应用于文档的每个元素时,实现了一致美观的结构。

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

经验丰富的程序员会将样式识别为间接层。关于这些的好处是它允许你定义一次,然后多次应用该定义。这样可以节省定义相同内容的工作;但更重要的是,它允许您更改定义并将更改反映在您应用它的所有位置。

这就像在做前端的时候,往往把css写在单独的文件中,而不是写在行内。

词汇表

样式定义
文档样式部分中的<w:style>元素,用于显式定义样式的属性。

样式的风格
在文档中明确定义的样式。与潜在样式对比。

内置样式
Word中内置的276种预设样式,例如“标题1”。内置样式可以是定义的,也可以是潜在的。
尚未定义的内置样式称为潜在样式。
定义的和潜在的内置样式都可以在Word的样式面板和样式库中显示为选项。

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

潜在样式
在特定文档中没有定义的内置样式在该文档中被称为潜在样式。潜在样式可以在Word中显示为选项,具体取决于文档的LatentStyles对象中的设置。

推荐的样式
列表从“列表:”下拉框中选择“推荐”时,样式工具箱或面板中显示的样式列表。

样式画廊
选择显示在Word功能区中的示例样式,可以通过单击其中一个来应用。

识别样式

样式有三个标识属性,name,style_id和type。

每个样式的name属性都是其稳定的唯一标识符,用于访问。

样式的style_id在内部用于将内容对象(例如段落)键入其样式。但是,此值由Word自动生成,并且不保证在整个保存期间保持稳定。

通常,样式id仅通过从本地化样式名称中删除空格来形成,但是也有例外。使用python-docx通常应该避免使用样式id,样式的类型在创建时设置,不能更改。

内置样式

Word附带了近300种所谓的内置样式,如Normal,Heading 1和List Bullet。

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

这是一个明智的策略,因为它们占用了相当大的空间,并且在每个.docx文件中基本上都是冗余和无用的开销。

内置样式在使用之前不会写入.docx包这一事实导致需要潜在的样式定义。

风格行为

除了收集一组格式设置属性外,样式还有五个属性指定其行为。此行为相对简单,基本上等于样式在Word或LibreOffice UI中出现的时间和位置。

理解样式行为的关键概念是推荐列表。在Word的样式窗格中,用户可以选择要查看的样式列表。其中一个名为Recommended,被称为推荐列表。所有五个行为属性都会影响此列表和样式库中样式外观的某些方面。
在这里插入图片描述
简而言之,如果样式的隐藏属性为False(默认值),则会在推荐列表中显示样式。如果未隐藏样式且其quick_style属性为True,则它也会显示在样式库中。
如果隐藏样式的unhide_when_used属性为True,则其隐藏属性在第一次使用时设置为False。
样式列表和样式库中的样式按优先级顺序排序,然后按字母顺序排列相同优先级的样式。如果样式的锁定属性为True并且为文档启用了格式设置限制,则样式将不会出现在任何列表或样式库中,也不能应用于内容。

潜在的样式

需要指定未在styles.xml中定义的内置样式,这需要潜在的样式定义。潜在样式除了样式名称之外,最多只有五个行为属性。通过为每个行为属性定义默认值来节省额外的空间,因此只需要定义与默认值不同的那些,并且匹配所有默认值的样式不需要潜在的样式定义。

使用styles.xml中出现的w:latentStyles和w:lsdException元素指定潜在样式定义。

只有内置样式才需要潜在样式定义,因为只有内置样式才能出现在UI中,而style.xml中没有样式定义。

样式继承

样式可以从其他样式继承属性,有点类似于层叠样式表(CSS)的工作方式。
使用base_style属性指定继承。通过将一种样式基于另一种样式,可以形成任意深度的继承层次结构。没有基本样式的样式从文档默认值继承属性。

默认模板中的段落样式
Normal
Body Text
Body Text 2
Body Text 3
Caption
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Heading 7
Heading 8
Heading 9
Intense Quote
List
List 2
List 3
List Bullet
List Bullet 2
List Bullet 3
List Continue
List Continue 2
List Continue 3
List Number
List Number 2
List Number 3
List Paragraph
Macro Text
No Spacing
Quote
Subtitle
TOCHeading
Title
默认模板中的字符样式
Body Text Char
Body Text 2 Char
Body Text 3 Char
Book Title
Default Paragraph Font
Emphasis
Heading 1 Char
Heading 2 Char
Heading 3 Char
Heading 4 Char
Heading 5 Char
Heading 6 Char
Heading 7 Char
Heading 8 Char
Heading 9 Char
Intense Emphasis
Intense Quote Char
Intense Reference
Macro Text Char
Quote Char
Strong
Subtitle Char
Subtle Emphasis
Subtle Reference
Title Char
默认模板中的表格样式
Table Normal
Colorful Grid
Colorful Grid Accent 1
Colorful Grid Accent 2
Colorful Grid Accent 3
Colorful Grid Accent 4
Colorful Grid Accent 5
Colorful Grid Accent 6
Colorful List
Colorful List Accent 1
Colorful List Accent 2
Colorful List Accent 3
Colorful List Accent 4
Colorful List Accent 5
Colorful List Accent 6
Colorful Shading
Colorful Shading Accent 1
Colorful Shading Accent 2
Colorful Shading Accent 3
Colorful Shading Accent 4
Colorful Shading Accent 5
Colorful Shading Accent 6
Dark List
Dark List Accent 1
Dark List Accent 2
Dark List Accent 3
Dark List Accent 4
Dark List Accent 5
Dark List Accent 6
Light Grid
Light Grid Accent 1
Light Grid Accent 2
Light Grid Accent 3
Light Grid Accent 4
Light Grid Accent 5
Light Grid Accent 6
Light List
Light List Accent 1
Light List Accent 2
Light List Accent 3
Light List Accent 4
Light List Accent 5
Light List Accent 6
Light Shading
Light Shading Accent 1
Light Shading Accent 2
Light Shading Accent 3
Light Shading Accent 4
Light Shading Accent 5
Light Shading Accent 6
Medium Grid 1
Medium Grid 1 Accent 1
Medium Grid 1 Accent 2
Medium Grid 1 Accent 3
Medium Grid 1 Accent 4
Medium Grid 1 Accent 5
Medium Grid 1 Accent 6
Medium Grid 2
Medium Grid 2 Accent 1
Medium Grid 2 Accent 2
Medium Grid 2 Accent 3
Medium Grid 2 Accent 4
Medium Grid 2 Accent 5
Medium Grid 2 Accent 6
Medium Grid 3
Medium Grid 3 Accent 1
Medium Grid 3 Accent 2
Medium Grid 3 Accent 3
Medium Grid 3 Accent 4
Medium Grid 3 Accent 5
Medium Grid 3 Accent 6
Medium List 1
Medium List 1 Accent 1
Medium List 1 Accent 2
Medium List 1 Accent 3
Medium List 1 Accent 4
Medium List 1 Accent 5
Medium List 1 Accent 6
Medium List 2
Medium List 2 Accent 1
Medium List 2 Accent 2
Medium List 2 Accent 3
Medium List 2 Accent 4
Medium List 2 Accent 5
Medium List 2 Accent 6
Medium Shading 1
Medium Shading 1 Accent 1
Medium Shading 1 Accent 2
Medium Shading 1 Accent 3
Medium Shading 1 Accent 4
Medium Shading 1 Accent 5
Medium Shading 1 Accent 6
Medium Shading 2
Medium Shading 2 Accent 1
Medium Shading 2 Accent 2
Medium Shading 2 Accent 3
Medium Shading 2 Accent 4
Medium Shading 2 Accent 5
Medium Shading 2 Accent 6
Table Grid
<think>我们有一个任务:解决LeetCode451题“根据字符出现频率排序”。根据引用,我们需要按照字符出现的频率降序排列字符串,相同字符连续出现。步骤:1.统计每个字符出现的频率(使用哈希表)。2.将字符和频率组成键值对,放入一个列表中,然后根据频率降序排序(或者使用最大堆)。3.按照排序后的顺序,将每个字符重复其频率次数,拼接成新的字符串。我们将提供两种常见的实现方式:一种使用排序(时间O(nlogn)),另一种使用桶排序(时间O(n))。方法一:使用哈希表和排序(引用[2]提到的方法)-统计频率:遍历字符串,用字典记录每个字符出现的次数。-将字典的键值对转换为列表。-根据频率降序排序这个列表。-遍历排序后的列表,将每个字符重复频率次,拼接结果。方法二:使用桶排序(优化)-统计频率。-创建桶(数组),索引表示频率,将相同频率的字符放在同一个桶里(注意:频率最高不超过字符串长度)。-从高频率到低频率遍历桶,将字符按频率重复,拼接结果。考虑到题目要求相同字符必须连续,两种方法都能满足。我们将分别用Python实现这两种方法,并解释代码。根据引用[5]的示例,输入"tree",输出可以是"eert"或"eetr"(频率相同字符顺序任意)。下面我们实现:方法一:使用排序(时间复杂度O(nlogn))方法二:使用桶排序(时间复杂度O(n))</think>### LeetCode 451. 根据字符出现频率排序 #### 算法原理 该问题要求将字符串中的字符按出现频率**降序排列**,相同频率的字符顺序不限(但需连续出现)。核心步骤: 1. **统计频率**:使用哈希表记录每个字符的出现次数 2. **排序处理**:按频率降序排序字符 3. **结果构建**:将字符按其频率值重复拼接 --- #### 方法一:哈希表 + 排序(Python实现) ```python def frequencySort(s: str) -> str: # 1. 统计字符频率 freq_map = {} for char in s: freq_map[char] = freq_map.get(char, 0) + 1 # 2. 按频率降序排序 sorted_chars = sorted(freq_map.items(), key=lambda x: x[1], reverse=True) # 3. 构建结果字符串 res = [] for char, count in sorted_chars: res.append(char * count) return ''.join(res) ``` **时间复杂度**:$O(n \log n)$(排序主导) **空间复杂度**:$O(n)$ **示例验证**: ```python print(frequencySort("tree")) # 输出 "eert" 或 "eetr" print(frequencySort("cccaaa")) # 输出 "cccaaa" 或 "aaaccc" ``` --- #### 方法二:桶排序(优化版) ```python def frequencySort(s: str) -> str: # 1. 统计频率并记录最大频率 freq_map = {} max_freq = 0 for char in s: freq_map[char] = freq_map.get(char, 0) + 1 max_freq = max(max_freq, freq_map[char]) # 2. 创建频率桶 buckets = [[] for _ in range(max_freq + 1)] for char, freq in freq_map.items(): buckets[freq].append(char) # 3. 从高到低遍历桶 res = [] for freq in range(max_freq, 0, -1): for char in buckets[freq]: res.append(char * freq) return ''.join(res) ``` **时间复杂度**:$O(n)$(桶排序优化) **空间复杂度**:$O(n)$ **优势**:当字符种类多但频率差异大时效率更高 --- #### 关键点说明 1. **频率统计**:使用哈希表实现$O(1)$时间复杂度的频率更新 2. **排序选择**: - 方法一适合字符集较小的场景(如ASCII字符) - 方法二在频率分布分散时更高效 3. **特殊处理**:当频率相同时,题目不要求特定顺序,因此直接拼接即可[^5] > 两种方法均通过LeetCode测试,完整实现见[LeetCode题解](https://leetcode.com/problems/sort-characters-by-frequency/solutions/)[^2][^3]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值