TxT2Docx/style_manager.py

822 lines
31 KiB
Python
Raw Normal View History

2025-09-26 15:49:06 +08:00
"""
文章排版样式管理模块
负责管理文档的排版样式包括内置样式和自定义样式
支持样式的创建编辑删除导入和导出等功能
"""
import os
import json
from typing import Dict, Any, List, Optional, Union
from dataclasses import dataclass, asdict, field
from copy import deepcopy
@dataclass
class FontStyle:
"""字体样式配置"""
name: str = "宋体"
size: int = 12
bold: bool = False
italic: bool = False
color: str = "#000000" # RGB颜色值
@dataclass
class ParagraphStyle:
"""段落样式配置"""
line_spacing: float = 1.5
space_before: int = 0 # 段前间距(磅)
space_after: int = 0 # 段后间距(磅)
first_line_indent: float = 0.0 # 首行缩进(字符)
alignment: str = "left" # left, center, right, justify
keep_with_next: bool = False # 与下段同页
@dataclass
class HeadingStyle:
"""标题样式配置"""
font: FontStyle
paragraph: ParagraphStyle
numbering: bool = False # 是否自动编号
outline_level: int = 0 # 大纲级别
@dataclass
class ListStyle:
"""列表样式配置"""
font: FontStyle
paragraph: ParagraphStyle
bullet_symbol: str = "" # 无序列表符号
number_format: str = "1." # 有序列表格式
@dataclass
class SpecialStyle:
"""特殊元素样式配置"""
font: FontStyle
paragraph: ParagraphStyle
background_color: str = "#F5F5F5" # 背景色
border: bool = False # 是否有边框
@dataclass
class DocumentStyle:
"""文档排版样式配置"""
# 基础信息
name: str = "默认样式"
description: str = "标准文档样式"
author: str = "系统"
version: str = "1.0"
# 页面设置
page_margin_top: float = 2.54 # 页边距(cm)
page_margin_bottom: float = 2.54
page_margin_left: float = 3.17
page_margin_right: float = 3.17
# 基础字体和段落
body_font: Optional[FontStyle] = None
body_paragraph: Optional[ParagraphStyle] = None
# 标题样式 (1-6级)
heading_styles: Optional[Dict[int, HeadingStyle]] = None
# 列表样式
unordered_list: Optional[ListStyle] = None
ordered_list: Optional[ListStyle] = None
# 特殊元素样式
code_block: Optional[SpecialStyle] = None
quote_block: Optional[SpecialStyle] = None
table_style: Optional[SpecialStyle] = None
def __post_init__(self):
"""初始化默认值"""
if self.body_font is None:
self.body_font = FontStyle()
if self.body_paragraph is None:
self.body_paragraph = ParagraphStyle()
if self.heading_styles is None:
self.heading_styles = self._create_default_headings()
if self.unordered_list is None:
self.unordered_list = ListStyle(
font=FontStyle(),
paragraph=ParagraphStyle(space_after=6)
)
if self.ordered_list is None:
self.ordered_list = ListStyle(
font=FontStyle(),
paragraph=ParagraphStyle(space_after=6)
)
if self.code_block is None:
self.code_block = SpecialStyle(
font=FontStyle(name="Courier New", size=10),
paragraph=ParagraphStyle(space_before=6, space_after=6),
background_color="#F5F5F5"
)
if self.quote_block is None:
self.quote_block = SpecialStyle(
font=FontStyle(italic=True),
paragraph=ParagraphStyle(first_line_indent=2.0, space_before=6, space_after=6),
background_color="#F9F9F9"
)
if self.table_style is None:
self.table_style = SpecialStyle(
font=FontStyle(size=11),
paragraph=ParagraphStyle(space_before=6, space_after=6),
border=True
)
def _create_default_headings(self) -> Dict[int, HeadingStyle]:
"""创建默认标题样式"""
headings = {}
base_sizes = [18, 16, 14, 13, 12, 11] # 各级标题字号
for level in range(1, 7):
font_size = base_sizes[level - 1] if level <= len(base_sizes) else 11
headings[level] = HeadingStyle(
font=FontStyle(
name="微软雅黑",
size=font_size,
bold=True,
color="#1F497D"
),
paragraph=ParagraphStyle(
line_spacing=1.3,
space_before=12 if level <= 2 else 6,
space_after=6,
keep_with_next=True
),
outline_level=level
)
return headings
class StyleManager:
"""排版样式管理器"""
def __init__(self, styles_dir: str = "data/styles"):
"""
初始化样式管理器
Args:
styles_dir: 样式文件存储目录
"""
self.styles_dir = styles_dir
self.builtin_styles = self._create_builtin_styles()
self.custom_styles = {}
self._load_custom_styles()
def _create_builtin_styles(self) -> Dict[str, DocumentStyle]:
"""创建内置样式(专业版)"""
styles = {}
# 1. 爆款文章风格 - 参考知乎、头条等平台
2025-10-07 15:46:36 +08:00
styles["爆款文章风格"] = self._create_viral_style()
# 2. 微信公众号风格 - 专业的新媒体排版
styles["微信公众号风格"] = self._create_wechat_style()
# 3. 知乎高赞回答风格 - 逻辑清晰,层次分明
styles["知乎高赞回答风格"] = self._create_zhihu_style()
# 4. 小红书笔记风格 - 清新文艺,少女心
styles["小红书笔记风格"] = self._create_xiaohongshu_style()
# 5. 今日头条新闻风格 - 信息量大,节奏紧凑
styles["今日头条新闻风格"] = self._create_toutiao_style()
# 6. B站UP主视频脚本风格 - 轻松活泼,年轻化
styles["B站UP主视频脚本风格"] = self._create_bilibili_style()
# 7. 企业微信群通知风格 - 正式严肃
styles["企业微信群通知风格"] = self._create_enterprise_style()
# 8. 情感鸡汤文风格 - 温暖治愈
styles["情感鸡汤文风格"] = self._create_emotional_style()
return styles
def _create_viral_style(self) -> DocumentStyle:
"""创建爆款文章风格"""
2025-09-26 15:49:06 +08:00
viral_style = DocumentStyle(
name="爆款文章风格",
description="高阅读量爆款文章风格,层次分明,吸引眼球",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#333333"),
body_paragraph=ParagraphStyle(
line_spacing=1.8,
first_line_indent=0.0, # 爆款文章不缩进
space_after=12,
space_before=0
)
)
# 设置爆款文章的标题样式
if viral_style.heading_styles:
# 主标题:大胆吸引眼球
viral_style.heading_styles[1].font = FontStyle(name="黑体", size=22, bold=True, color="#FF4500")
viral_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=20, space_after=20, alignment="center"
)
# 二级标题:强烈对比
viral_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=18, bold=True, color="#FF6B35")
viral_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.4, space_before=16, space_after=12, alignment="left"
)
# 三级标题:精彩分段
viral_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#4CAF50")
viral_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.4, space_before=12, space_after=8
)
# 四级及以下:细分点
for level in range(4, 7):
viral_style.heading_styles[level].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#2196F3")
viral_style.heading_styles[level].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
# 设置特殊元素样式
viral_style.quote_block = SpecialStyle(
font=FontStyle(name="楷体", size=13, italic=True, color="#666666"),
paragraph=ParagraphStyle(
line_spacing=1.6, space_before=10, space_after=10,
first_line_indent=0, alignment="center"
),
background_color="#F8F9FA"
)
2025-10-07 15:46:36 +08:00
return viral_style
def _create_wechat_style(self) -> DocumentStyle:
"""创建微信公众号风格"""
2025-09-26 15:49:06 +08:00
wechat_style = DocumentStyle(
name="微信公众号风格",
description="专业的微信公众号排版,阅读体验佳",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#3C4043"),
body_paragraph=ParagraphStyle(
line_spacing=1.75,
first_line_indent=0.0,
space_after=14,
space_before=0
)
)
if wechat_style.heading_styles:
# 公众号标题的精心设计
wechat_style.heading_styles[1].font = FontStyle(name="黑体", size=20, bold=True, color="#1AAD19")
wechat_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=18, space_after=16, alignment="center"
)
wechat_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=17, bold=True, color="#576B95")
wechat_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=14, space_after=10
)
wechat_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#FA5151")
wechat_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
# 微信公众号的引用样式
wechat_style.quote_block = SpecialStyle(
font=FontStyle(name="微软雅黑", size=13, italic=True, color="#888888"),
paragraph=ParagraphStyle(
line_spacing=1.5, space_before=12, space_after=12,
first_line_indent=1.0, alignment="left"
),
background_color="#F7F7F7",
border=True
)
2025-10-07 15:46:36 +08:00
return wechat_style
def _create_zhihu_style(self) -> DocumentStyle:
"""创建知乎高赞回答风格"""
2025-09-26 15:49:06 +08:00
zhihu_style = DocumentStyle(
name="知乎高赞回答风格",
description="逻辑清晰,层次分明,专业权威",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=15, color="#1A1A1A"),
body_paragraph=ParagraphStyle(
line_spacing=1.6,
first_line_indent=0.0,
space_after=10,
space_before=0
)
)
if zhihu_style.heading_styles:
# 知乎风格的标题设计
zhihu_style.heading_styles[1].font = FontStyle(name="黑体", size=20, bold=True, color="#0084FF")
zhihu_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=16, space_after=14
)
zhihu_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=17, bold=True, color="#00A6FB")
zhihu_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=10
)
zhihu_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#FF6B6B")
zhihu_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
2025-10-07 15:46:36 +08:00
return zhihu_style
def _create_xiaohongshu_style(self) -> DocumentStyle:
"""创建小红书笔记风格"""
2025-09-26 15:49:06 +08:00
xiaohongshu_style = DocumentStyle(
name="小红书笔记风格",
description="清新文艺,适合生活方式类内容",
author="系统内置",
body_font=FontStyle(name="华文细黑", size=14, color="#333333"),
body_paragraph=ParagraphStyle(
line_spacing=1.8,
first_line_indent=0.0,
space_after=12,
space_before=0
)
)
if xiaohongshu_style.heading_styles:
xiaohongshu_style.heading_styles[1].font = FontStyle(name="华文细黑", size=18, bold=True, color="#FF69B4")
xiaohongshu_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=15, space_after=12, alignment="center"
)
xiaohongshu_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#FF6EB4")
xiaohongshu_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=8
)
xiaohongshu_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#FFB6C1")
xiaohongshu_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
2025-10-07 15:46:36 +08:00
return xiaohongshu_style
def _create_toutiao_style(self) -> DocumentStyle:
"""创建今日头条新闻风格"""
2025-09-26 15:49:06 +08:00
toutiao_style = DocumentStyle(
name="今日头条新闻风格",
description="信息密度高,节奏紧凑,突出重点",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#222222"),
body_paragraph=ParagraphStyle(
line_spacing=1.5,
first_line_indent=0.0,
space_after=8,
space_before=0
)
)
if toutiao_style.heading_styles:
toutiao_style.heading_styles[1].font = FontStyle(name="黑体", size=19, bold=True, color="#D43F3A")
toutiao_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=12, space_after=12
)
toutiao_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#D9534F")
toutiao_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
toutiao_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#F0AD4E")
toutiao_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
2025-10-07 15:46:36 +08:00
return toutiao_style
def _create_bilibili_style(self) -> DocumentStyle:
"""创建B站UP主视频脚本风格"""
2025-09-26 15:49:06 +08:00
bilibili_style = DocumentStyle(
name="B站UP主视频脚本风格",
description="轻松活泼,适合年轻受众,有趣有料",
author="系统内置",
body_font=FontStyle(name="微软雅黑", size=14, color="#222222"),
body_paragraph=ParagraphStyle(
line_spacing=1.6,
first_line_indent=0.0,
space_after=10,
space_before=0
)
)
if bilibili_style.heading_styles:
bilibili_style.heading_styles[1].font = FontStyle(name="黑体", size=18, bold=True, color="#00A1D6")
bilibili_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=14, space_after=12
)
bilibili_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#FB7299")
bilibili_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=10, space_after=8
)
bilibili_style.heading_styles[3].font = FontStyle(name="微软雅黑", size=15, bold=True, color="#9C88FF")
bilibili_style.heading_styles[3].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=8, space_after=6
)
2025-10-07 15:46:36 +08:00
return bilibili_style
def _create_enterprise_style(self) -> DocumentStyle:
"""创建企业微信群通知风格"""
2025-09-26 15:49:06 +08:00
enterprise_style = DocumentStyle(
name="企业微信群通知风格",
description="正式严肃,信息传达清晰,商务风格",
author="系统内置",
body_font=FontStyle(name="宋体", size=14, color="#2C2C2C"),
body_paragraph=ParagraphStyle(
line_spacing=1.5,
first_line_indent=2.0,
space_after=10,
space_before=0
)
)
if enterprise_style.heading_styles:
enterprise_style.heading_styles[1].font = FontStyle(name="黑体", size=18, bold=True, color="#1F4E79")
enterprise_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=16, space_after=12, alignment="center"
)
enterprise_style.heading_styles[2].font = FontStyle(name="微软雅黑", size=16, bold=True, color="#2F5597")
enterprise_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=8
)
2025-10-07 15:46:36 +08:00
return enterprise_style
def _create_emotional_style(self) -> DocumentStyle:
"""创建情感鸡汤文风格"""
2025-09-26 15:49:06 +08:00
emotional_style = DocumentStyle(
name="情感鸡汤文风格",
description="温暖治愈,情感丰富,適合心灵鸡汤类内容",
author="系统内置",
body_font=FontStyle(name="楷体", size=14, color="#444444"),
body_paragraph=ParagraphStyle(
line_spacing=1.8,
first_line_indent=1.5,
space_after=12,
space_before=0
)
)
if emotional_style.heading_styles:
emotional_style.heading_styles[1].font = FontStyle(name="华文行楷", size=18, bold=True, color="#E91E63")
emotional_style.heading_styles[1].paragraph = ParagraphStyle(
line_spacing=1.2, space_before=16, space_after=14, alignment="center"
)
emotional_style.heading_styles[2].font = FontStyle(name="楷体", size=16, bold=True, color="#FF5722")
emotional_style.heading_styles[2].paragraph = ParagraphStyle(
line_spacing=1.3, space_before=12, space_after=10
)
# 情感鸡汤文的引用样式
emotional_style.quote_block = SpecialStyle(
font=FontStyle(name="华文行楷", size=13, italic=True, color="#795548"),
paragraph=ParagraphStyle(
line_spacing=1.6, space_before=10, space_after=10,
alignment="center"
),
background_color="#FFF3E0"
)
2025-10-07 15:46:36 +08:00
return emotional_style
2025-09-26 15:49:06 +08:00
def _load_custom_styles(self) -> None:
"""加载自定义样式"""
if not os.path.exists(self.styles_dir):
os.makedirs(self.styles_dir, exist_ok=True)
return
try:
for filename in os.listdir(self.styles_dir):
if filename.endswith('.json'):
filepath = os.path.join(self.styles_dir, filename)
style = self.load_style_from_file(filepath)
if style:
self.custom_styles[style.name] = style
except Exception as e:
print(f"加载自定义样式失败: {e}")
def get_all_styles(self) -> Dict[str, DocumentStyle]:
"""获取所有样式(内置+自定义)"""
all_styles = deepcopy(self.builtin_styles)
all_styles.update(self.custom_styles)
return all_styles
def get_style_names(self) -> List[str]:
"""获取所有样式名称"""
return list(self.get_all_styles().keys())
def get_style(self, name: str) -> Optional[DocumentStyle]:
"""
获取指定样式
Args:
name: 样式名称
Returns:
DocumentStyle: 样式对象如果不存在返回None
"""
if name in self.builtin_styles:
return deepcopy(self.builtin_styles[name])
elif name in self.custom_styles:
return deepcopy(self.custom_styles[name])
return None
def create_custom_style(self, style: DocumentStyle) -> bool:
"""
创建自定义样式
Args:
style: 样式对象
Returns:
bool: 是否创建成功
"""
try:
print(f"尝试创建自定义样式: {style.name}") # 调试信息
if style.name in self.builtin_styles:
print(f"错误: {style.name} 是内置样式,不能覆盖")
return False # 不能覆盖内置样式
# 检查样式对象的完整性
if not style.body_font:
print("错误: 样式缺少body_font")
return False
if not style.body_paragraph:
print("错误: 样式缺少body_paragraph")
return False
print("样式对象检查通过")
# 保存到内存
self.custom_styles[style.name] = style
print(f"样式已保存到内存: {style.name}")
# 保存到文件
file_result = self.save_style_to_file(style)
print(f"文件保存结果: {file_result}")
if not file_result:
# 如果文件保存失败,从内存中移除
del self.custom_styles[style.name]
print("文件保存失败,已从内存中移除")
return False
print(f"样式 '{style.name}' 创建成功")
return True
except Exception as e:
print(f"创建自定义样式异常: {e}")
import traceback
traceback.print_exc()
return False
def update_custom_style(self, style: DocumentStyle) -> bool:
"""
更新自定义样式
Args:
style: 样式对象
Returns:
bool: 是否更新成功
"""
try:
if style.name in self.builtin_styles:
return False # 不能修改内置样式
self.custom_styles[style.name] = style
self.save_style_to_file(style)
return True
except Exception as e:
print(f"更新自定义样式失败: {e}")
return False
def delete_custom_style(self, name: str) -> bool:
"""
删除自定义样式
Args:
name: 样式名称
Returns:
bool: 是否删除成功
"""
try:
if name in self.builtin_styles:
return False # 不能删除内置样式
if name in self.custom_styles:
del self.custom_styles[name]
# 删除文件
filepath = os.path.join(self.styles_dir, f"{name}.json")
if os.path.exists(filepath):
os.remove(filepath)
return True
return False
except Exception as e:
print(f"删除自定义样式失败: {e}")
return False
def save_style_to_file(self, style: DocumentStyle, filepath: Optional[str] = None) -> bool:
"""
保存样式到文件
Args:
style: 样式对象
filepath: 文件路径如果为None则使用默认路径
Returns:
bool: 是否保存成功
"""
try:
if filepath is None:
os.makedirs(self.styles_dir, exist_ok=True)
filepath = os.path.join(self.styles_dir, f"{style.name}.json")
print(f"保存样式到文件: {filepath}") # 调试信息
# 检查目录权限
if not os.access(self.styles_dir, os.W_OK):
print(f"错误: 没有写入权限 - {self.styles_dir}")
return False
# 尝试序列化样式对象
style_dict = asdict(style)
print("样式对象序列化成功")
# 尝试写入文件
with open(filepath, 'w', encoding='utf-8') as f:
json.dump(style_dict, f, ensure_ascii=False, indent=2)
print(f"样式文件保存成功: {filepath}")
# 验证文件是否存在且可读
if os.path.exists(filepath) and os.path.getsize(filepath) > 0:
print("文件存在性验证通过")
return True
else:
print("错误: 文件保存后验证失败")
return False
except Exception as e:
print(f"保存样式文件异常: {e}")
import traceback
traceback.print_exc()
return False
def load_style_from_file(self, filepath: str) -> Optional[DocumentStyle]:
"""
从文件加载样式
Args:
filepath: 文件路径
Returns:
DocumentStyle: 样式对象加载失败返回None
"""
try:
with open(filepath, 'r', encoding='utf-8') as f:
style_dict = json.load(f)
# 递归转换字典为dataclass
style = self._dict_to_style(style_dict)
return style
except Exception as e:
print(f"加载样式文件失败: {e}")
return None
def _dict_to_style(self, data: Dict[str, Any]) -> DocumentStyle:
"""将字典转换为DocumentStyle对象"""
# 转换嵌套的字体样式
if 'body_font' in data and data['body_font']:
data['body_font'] = FontStyle(**data['body_font'])
# 转换段落样式
if 'body_paragraph' in data and data['body_paragraph']:
data['body_paragraph'] = ParagraphStyle(**data['body_paragraph'])
# 转换标题样式
if 'heading_styles' in data and data['heading_styles']:
heading_styles = {}
for level, heading_data in data['heading_styles'].items():
if isinstance(heading_data, dict):
font_data = heading_data.get('font', {})
para_data = heading_data.get('paragraph', {})
heading_styles[int(level)] = HeadingStyle(
font=FontStyle(**font_data) if font_data else FontStyle(),
paragraph=ParagraphStyle(**para_data) if para_data else ParagraphStyle(),
numbering=heading_data.get('numbering', False),
outline_level=heading_data.get('outline_level', int(level))
)
data['heading_styles'] = heading_styles
# 转换列表样式
for list_type in ['unordered_list', 'ordered_list']:
if list_type in data and data[list_type]:
list_data = data[list_type]
font_data = list_data.get('font', {})
para_data = list_data.get('paragraph', {})
data[list_type] = ListStyle(
font=FontStyle(**font_data) if font_data else FontStyle(),
paragraph=ParagraphStyle(**para_data) if para_data else ParagraphStyle(),
bullet_symbol=list_data.get('bullet_symbol', ''),
number_format=list_data.get('number_format', '1.')
)
# 转换特殊样式
for special_type in ['code_block', 'quote_block', 'table_style']:
if special_type in data and data[special_type]:
special_data = data[special_type]
font_data = special_data.get('font', {})
para_data = special_data.get('paragraph', {})
data[special_type] = SpecialStyle(
font=FontStyle(**font_data) if font_data else FontStyle(),
paragraph=ParagraphStyle(**para_data) if para_data else ParagraphStyle(),
background_color=special_data.get('background_color', '#F5F5F5'),
border=special_data.get('border', False)
)
return DocumentStyle(**data)
def export_style(self, name: str, export_path: str) -> bool:
"""
导出样式到指定路径
Args:
name: 样式名称
export_path: 导出路径
Returns:
bool: 是否导出成功
"""
style = self.get_style(name)
if style:
return self.save_style_to_file(style, export_path)
return False
def import_style(self, import_path: str) -> Optional[str]:
"""
从指定路径导入样式
Args:
import_path: 导入路径
Returns:
Optional[str]: 导入的样式名称失败返回None
"""
style = self.load_style_from_file(import_path)
if style:
if self.create_custom_style(style):
return style.name
return None
def duplicate_style(self, source_name: str, new_name: str) -> bool:
"""
复制样式
Args:
source_name: 源样式名称
new_name: 新样式名称
Returns:
bool: 是否复制成功
"""
source_style = self.get_style(source_name)
if source_style and new_name not in self.get_all_styles():
source_style.name = new_name
source_style.description = f"基于 {source_name} 复制"
return self.create_custom_style(source_style)
return False
# 创建全局样式管理器实例
style_manager = StyleManager()
# 兼容性函数
def get_all_styles() -> Dict[str, DocumentStyle]:
"""获取所有样式(兼容旧接口)"""
return style_manager.get_all_styles()
def get_style(name: str) -> Optional[DocumentStyle]:
"""获取指定样式(兼容旧接口)"""
return style_manager.get_style(name)