diff --git a/.qoder/quests/pdf-to-word-gui-tool.md b/.qoder/quests/pdf-to-word-gui-tool.md deleted file mode 100644 index a618d0ca..00000000 --- a/.qoder/quests/pdf-to-word-gui-tool.md +++ /dev/null @@ -1,361 +0,0 @@ -# PDF转Word GUI工具设计文档 - -## 功能概述 - -为python-office项目开发一个独立的PDF转Word桌面应用程序,提供图形化界面供用户便捷地将PDF文件转换为可编辑的Word文档。 - -## 核心目标 - -- 提供简洁易用的图形界面 -- 支持单个PDF文件转换 -- 支持批量PDF文件转换 -- 显示转换进度 -- 提供转换结果反馈 - -## 功能需求 - -### 界面布局 - -主窗口包含以下区域: - -| 区域名称 | 说明 | 主要内容 | -|---------|------|---------| -| 标题栏 | 应用程序标题 | 显示"PDF转Word工具" | -| 文件选择区 | 选择待转换文件 | 文件路径输入框、浏览按钮、批量选择按钮 | -| 输出设置区 | 配置输出选项 | 输出路径选择、文件命名规则 | -| 操作控制区 | 转换操作控制 | 开始转换按钮、取消按钮、清空列表按钮 | -| 状态显示区 | 显示转换状态 | 进度条、状态文本、文件列表及转换状态 | - -### 交互流程 - -```mermaid -flowchart TD - A[启动应用] --> B[显示主界面] - B --> C{用户操作} - C -->|选择单个文件| D[浏览选择PDF文件] - C -->|批量选择| E[批量浏览选择多个PDF] - C -->|拖拽文件| F[拖拽PDF文件到窗口] - - D --> G[文件添加到列表] - E --> G - F --> G - - G --> H[设置输出路径] - H --> I{开始转换} - - I --> J[遍历文件列表] - J --> K[转换单个文件] - K --> L[更新进度] - L --> M{是否还有文件} - - M -->|是| J - M -->|否| N[显示完成提示] - - K -->|转换失败| O[记录错误信息] - O --> M - - N --> P[用户可选择] - P -->|打开输出目录| Q[打开文件夹] - P -->|继续转换| B - P -->|退出| R[关闭应用] -``` - -### 功能特性 - -#### 文件选择 - -- 单文件选择:通过文件浏览对话框选择单个PDF文件 -- 批量选择:支持一次性选择多个PDF文件 -- 拖拽支持:支持将PDF文件拖拽到窗口中 -- 文件过滤:仅显示和接受.pdf格式文件 -- 文件列表:显示已选择的所有待转换文件及其路径 - -#### 输出设置 - -- 输出路径选择:用户可自定义Word文档保存位置 -- 默认输出路径:默认为源文件所在目录 -- 文件命名策略: - - 保持原文件名,扩展名改为.docx - - 文件重名时自动添加编号后缀 - -#### 转换控制 - -- 开始转换:触发转换流程 -- 取消转换:中断正在进行的转换任务 -- 清空列表:清除所有已选择的文件 -- 批量转换:自动依次处理列表中的所有文件 - -#### 状态反馈 - -- 整体进度:显示总体转换进度百分比和进度条 -- 当前文件:显示正在转换的文件名称 -- 文件状态:在列表中标记每个文件的转换状态(等待、转换中、成功、失败) -- 错误提示:转换失败时显示具体错误信息 -- 完成通知:所有转换完成后弹出提示 - -## 技术方案 - -### 技术栈选择 - -| 技术组件 | 选用方案 | 说明 | -|---------|---------|------| -| GUI框架 | PyQt5 | 与项目现有GUI版本保持一致 | -| PDF转换核心 | office.pdf.pdf2docx | 使用项目已有的PDF转换API | -| 底层依赖 | popdf | 实际执行转换的底层库 | - -### 架构设计 - -采用MVC架构模式组织代码: - -```mermaid -flowchart LR - A[View 视图层] -->|用户交互| B[Controller 控制层] - B -->|调用转换| C[Model 业务层] - C -->|返回结果| B - B -->|更新界面| A - - C -->|调用| D[office.pdf.pdf2docx] - D -->|依赖| E[popdf库] -``` - -| 层次 | 职责 | 主要内容 | -|------|------|---------| -| View 视图层 | 界面呈现与交互 | 窗口组件、布局、样式、事件绑定 | -| Controller 控制层 | 业务逻辑控制 | 文件管理、转换流程控制、状态管理 | -| Model 业务层 | 数据处理 | 调用PDF转换API、文件操作、错误处理 | - -### 核心模块 - -#### 主窗口模块 - -- 负责整体界面布局和组件初始化 -- 管理子组件的创建和布局 -- 处理窗口级别的事件(关闭、最小化等) - -#### 文件管理模块 - -- 管理文件列表数据结构 -- 处理文件选择、添加、移除操作 -- 验证文件格式和可访问性 -- 支持拖拽功能 - -#### 转换控制模块 - -- 封装PDF转Word转换逻辑 -- 管理转换任务队列 -- 处理单个和批量转换流程 -- 实现转换的启动、暂停、取消 - -#### 进度管理模块 - -- 计算和更新转换进度 -- 管理各文件的状态 -- 向界面反馈实时进度信息 - -#### 异常处理模块 - -- 捕获转换过程中的异常 -- 提供友好的错误信息 -- 记录错误日志供调试使用 - -## 界面设计 - -### 主窗口布局 - -主窗口采用垂直布局,从上到下依次为: - -- 顶部工具栏:包含批量添加、清空列表等快捷操作 -- 文件列表区域:表格形式展示待转换文件 -- 输出设置面板:输出路径选择控件 -- 底部操作区:开始转换按钮和进度条 - -### 文件列表表格 - -| 列名 | 宽度比例 | 内容 | -|------|---------|------| -| 序号 | 5% | 文件编号 | -| 文件名 | 40% | PDF文件名称 | -| 文件路径 | 40% | 完整路径 | -| 状态 | 15% | 等待/转换中/成功/失败 | - -### 状态标识 - -使用不同颜色和图标标识文件状态: - -- 等待:灰色圆点 -- 转换中:蓝色旋转图标 -- 成功:绿色对勾 -- 失败:红色叉号 - -## 转换逻辑 - -### 转换流程 - -转换过程分为以下阶段: - -| 阶段 | 说明 | 关键操作 | -|------|------|---------| -| 准备阶段 | 转换前的验证和初始化 | 检查文件存在性、创建输出目录、初始化进度 | -| 转换阶段 | 执行实际转换 | 调用office.pdf.pdf2docx,传入文件路径和输出路径 | -| 结果处理 | 处理转换结果 | 验证输出文件、更新状态、记录日志 | -| 清理阶段 | 转换后的收尾工作 | 更新进度条、释放资源 | - -### 批量转换策略 - -批量转换时采用顺序处理策略: - -- 按文件列表顺序依次转换 -- 单个文件转换失败不影响后续文件 -- 记录每个文件的转换结果 -- 所有文件处理完毕后统一展示结果报告 - -### 错误处理 - -针对可能出现的错误情况制定处理策略: - -| 错误类型 | 处理策略 | -|---------|---------| -| 文件不存在 | 提示用户文件路径无效,跳过该文件 | -| 文件被占用 | 提示用户关闭文件,可选择重试或跳过 | -| 输出路径无权限 | 提示用户选择其他输出路径 | -| 转换失败 | 显示具体错误信息,记录日志,跳过该文件 | -| 磁盘空间不足 | 提示用户清理磁盘空间或更换输出路径 | - -## 数据结构 - -### 文件信息对象 - -每个待转换文件使用字典结构存储信息: - -| 字段名 | 类型 | 说明 | -|-------|------|------| -| id | int | 文件序号 | -| filename | str | 文件名 | -| filepath | str | 完整路径 | -| status | str | 当前状态:waiting/processing/success/failed | -| output_path | str | 输出文件路径 | -| error_msg | str | 错误信息(如有) | - -### 应用状态 - -应用程序维护全局状态信息: - -| 状态项 | 说明 | -|-------|------| -| file_list | 待转换文件列表 | -| current_index | 当前正在转换的文件索引 | -| total_count | 文件总数 | -| success_count | 成功转换数量 | -| failed_count | 失败转换数量 | -| is_converting | 是否正在转换 | -| output_directory | 默认输出目录 | - -## 配置项 - -应用程序支持以下配置选项: - -| 配置项 | 默认值 | 说明 | -|-------|-------|------| -| 默认输出路径 | 源文件目录 | 转换文件的默认保存位置 | -| 窗口大小 | 800x600 | 主窗口初始尺寸 | -| 最大并发数 | 1 | 同时转换的文件数量(当前版本为1,顺序处理) | -| 自动打开输出目录 | False | 转换完成后是否自动打开输出文件夹 | -| 显示详细日志 | False | 是否在界面显示详细的转换日志 | - -## 用户体验优化 - -### 交互优化 - -- 提供文件拖拽功能,简化文件添加流程 -- 转换完成后可一键打开输出文件夹 -- 支持键盘快捷键操作(如Delete删除选中文件) -- 双击列表中的文件可在资源管理器中定位 - -### 性能优化 - -- 文件列表使用虚拟滚动,支持大量文件 -- 转换过程使用多线程,避免界面卡顿 -- 大文件转换时实时显示进度避免假死感 - -### 视觉优化 - -- 使用清晰的图标和状态颜色 -- 进度条平滑过渡动画 -- 错误信息使用醒目的颜色提示 -- 界面采用简洁现代的设计风格 - -## 扩展性考虑 - -预留以下扩展能力: - -| 扩展方向 | 说明 | -|---------|------| -| 转换参数配置 | 未来可支持配置转换质量、页面范围等参数 | -| 格式支持扩展 | 预留接口支持其他格式转换(如PDF转图片) | -| 批处理脚本 | 支持保存批处理任务配置,一键重复执行 | -| 转换历史 | 记录转换历史,支持查看和重新转换 | -| 多语言支持 | 预留国际化接口,支持中英文切换 | - -## 部署方案 - -### 打包方式 - -使用PyInstaller将Python应用打包为独立可执行文件: - -- Windows平台:生成.exe可执行文件 -- 包含所有依赖库,无需用户安装Python环境 -- 单文件模式或目录模式可选 - -### 目录结构 - -打包后的应用程序目录结构: - -``` -pdf2word-gui/ -├── pdf2word.exe # 主程序 -├── config/ # 配置文件目录(可选) -│ └── settings.json -├── logs/ # 日志目录(运行时创建) -└── README.txt # 使用说明 -``` - -### 依赖管理 - -确保打包时包含以下核心依赖: - -- PyQt5:GUI框架 -- python-office:项目核心库 -- popdf:PDF处理底层库 - -## 测试要点 - -### 功能测试 - -- 单文件转换正常流程 -- 批量文件转换正常流程 -- 文件拖拽功能 -- 输出路径自定义 -- 转换取消功能 -- 清空列表功能 - -### 异常测试 - -- 选择非PDF文件的处理 -- 输入文件不存在的处理 -- 输出路径无权限的处理 -- 转换过程中删除源文件 -- 磁盘空间不足场景 -- 超大PDF文件转换 - -### 兼容性测试 - -- Windows 10/11系统 -- 不同分辨率屏幕显示 -- 高DPI显示器适配 - -### 性能测试 - -- 批量转换100个文件的性能 -- 大文件(如100MB以上)转换性能 -- 界面响应速度 -- 内存占用情况 diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/API\345\217\202\350\200\203.md" "b/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/API\345\217\202\350\200\203.md" deleted file mode 100644 index 96fe2349..00000000 --- "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/API\345\217\202\350\200\203.md" +++ /dev/null @@ -1,1510 +0,0 @@ -# API参考 - - -**本文档中引用的文件** -- [office/__init__.py](file://office/__init__.py) -- [office/api/__init__.py](file://office/api/__init__.py) -- [office/api/excel.py](file://office/api/excel.py) -- [office/api/email.py](file://office/api/email.py) -- [office/api/pdf.py](file://office/api/pdf.py) -- [office/api/wechat.py](file://office/api/wechat.py) -- [office/api/word.py](file://office/api/word.py) -- [office/api/image.py](file://office/api/image.py) -- [office/api/tools.py](file://office/api/tools.py) -- [office/api/file.py](file://office/api/file.py) -- [office/api/finance.py](file://office/api/finance.py) -- [office/api/ocr.py](file://office/api/ocr.py) -- [office/api/markdown.py](file://office/api/markdown.py) -- [office/api/ppt.py](file://office/api/ppt.py) -- [office/api/video.py](file://office/api/video.py) -- [office/api/web.py](file://office/api/web.py) -- [office/api/testApi/ruiming.py](file://office/api/testApi/ruiming.py) - - -## 目录 -1. [简介](#简介) -2. [API聚合机制](#api聚合机制) -3. [Excel API](#excel-api) -4. [邮件 API](#邮件-api) -5. [PDF API](#pdf-api) -6. [微信 API](#微信-api) -7. [Word API](#word-api) -8. [图片 API](#图片-api) -9. [工具 API](#工具-api) -10. [文件 API](#文件-api) -11. [金融 API](#金融-api) -12. [OCR API](#ocr-api) -13. [Markdown API](#markdown-api) -14. [PPT API](#ppt-api) -15. [视频 API](#视频-api) -16. [Web API](#web-api) -17. [测试API](#测试api) - -## 简介 -`python-office` 是一个功能丰富的Python库,旨在简化办公自动化任务。该库提供了处理Excel、PDF、Word、邮件、微信等多种办公文档和通信工具的API。每个API模块都封装了特定功能,使开发者能够通过简单的函数调用来完成复杂的办公自动化任务。本API参考文档详细记录了`office.api`包下所有公开接口,包括函数签名、参数说明、返回值和使用示例。 - -## API聚合机制 -`python-office`库通过精心设计的模块结构,实现了API的聚合和便捷访问。核心机制位于`office/__init__.py`文件中,它将各个功能模块聚合并暴露给用户,使得开发者可以通过`import office`后直接访问`office.excel`、`office.pdf`等功能。 - -```mermaid -graph TD -office[office] --> api[api] -office --> compatibility[compatibility] -api --> excel[excel] -api --> pdf[pdf] -api --> word[word] -api --> wechat[wechat] -api --> email[email] -api --> image[image] -api --> file[file] -api --> finance[finance] -api --> ocr[ocr] -api --> markdown[markdown] -api --> ppt[ppt] -api --> video[video] -api --> web[web] -api --> tools[tools] -api --> testApi[testApi] -testApi --> ruiming[ruiming] -``` - -**图源** -- [office/__init__.py](file://office/__init__.py) -- [office/api/__init__.py](file://office/api/__init__.py) - -**节源** -- [office/__init__.py](file://office/__init__.py#L1-L30) -- [office/api/__init__.py](file://office/api/__init__.py#L1-L2) - -### 模块聚合实现 -`office/__init__.py`文件通过一系列导入语句,将`office.api`包中的所有模块聚合到`office`命名空间下: - -```python -from office.api import email -from office.api import excel -from office.api import file -from office.api import finance -from office.api import image -from office.api import pdf -from office.api import ppt -from office.api import tools -from office.api import video -from office.api import wechat -from office.api import word -from office.api import markdown -from office.api import ocr -# 以下是beta版本 -from office.api.testApi import ruiming -``` - -这种设计模式使得用户只需导入`office`包,即可访问所有子模块,极大地简化了API的使用。例如,用户可以直接使用`office.excel.fake2excel()`来调用Excel模块的功能,而无需关心底层的模块结构。 - -## Excel API -Excel API模块提供了丰富的Excel文件处理功能,包括数据模拟、文件合并拆分、格式转换等。 - -**节源** -- [office/api/excel.py](file://office/api/excel.py#L1-L137) - -### fake2excel -自动创建Excel并模拟数据。 - -**参数** -- **columns** (list): 列名。可以模拟的列有:https://www.python4office.cn/python-office/fake2excel/,默认值:['name'] -- **rows** (int): 生成多少行数据,默认值:1 -- **path** (str): 生成的Excel的位置和名称 -- **language** (str): 数据用什么语言,默认是中文,可以填english - -**返回值** -- None - -**示例** -```python -office.excel.fake2excel(columns=['姓名', '年龄', '邮箱'], rows=100, path='模拟数据.xlsx', language='zh_CN') -``` - -### merge2excel -多个Excel合并到一个文件的不同sheet中。 - -**参数** -- **dir_path** (str): 包含多个Excel文件的目录路径 -- **output_file** (str): 合并后的Excel文件路径,默认为'merge2excel.xlsx' - -**返回值** -- None - -**示例** -```python -office.excel.merge2excel(dir_path='./excel_files', output_file='合并结果.xlsx') -``` - -### sheet2excel -同一个Excel的不同sheet拆分为不同文件。 - -**参数** -- **file_path** (str): 需要拆分的Excel文件路径 -- **output_path** (str): 拆分后文件的输出目录,默认为当前目录 - -**返回值** -- None - -**示例** -```python -office.excel.sheet2excel(file_path='多个sheet.xlsx', output_path='./拆分结果/') -``` - -### merge2sheet -实现多个Excel的多个sheet的自动合并。 - -**参数** -- **dir_path** (str): 包含多个Excel文件的目录路径 -- **output_sheet_name** (str): 合并后的sheet名称,默认为'Sheet1' -- **output_excel_name** (str): 合并后的Excel文件名,默认为'merge2sheet' - -**返回值** -- None - -**示例** -```python -office.excel.merge2sheet(dir_path='./待合并文件/', output_sheet_name='汇总数据', output_excel_name='合并工作簿') -``` - -### find_excel_data -搜索Excel中指定内容的文件、行数、内容详情。 - -**参数** -- **search_key** (str): 需要搜索的关键词 -- **target_dir** (str): 搜索的目录路径 - -**返回值** -- None - -**示例** -```python -office.excel.find_excel_data(search_key='重要客户', target_dir='./财务数据/') -``` - -### split_excel_by_column -按指定列的内容拆分Excel。 - -**参数** -- **filepath** (str): 需要拆分的Excel文件路径 -- **column** (int): 按哪一列的内容进行拆分 -- **worksheet_name** (str, 可选): 指定工作表名称,默认为None表示第一个工作表 - -**返回值** -- None - -**示例** -```python -office.excel.split_excel_by_column(filepath='销售数据.xlsx', column=2, worksheet_name='2023年销售') -``` - -### excel2pdf -将指定的Excel文件的指定工作表转换为PDF文件。 - -**参数** -- **excel_path** (str): Excel文件的路径 -- **pdf_path** (str): 转换后生成的PDF文件的路径 -- **sheet_id** (int): 工作表的索引,默认为0,表示第一个工作表 - -**返回值** -- None - -**示例** -```python -office.excel.excel2pdf(excel_path='报告.xlsx', pdf_path='报告.pdf', sheet_id=0) -``` - -## 邮件 API -邮件API模块提供了发送和接收邮件的功能。 - -**节源** -- [office/api/email.py](file://office/api/email.py#L1-L45) - -### send_email -自动发送邮件。 - -**参数** -- **key** (str): 邮箱账户密钥 -- **msg_from** (str): 发件人邮箱地址 -- **msg_to** (str): 收件人邮箱地址 -- **msg_cc** (str, 可选): 抄送人邮箱地址 -- **attach_files** (list, 可选): 邮件附件路径列表,默认为空列表 -- **msg_subject** (str, 可选): 邮件主题,默认为空字符串 -- **content** (str, 可选): 邮件内容,默认为空字符串 -- **host** (str, 可选): 邮箱服务器地址,默认为'qq' -- **port** (int, 可选): 邮箱服务器端口号,默认为465 - -**返回值** -- None - -**示例** -```python -office.email.send_email( - key='your_password', - msg_from='sender@example.com', - msg_to='recipient@example.com', - msg_subject='测试邮件', - content='这是一封测试邮件', - host='smtp.qq.com', - port=465 -) -``` - -### receive_email -接收邮件。 - -**参数** -- **key** (str): 邮箱账户密钥 -- **msg_from** (str): 发件人邮箱地址 -- **msg_to** (str): 收件人邮箱地址 -- **output_path** (str, 可选): 输出路径,默认为当前目录 -- **status** (str, 可选): 邮件状态,默认为"UNSEEN" -- **msg_subject** (str, 可选): 邮件主题 -- **content** (str, 可选): 邮件内容 -- **host** (str, 可选): 邮箱服务器地址,默认为'qq' -- **port** (int, 可选): 邮箱服务器端口号,默认为465 - -**返回值** -- None - -**示例** -```python -office.email.receive_email( - key='your_password', - msg_from='sender@example.com', - msg_to='your_email@example.com', - output_path='./received_emails/', - status="UNSEEN" -) -``` - -## PDF API -PDF API模块提供了丰富的PDF文件处理功能,包括格式转换、加密解密、水印添加等。 - -**节源** -- [office/api/pdf.py](file://office/api/pdf.py#L1-L226) - -### pdf2docx -PDF转Word。 - -**参数** -- **input_file** (str): PDF文件路径 -- **output_path** (str, 可选): 输出Word文件路径,默认为当前目录 - -**返回值** -- None - -**示例** -```python -office.pdf.pdf2docx(input_file='文档.pdf', output_path='./转换结果/') -``` - -### pdf2imgs -PDF转图片。 - -**参数** -- **input_file** (str): PDF文件路径 -- **output_path** (str): 输出图片路径 -- **merge** (bool, 可选): 是否合并为一张图片,默认为False - -**返回值** -- None - -**示例** -```python -office.pdf.pdf2imgs(input_file='文档.pdf', output_path='./图片结果/', merge=True) -``` - -### txt2pdf -将文本文件转换为PDF文件。 - -**参数** -- **input_file** (str): 文本文件路径 -- **output_file** (str, 可选): 输出PDF文件路径,默认为'txt2pdf.pdf' - -**返回值** -- None - -**示例** -```python -office.pdf.txt2pdf(input_file='文章.txt', output_file='文章.pdf') -``` - -### split4pdf -拆分PDF文件。 - -**参数** -- **input_file** (str): PDF文件路径 -- **output_file** (str, 可选): 输出拆分后的PDF文件路径 -- **from_page** (int, 可选): 起始页码,默认为-1(从第一页开始) -- **to_page** (int, 可选): 结束页码,默认为-1(到最后一页结束) - -**返回值** -- None - -**示例** -```python -office.pdf.split4pdf(input_file='长文档.pdf', output_file='拆分结果.pdf', from_page=5, to_page=10) -``` - -### encrypt4pdf -加密PDF文件。 - -**参数** -- **password** (str): PDF文件的加密密码 -- **input_file** (str, 可选): 输入的PDF文件名(包含路径) -- **output_file** (str, 可选): 输出的加密PDF文件名(包含路径) -- **input_path** (str, 可选): 输入文件的完整路径 -- **output_path** (str, 可选): 输出文件的完整路径 - -**返回值** -- None - -**示例** -```python -office.pdf.encrypt4pdf( - password='123456', - input_file='文档.pdf', - output_file='加密文档.pdf' -) -``` - -### decrypt4pdf -解密PDF文件。 - -**参数** -- **password** (str): PDF文件的解密密码 -- **input_file** (str, 可选): 输入的PDF文件名(包含路径) -- **output_file** (str, 可选): 输出的解密PDF文件名(包含路径) -- **input_path** (str, 可选): 输入文件的完整路径 -- **output_path** (str, 可选): 输出文件的完整路径 - -**返回值** -- None - -**示例** -```python -office.pdf.decrypt4pdf( - password='123456', - input_file='加密文档.pdf', - output_file='解密文档.pdf' -) -``` - -### add_text_watermark -在PDF文档中添加文本水印。 - -**参数** -- **input_file** (str): PDF文件路径 -- **point** (tuple): 水印位置坐标 -- **text** (str, 可选): 水印文本内容,默认为'python-office' -- **output_file** (str, 可选): 输出PDF文件路径 -- **fontname** (str, 可选): 字体名称,默认为'Helvetica' -- **fontsize** (int, 可选): 字体大小,默认为12 -- **color** (tuple, 可选): 字体颜色,默认为红色(1, 0, 0) - -**返回值** -- None - -**示例** -```python -office.pdf.add_text_watermark( - input_file='文档.pdf', - point=(100, 100), - text='机密文件', - output_file='带水印文档.pdf', - fontsize=20, - color=(0.5, 0.5, 0.5) -) -``` - -### merge2pdf -合并多个PDF文件。 - -**参数** -- **input_file_list** (list): PDF文件路径列表 -- **output_file** (str): 合并后的PDF文件路径 - -**返回值** -- None - -**示例** -```python -pdf_files = ['文档1.pdf', '文档2.pdf', '文档3.pdf'] -office.pdf.merge2pdf(input_file_list=pdf_files, output_file='合并文档.pdf') -``` - -### del4pdf -删除PDF文件中的指定页面。 - -**参数** -- **input_file** (str): PDF文件路径 -- **output_file** (str): 输出PDF文件路径 -- **page_nums** (list): 要删除的页码列表 - -**返回值** -- None - -**示例** -```python -office.pdf.del4pdf(input_file='文档.pdf', output_file='删除页面后.pdf', page_nums=[3, 5, 7]) -``` - -### add_mark -给PDF添加水印。 - -**参数** -- **pdf_file** (str): PDF文件的位置 -- **mark_str** (str): 需要添加的水印内容 -- **output_path** (str, 可选): 保存文件的位置 -- **output_file_name** (str, 可选): 指定添加了水印的文件名称 - -**返回值** -- None - -**示例** -```python -office.pdf.add_mark( - pdf_file='文档.pdf', - mark_str='内部资料', - output_path='./水印结果/', - output_file_name='内部文档.pdf' -) -``` - -### add_watermark_by_parameters -给PDF添加水印(带参数)。 - -**参数** -- **pdf_file** (str): PDF文件的位置 -- **mark_str** (str): 需要添加的水印内容 -- **output_path** (str, 可选): 保存文件的位置 -- **output_file_name** (str, 可选): 指定添加了水印的文件名称 - -**返回值** -- None - -**示例** -```python -office.pdf.add_watermark_by_parameters( - pdf_file='文档.pdf', - mark_str='草稿', - output_path='./水印结果/', - output_file_name='草稿文档.pdf' -) -``` - -### add_img_water -给PDF添加图片水印。 - -**参数** -- **pdf_file_in** (str): 原始PDF文件路径 -- **pdf_file_mark** (str): 水印PDF文件路径 -- **pdf_file_out** (str): 输出PDF文件路径 - -**返回值** -- None - -**示例** -```python -office.pdf.add_img_water( - pdf_file_in='文档.pdf', - pdf_file_mark='水印.pdf', - pdf_file_out='带图片水印.pdf' -) -``` - -## 微信 API -微信API模块提供了与微信机器人交互的功能,包括发送消息、发送文件、群发等。 - -**节源** -- [office/api/wechat.py](file://office/api/wechat.py#L1-L95) - -### send_message -发送消息给指定联系人。 - -**参数** -- **who** (str): 接收消息的联系人名称 -- **message** (str): 要发送的消息内容 - -**返回值** -- None - -**示例** -```python -office.wechat.send_message(who='张三', message='你好,今天的工作完成了吗?') -``` - -### send_message_by_time -在指定时间发送消息给指定联系人。 - -**参数** -- **who** (str): 接收消息的联系人名称 -- **message** (str): 要发送的消息内容 -- **time** (str): 发送消息的预定时间 - -**返回值** -- None - -**示例** -```python -office.wechat.send_message_by_time(who='李四', message='记得参加会议', time='2023-12-01 14:00:00') -``` - -### chat_by_keywords -根据关键词与指定联系人聊天。 - -**参数** -- **who** (str): 进行聊天的联系人名称 -- **keywords** (list): 触发聊天的关键词列表 - -**返回值** -- None - -**示例** -```python -office.wechat.chat_by_keywords(who='王五', keywords=['你好', '在吗', '忙吗']) -``` - -### send_file -发送文件给指定联系人。 - -**参数** -- **who** (str): 接收文件的联系人名称 -- **file** (str): 要发送的文件路径 - -**返回值** -- None - -**示例** -```python -office.wechat.send_file(who='赵六', file='./报告.pdf') -``` - -### group_send -群发消息。 - -**参数** -- 无 - -**返回值** -- None - -**示例** -```python -office.wechat.group_send() -``` - -### receive_message -接收微信机器人消息并保存到指定路径。 - -**参数** -- **who** (str, 可选): 发送消息的微信联系人,默认为'文件传输助手' -- **txt** (str, 可选): 消息内容的文本文件名,默认为'userMessage.txt' -- **output_path** (str, 可选): 消息内容的保存路径,默认为当前目录 - -**返回值** -- None - -**示例** -```python -office.wechat.receive_message(who='张三', txt='聊天记录.txt', output_path='./微信消息/') -``` - -### chat_robot -智能聊天。 - -**参数** -- **who** (str, 可选): 指定聊天对象,可以是备注名称,不支持特殊字符,默认为'程序员晚枫' - -**返回值** -- None - -**示例** -```python -office.wechat.chat_robot(who='李四') -``` - -## Word API -Word API模块提供了Word文档处理功能,包括格式转换、文件合并等。 - -**节源** -- [office/api/word.py](file://office/api/word.py#L1-L72) - -### docx2pdf -Word转PDF。 - -**参数** -- **path** (str): Word文件的位置,支持批量处理:填写文件夹位置 -- **output_path** (str, 可选): 转换后的输出位置,如果不存在会自动创建 - -**返回值** -- None - -**示例** -```python -office.word.docx2pdf(path='./word_files/', output_path='./pdf_results/') -``` - -### merge4docx -合并多个Docx文件为一个文件。 - -**参数** -- **input_path** (str): 输入文件的路径,可以是单个文件或文件夹路径 -- **output_path** (str): 输出合并后文件的路径 -- **new_word_name** (str, 可选): 合并后新文件的名称,默认为'merge4docx' - -**返回值** -- None - -**示例** -```python -office.word.merge4docx( - input_path='./待合并文档/', - output_path='./合并结果/', - new_word_name='年度报告' -) -``` - -### doc2docx -将Doc文件转换为Docx文件。 - -**参数** -- **input_path** (str): 输入Doc文件的路径 -- **output_path** (str, 可选): 输出Docx文件的路径,默认为当前目录 -- **output_name** (str, 可选): 输出Docx文件的名称,默认为原文件名 - -**返回值** -- None - -**示例** -```python -office.word.doc2docx( - input_path='./旧文档/报告.doc', - output_path='./新文档/', - output_name='更新报告.docx' -) -``` - -### docx2doc -将Docx文件转换为Doc文件。 - -**参数** -- **input_path** (str): 输入Docx文件的路径 -- **output_path** (str, 可选): 输出Doc文件的路径,默认为当前目录 -- **output_name** (str, 可选): 输出Doc文件的名称,默认为原文件名 - -**返回值** -- None - -**示例** -```python -office.word.docx2doc( - input_path='./新文档/报告.docx', - output_path='./旧格式/', - output_name='兼容报告.doc' -) -``` - -### docx4imgs -从Word里提取图片。 - -**参数** -- **word_path** (str): Word文档的路径 -- **img_path** (str): 提取图片的存储位置,会自动根据word名称,在指定文件夹下,生成一个子目录 - -**返回值** -- None - -**示例** -```python -office.word.docx4imgs(word_path='./文档/报告.docx', img_path='./提取图片/') -``` - -## 图片 API -图片API模块提供了图像处理功能,包括压缩、转换、添加水印等。 - -**节源** -- [office/api/image.py](file://office/api/image.py#L1-L153) - -### compress_image -压缩图像文件,以减小其文件大小,同时尽量保持视觉质量。 - -**参数** -- **input_file** (str): 需要压缩的输入图像文件的路径 -- **output_file** (str): 压缩后的图像文件保存路径 -- **quality** (int): 压缩质量等级,取值范围为0到95。数值越高,表示图像质量越好,但文件体积也越大 - -**返回值** -- None - -**示例** -```python -office.image.compress_image( - input_file='./原图/风景.jpg', - output_file='./压缩图/风景.jpg', - quality=75 -) -``` - -### image2gif -将图像转换为GIF格式。 - -**参数** -- 无 - -**返回值** -- None - -**示例** -```python -office.image.image2gif() -``` - -### add_watermark -给图片加水印。 - -**参数** -- **file** (str): 图片位置 -- **mark** (str): 水印内容 -- **output_path** (str, 可选): 输出位置,默认为当前目录 -- **color** (str, 可选): 水印颜色,默认为"#eaeaea" -- **size** (int, 可选): 水印大小,默认为30 -- **opacity** (float, 可选): 不透明度,0.01~1,默认为0.35 -- **space** (int, 可选): 水印间距,默认为200 -- **angle** (int, 可选): 水印角度,默认为30 - -**返回值** -- None - -**示例** -```python -office.image.add_watermark( - file='./图片/产品.jpg', - mark='公司名称', - output_path='./带水印/', - color="#808080", - size=40, - opacity=0.5, - space=150, - angle=45 -) -``` - -### img2Cartoon -将图片转换为卡通风格。 - -**参数** -- **path** (str): 图片文件的路径 -- **client_api** (str, 可选): 客户端的API密钥,默认值为'OVALewIvPyLmiNITnceIhrYf' -- **client_secret** (str, 可选): 客户端的密钥秘密,默认值为'rpBQH8WuXP4ldRQo5tbDkv3t0VgzwvCN' - -**返回值** -- None - -**示例** -```python -office.image.img2Cartoon( - path='./照片/人像.jpg', - client_api='your_api_key', - client_secret='your_secret_key' -) -``` - -### down4img -下载图片并保存到指定路径。 - -**参数** -- **url** (str): 图片的URL地址 -- **output_path** (str, 可选): 保存图片的路径,默认为当前目录 -- **output_name** (str, 可选): 保存图片时使用的文件名,默认为'down4img' -- **type** (str, 可选): 图片的文件类型,默认为'jpg' - -**返回值** -- None - -**示例** -```python -office.image.down4img( - url='https://example.com/image.jpg', - output_path='./下载图片/', - output_name='示例图片', - type='png' -) -``` - -### txt2wordcloud -根据指定的文本文件生成词云图像。 - -**参数** -- **filename** (str): 文本文件的路径 -- **color** (str, 可选): 词云的背景颜色,默认为"white" -- **result_file** (str, 可选): 生成的词云图像文件名,默认为"your_wordcloud.png" - -**返回值** -- None - -**示例** -```python -office.image.txt2wordcloud( - filename='./文本/文章.txt', - color="black", - result_file='词云图.png' -) -``` - -### pencil4img -使用pencil4img算法处理图像。 - -**参数** -- **input_img** (str): 输入的图像文件路径 -- **output_path** (str, 可选): 输出图像的路径,默认为当前目录 -- **output_name** (str, 可选): 转换后的图像文件名,默认为'pencil4img.jpg' - -**返回值** -- None - -**示例** -```python -office.image.pencil4img( - input_img='./图片/风景.jpg', - output_path='./铅笔画/', - output_name='艺术风景.jpg' -) -``` - -### decode_qrcode -解析二维码。 - -**参数** -- **qrcode_path** (str): 二维码图片的路径 - -**返回值** -- None - -**示例** -```python -office.image.decode_qrcode(qrcode_path='./二维码/链接.png') -``` - -### del_watermark -从输入的图片中删除水印,并保存处理后的图片到指定路径。 - -**参数** -- **input_image** (str): 输入图片的路径,这是需要进行水印删除处理的图片 -- **output_image** (str, 可选): 处理后图片的保存路径,默认为当前目录下的'del_water_mark.jpg' - -**返回值** -- None - -**示例** -```python -office.image.del_watermark( - input_image='./带水印/图片.jpg', - output_image='./去水印/图片.jpg' -) -``` - -## 工具 API -工具API模块提供了各种实用工具功能,包括翻译、二维码生成、密码生成等。 - -**节源** -- [office/api/tools.py](file://office/api/tools.py#L1-L146) - -### transtools -将内容从一种语言翻译为另一种语言。 - -**参数** -- **to_lang** (str): 目标语言 -- **content** (str): 待翻译的内容 -- **from_lang** (str, 可选): 源语言,默认为'zh'(中文) - -**返回值** -- str: 翻译后的结果 - -**示例** -```python -translated = office.tools.transtools(to_lang='en', content='你好,世界', from_lang='zh') -print(translated) # 输出: Hello, world -``` - -### qrcodetools -生成二维码图片。 - -**参数** -- **url** (str): 用于生成二维码的URL地址 -- **output** (str, 可选): 生成的二维码图片保存路径,默认为当前目录下的'./qrcode_img.png' - -**返回值** -- None - -**示例** -```python -office.tools.qrcodetools(url='https://www.python-office.com', output='./二维码/官网.png') -``` - -### passwordtools -生成一个指定长度的密码。 - -**参数** -- **len** (int, 可选): 密码长度,默认为8 - -**返回值** -- str: 生成的密码 - -**示例** -```python -password = office.tools.passwordtools(len=12) -print(password) # 输出: 生成的12位密码 -``` - -### weather -获取当前天气信息。 - -**参数** -- 无 - -**返回值** -- None - -**示例** -```python -office.tools.weather() -``` - -### url2ip -将URL转换为IP地址。 - -**参数** -- **url** (str): 需要转换的URL字符串 - -**返回值** -- str: 解析得到的IP地址字符串 - -**示例** -```python -ip = office.tools.url2ip(url='https://www.python-office.com') -print(ip) # 输出: 解析得到的IP地址 -``` - -### lottery8ticket -生成一张8位彩票号码。 - -**参数** -- 无 - -**返回值** -- None - -**示例** -```python -office.tools.lottery8ticket() -``` - -### create_article -创建文章。 - -**参数** -- **theme** (str): 文章的主题 -- **line_num** (int, 可选): 文章的行数,默认为200行 - -**返回值** -- None - -**示例** -```python -office.tools.create_article(theme='人工智能', line_num=100) -``` - -### pwd4wifi -生成WiFi密码列表。 - -**参数** -- **len_pwd** (int, 可选): 密码长度,默认为8 -- **pwd_list** (list, 可选): 密码列表,默认为空列表 - -**返回值** -- None - -**示例** -```python -office.tools.pwd4wifi(len_pwd=12, pwd_list=['company', 'office']) -``` - -### net_speed_test -网络速度测试函数。 - -**参数** -- 无 - -**返回值** -- None - -**示例** -```python -office.tools.net_speed_test() -``` - -### course -显示python-office库的相关信息和资源链接。 - -**参数** -- 无 - -**返回值** -- None - -**示例** -```python -office.tools.course() -``` - -## 文件 API -文件API模块提供了文件管理功能,包括批量重命名、文件搜索、目录整理等。 - -**节源** -- [office/api/file.py](file://office/api/file.py#L1-L163) - -### replace4filename -批量重命名:批量修改文件/文件夹名称。 - -**参数** -- **path** (str): 需要修改文件夹/文件名称的根目录,注意:该根目录名称不会被修改 -- **del_content** (str): 需要替换/删除的内容 -- **replace_content** (str, 可选): 替换后的内容,不填则实现删除效果 -- **dir_rename** (bool, 可选): 是否修改文件夹名称,默认:修改 -- **file_rename** (bool, 可选): 是否修改文件名称,默认:修改 -- **suffix** (str, 可选): 指定修改的文件类型,默认:所有 - -**返回值** -- None - -**示例** -```python -office.file.replace4filename( - path='./文档/', - del_content='旧名称', - replace_content='新名称', - dir_rename=True, - file_rename=True, - suffix='.txt' -) -``` - -### file_name_insert_content -批量重命名:在文件名中间插入字符。 - -**参数** -- **file_path** (str): 文件路径 -- **insert_position** (int): 插入位置 -- **insert_content** (str): 插入的内容 - -**返回值** -- None - -**示例** -```python -office.file.file_name_insert_content( - file_path='./文档/报告.txt', - insert_position=2, - insert_content='2023_' -) -``` - -### file_name_add_prefix -批量重命名:给文件名增加前缀。 - -**参数** -- **file_path** (str): 文件路径 -- **prefix_content** (str): 前缀内容 - -**返回值** -- None - -**示例** -```python -office.file.file_name_add_prefix( - file_path='./文档/报告.txt', - prefix_content='重要_' -) -``` - -### file_name_add_postfix -批量重命名:给文件名增加后缀。 - -**参数** -- **file_path** (str): 文件路径 -- **postfix_content** (str): 后缀内容 - -**返回值** -- None - -**示例** -```python -office.file.file_name_add_postfix( - file_path='./文档/报告.txt', - postfix_content='_最终版' -) -``` - -### output_file_list_to_excel -整理当前文件夹下的文件名,到一个Excel里。 - -**参数** -- **dir_path** (str): 目录路径 - -**返回值** -- None - -**示例** -```python -office.file.output_file_list_to_excel(dir_path='./项目文件/') -``` - -### add_line_by_type -根据类型添加行。 - -**参数** -- **add_line_dict** (dict): 添加行的字典 -- **file_path** (str): 文件路径 -- **file_type** (str, 可选): 文件类型,默认为'.py' -- **output_path** (str, 可选): 输出路径,默认为'add_line' - -**返回值** -- None - -**示例** -```python -add_dict = {'.py': '# coding: utf-8'} -office.file.add_line_by_type( - add_line_dict=add_dict, - file_path='./代码/', - file_type='.py', - output_path='./处理后代码/' -) -``` - -### search_specify_type_file -当前路径下,搜索指定类型的文件。 - -**参数** -- **file_path** (str): 文件路径 -- **file_type** (str): 文件类型 - -**返回值** -- None - -**示例** -```python -office.file.search_specify_type_file(file_path='./文档/', file_type='.pdf') -``` - -### group_by_name -按名称分组。 - -**参数** -- **path** (str): 路径 -- **output_path** (str, 可选): 输出路径 -- **del_old_file** (bool, 可选): 是否删除旧文件 - -**返回值** -- None - -**示例** -```python -office.file.group_by_name(path='./文件/', output_path='./分组结果/', del_old_file=False) -``` - -### get_files -搜索当前路径下,所有指定类型的文件,并以列表的形式返回。 - -**参数** -- **path** (str): 路径 -- **name** (str, 可选): 文件名 -- **suffix** (str, 可选): 文件后缀 -- **sub** (bool, 可选): 是否搜索子目录 -- **level** (int, 可选): 搜索层级 - -**返回值** -- list: 文件路径列表 - -**示例** -```python -files = office.file.get_files(path='./项目/', name='main', suffix='.py', sub=True, level=2) -print(files) # 输出: 找到的文件路径列表 -``` - -## 金融 API -金融API模块提供了金融计算功能,如股票交易收益计算。 - -**节源** -- [office/api/finance.py](file://office/api/finance.py#L1-L35) - -### t0 -计算做T的收益。 - -**参数** -- **buy_price** (float): 买入成本 -- **sale_price** (float): 卖出价格 -- **shares** (int): 单笔数量 -- **w_rate** (float, 可选): 手续费,默认万2.5 -- **min_rate** (int, 可选): 单笔最低手续费,默认5元 -- **stamp_tax** (float, 可选): 印花税,默认千1 - -**返回值** -- float: 做T后的收益金额 - -**示例** -```python -returns = office.finance.t0( - buy_price=11.99, - sale_price=12.26, - shares=700, - w_rate=2.5/10000, - min_rate=5, - stamp_tax=1/1000 -) -print(f"交易收益: {returns}元") -``` - -## OCR API -OCR API模块提供了光学字符识别功能,如发票信息提取。 - -**节源** -- [office/api/ocr.py](file://office/api/ocr.py#L1-L29) - -### VatInvoiceOCR2Excel -使用光学字符识别(OCR)技术将增值税发票信息提取并导出到Excel文件中。 - -**参数** -- **input_path** (str): 发票图片文件的路径或包含多个发票图片的文件夹路径 -- **output_path** (str, 可选): 输出Excel文件的文件夹路径,默认为当前目录 -- **output_excel** (str, 可选): 输出Excel文件的名称,默认为'VatInvoiceOCR2Excel.xlsx' -- **img_url** (str, 可选): 如果提供了input_path,则此参数将被忽略。用于指定网络发票图片的URL -- **id** (str, 可选): 百度OCR API的识别ID,如果在configPath中已配置,则不需要提供 -- **key** (str, 可选): 百度OCR API的密钥,如果在configPath中已配置,则不需要提供 -- **file_name** (bool, 可选): 是否使用图片文件名作为Sheet名称,默认为False -- **trans** (bool, 可选): 是否将识别结果翻译成英文,默认为False - -**返回值** -- None - -**示例** -```python -office.ocr.VatInvoiceOCR2Excel( - input_path='./发票图片/', - output_path='./发票结果/', - output_excel='发票汇总.xlsx', - id='your_baidu_ocr_id', - key='your_baidu_ocr_key', - file_name=True, - trans=False -) -``` - -## Markdown API -Markdown API模块提供了Markdown格式转换功能。 - -**节源** -- [office/api/markdown.py](file://office/api/markdown.py#L1-L21) - -### excel2markdown -将Excel文件转换为Markdown格式的文件。 - -**参数** -- **input_file** (str): 输入Excel文件的路径 -- **output_file** (str, 可选): 输出Markdown文件的路径,默认为当前目录下的'excel2markdown.md' -- **sheet_name** (str, 可选): 需要转换的Excel工作表名称,默认为None,表示转换所有工作表 - -**返回值** -- None - -**示例** -```python -office.markdown.excel2markdown( - input_file='数据表.xlsx', - output_file='数据表.md', - sheet_name='销售数据' -) -``` - -## PPT API -PPT API模块提供了PPT文件处理功能,包括格式转换、文件合并等。 - -**节源** -- [office/api/ppt.py](file://office/api/ppt.py#L1-L46) - -### ppt2pdf -PPT转换为PDF。 - -**参数** -- **path** (str): PPT文件路径 -- **output_path** (str, 可选): 输出PDF文件路径,默认为当前目录 - -**返回值** -- None - -**示例** -```python -office.ppt.ppt2pdf(path='./演示文稿/报告.pptx', output_path='./PDF版本/') -``` - -### ppt2img -PPT转图片,可以转为长图。 - -**参数** -- **input_path** (str): 存放PPT的位置,转换单个文件可以写文件的路径,转换文件夹可以写文件夹的路径 -- **output_path** (str, 可选): 结果图片的存储位置,默认为当前目录 -- **merge** (bool, 可选): True转为1张图片,False转为多张图片,默认为False - -**返回值** -- None - -**示例** -```python -office.ppt.ppt2img( - input_path='./演示文稿/报告.pptx', - output_path='./图片版本/', - merge=True -) -``` - -### merge4ppt -合并多个PPT文件。 - -**参数** -- **input_path** (str): 输入PPT文件路径 -- **output_path** (str, 可选): 输出PPT文件路径,默认为当前目录 -- **output_name** (str, 可选): 合并后的PPT文件名,默认为'merge4ppt.pptx' - -**返回值** -- None - -**示例** -```python -office.ppt.merge4ppt( - input_path='./待合并PPT/', - output_path='./合并结果/', - output_name='年度汇报.pptx' -) -``` - -## 视频 API -视频API模块提供了视频处理功能。 - -**节源** -- [office/api/video.py](file://office/api/video.py) - -### mark2video -视频加水印。 - -**参数** -- **video_path** (str): 视频文件路径 -- **mark_path** (str): 水印图片路径 -- **output_path** (str): 输出视频路径 - -**返回值** -- None - -**示例** -```python -office.video.mark2video( - video_path='./视频/宣传片.mp4', - mark_path='./水印/logo.png', - output_path='./加水印视频/' -) -``` - -## Web API -Web API模块提供了网页处理功能。 - -**节源** -- [office/api/web.py](file://office/api/web.py) - -### url2ip -将URL转换为IP地址。 - -**参数** -- **url** (str): 需要转换的URL - -**返回值** -- str: IP地址 - -**示例** -```python -ip = office.web.url2ip('https://www.python-office.com') -print(ip) -``` - -### web2pdf -将网页转换为PDF。 - -**参数** -- **url** (str): 网页URL -- **output_path** (str): 输出PDF路径 - -**返回值** -- None - -**示例** -```python -office.web.web2pdf( - url='https://www.python-office.com', - output_path='./网页PDF/官网.pdf' -) -``` - -## 测试API -测试API模块包含试验性功能,这些功能可能不稳定或正在开发中。 - -**节源** -- [office/api/testApi/ruiming.py](file://office/api/testApi/ruiming.py#L1-L19) - -### screen_unmarked_image -筛选未标记的图片。 - -**参数** -- **dir_path** (str): 目录路径 - -**返回值** -- None - -**示例** -```python -office.ruiming.screen_unmarked_image(dir_path='./图片集/') -``` - -### change_label_in_xml -修改XML文件中的标签。 - -**参数** -- **dir_path** (str): 目录路径 -- **old_label** (str): 旧标签名称 -- **new_label** (str): 新标签名称 - -**返回值** -- None - -**示例** -```python -office.ruiming.change_label_in_xml( - dir_path='./标注数据/', - old_label='person', - new_label='human' -) -``` - -### screen_without_label_json_file -筛选没有标签的JSON文件。 - -**参数** -- **dir_path** (str): 目录路径 - -**返回值** -- None - -**示例** -```python -office.ruiming.screen_without_label_json_file(dir_path='./JSON数据/') -``` \ No newline at end of file diff --git "a/.qoder/repowiki/zh/content/\345\256\211\350\243\205\346\214\207\345\215\227.md" "b/.qoder/repowiki/zh/content/\345\256\211\350\243\205\346\214\207\345\215\227.md" deleted file mode 100644 index 8438eca4..00000000 --- "a/.qoder/repowiki/zh/content/\345\256\211\350\243\205\346\214\207\345\215\227.md" +++ /dev/null @@ -1,658 +0,0 @@ -# 安装指南 - - -**本文档中引用的文件** -- [README.md](file://README.md) -- [setup.py](file://setup.py) -- [setup.cfg](file://setup.cfg) -- [settings.py](file://settings.py) -- [requirements.txt](file://contributors\old_from_gitee\bob-zhao\requirements.txt) -- [WordType.py](file://contributors\demo\WordType.py) -- [readme.md](file://examples\readme.md) -- [test_dev.py](file://tests\test_code\test_dev.py) -- [compatibility.py](file://office\compatibility.py) - - -## 目录 -1. [简介](#简介) -2. [系统要求](#系统要求) -3. [安装方法](#安装方法) -4. [环境准备](#环境准备) -5. [安装验证](#安装验证) -6. [常见问题与解决方案](#常见问题与解决方案) -7. [多平台托管说明](#多平台托管说明) -8. [源码安装](#源码安装) -9. [兼容性说明](#兼容性说明) -10. [故障排除指南](#故障排除指南) - -## 简介 - -python-office是一个功能强大的Python自动化办公第三方库,提供了超过100种办公自动化功能。该库采用模块化设计,支持一键安装和开箱即用,无需复杂的配置过程。 - -### 核心特性 -- **开箱即用**:每个功能只需一行代码 -- **模块化架构**:可按需选择功能模块 -- **跨平台支持**:支持Windows、Linux、macOS -- **丰富的功能**:涵盖Word、Excel、PDF、PPT、图片处理等多个办公场景 - -## 系统要求 - -### Python版本要求 -- **最低版本**:Python 3.6及以上 -- **推荐版本**:Python 3.8或更高版本 -- **兼容性**:支持Python 3.6+的所有主流操作系统 - -### 系统要求 -- **操作系统**:Windows 7+、Linux、macOS -- **内存**:至少512MB可用内存 -- **磁盘空间**:约100MB可用空间(取决于安装的模块) - -### 平台特定要求 -```mermaid -graph TD -A[系统检测] --> B{操作系统类型} -B --> |Windows| C[完整功能支持] -B --> |Linux/macOS| D[部分功能限制] -D --> E[需要额外依赖] -C --> F[所有模块可用] -E --> G[文档转换功能受限] -``` - -**图表来源** -- [compatibility.py](file://office\compatibility.py#L232-L250) - -## 安装方法 - -### 推荐安装命令 - -#### 使用阿里云镜像加速安装 -```bash -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U -``` - -#### 参数详解 -- `-i https://mirrors.aliyun.com/pypi/simple/`:指定阿里云PyPI镜像源,加速下载 -- `python-office`:目标安装包名称 -- `-U` 或 `--upgrade`:升级到最新版本 - -### 安装流程图 - -```mermaid -flowchart TD -Start([开始安装]) --> CheckPython{检查Python版本} -CheckPython --> |>= 3.6| CheckPIP{检查pip是否安装} -CheckPython --> |< 3.6| ErrorVersion[❌ 版本过低] -CheckPIP --> |已安装| SelectMirror[选择镜像源] -CheckPIP --> |未安装| InstallPIP[安装pip] -SelectMirror --> AliyunMirror[阿里云镜像加速] -AliyunMirror --> RunInstall[执行安装命令] -RunInstall --> InstallSuccess{安装成功?} -InstallSuccess --> |是| VerifyInstallation[验证安装] -InstallSuccess --> |否| CheckError[检查错误信息] -CheckError --> Troubleshoot[故障排除] -VerifyInstallation --> Complete([安装完成]) -InstallPIP --> SelectMirror -ErrorVersion --> UpgradePython[升级Python] -UpgradePython --> CheckPython -``` - -**图表来源** -- [setup.cfg](file://setup.cfg#L41-L45) - -### 详细安装步骤 - -#### 步骤1:验证Python环境 -```bash -python --version -# 或 -python3 --version -``` - -#### 步骤2:安装pip(如未安装) -```bash -# Windows -python -m ensurepip --upgrade - -# Linux/macOS -sudo apt-get install python3-pip # Ubuntu/Debian -brew install python3 # macOS -``` - -#### 步骤3:执行安装命令 -```bash -# 使用阿里云镜像 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U - -# 或使用默认PyPI源 -pip install python-office -U -``` - -## 环境准备 - -### Python环境配置 - -#### Windows环境 -1. **下载Python**:从[Python官网](https://www.python.org/downloads/)下载适合的版本 -2. **安装选项**:勾选"Add Python to PATH"选项 -3. **验证安装**: - ```cmd - python --version - pip --version - ``` - -#### Linux环境 -```bash -# Ubuntu/Debian -sudo apt update -sudo apt install python3 python3-pip python3-venv - -# CentOS/RHEL -sudo yum install python3 python3-pip - -# 验证 -python3 --version -pip3 --version -``` - -#### macOS环境 -```bash -# 使用Homebrew安装 -brew install python3 - -# 或从官网下载安装 -# 验证 -python3 --version -pip3 --version -``` - -### 虚拟环境创建(推荐) - -#### 创建虚拟环境 -```bash -# 创建虚拟环境 -python -m venv python-office-env - -# 激活虚拟环境 -# Windows -python-office-env\Scripts\activate - -# Linux/macOS -source python-office-env/bin/activate -``` - -#### 安装python-office -```bash -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U -``` - -## 安装验证 - -### 验证安装成功 - -#### 方法1:Python交互式验证 -```python -# 启动Python解释器 -python - -# 执行验证代码 ->>> import office ->>> print(f"python-office版本: {office.__version__}") ->>> print("安装成功!") -``` - -#### 方法2:脚本验证 -```python -# 创建验证脚本 -cat > verify_installation.py << 'EOF' -import office - -print(f"python-office版本: {office.__version__}") -print("功能模块列表:") -for module in dir(office): - if not module.startswith('_'): - print(f"- {module}") - -print("\n安装验证成功!") -EOF - -# 执行验证 -python verify_installation.py -``` - -#### 方法3:功能测试 -```python -# 测试基本功能 -try: - import office - print(f"✓ python-office {office.__version__} 安装成功") - print(f"✓ 总共包含 {len(dir(office))} 个功能模块") - print("✓ 可以正常使用python-office库") -except ImportError as e: - print(f"✗ 安装失败: {e}") -``` - -### 验证结果表格 - -| 验证项目 | 预期结果 | 说明 | -|---------|---------|------| -| Python版本 | 3.6+ | 确保满足最低要求 | -| pip可用性 | 成功安装 | 验证包管理工具 | -| 库导入 | 无错误 | 检查核心模块 | -| 版本信息 | 显示版本号 | 验证安装完整性 | -| 功能模块 | 显示模块列表 | 检查所有功能 | - -**章节来源** -- [test_dev.py](file://tests\test_code\test_dev.py#L1-L3) - -## 常见问题与解决方案 - -### 权限错误 - -#### 问题描述 -```bash -ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied -``` - -#### 解决方案 -```bash -# 方法1:使用管理员权限 -sudo pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U - -# 方法2:使用用户安装 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U --user - -# 方法3:使用虚拟环境 -python -m venv myenv -source myenv/bin/activate # Linux/macOS -myenv\Scripts\activate # Windows -pip install python-office -U -``` - -### 网络问题 - -#### 问题描述 -安装过程中出现超时或连接失败 - -#### 解决方案 -```bash -# 使用阿里云镜像 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U - -# 设置代理 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U \ - --proxy http://proxy.example.com:8080 - -# 设置超时时间 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U \ - --timeout 60 -``` - -### 依赖冲突 - -#### 问题描述 -安装过程中出现依赖版本冲突 - -#### 解决方案 -```bash -# 清理pip缓存 -pip cache purge - -# 强制重新安装 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U --force-reinstall - -# 使用约束文件 -pip install -r requirements.txt -``` - -### 版本兼容性问题 - -#### 问题描述 -某些功能在特定Python版本下不可用 - -#### 解决方案 -```bash -# 检查当前Python版本 -python --version - -# 升级到推荐版本 -# Windows: 从Python官网下载新版本 -# Linux: sudo apt install python3.8 -# macOS: brew upgrade python3 - -# 降级到兼容版本 -pip install python-office==1.0.5 -``` - -### 故障排除流程图 - -```mermaid -flowchart TD -InstallFail[安装失败] --> CheckError{检查错误类型} -CheckError --> |权限错误| FixPermission[修复权限问题] -CheckError --> |网络错误| FixNetwork[解决网络问题] -CheckError --> |依赖冲突| ResolveConflict[解决依赖冲突] -CheckError --> |版本问题| FixVersion[修复版本问题] -FixPermission --> TryAgain[重新安装] -FixNetwork --> TryAgain -ResolveConflict --> TryAgain -FixVersion --> TryAgain -TryAgain --> Success{安装成功?} -Success --> |是| Complete[安装完成] -Success --> |否| AdvancedTrouble[高级故障排除] -AdvancedTrouble --> CheckLogs[检查安装日志] -CheckLogs --> ContactSupport[联系技术支持] -``` - -## 多平台托管说明 - -### 项目托管平台 - -python-office项目在三个主要平台上进行托管,为用户提供多种访问和贡献方式: - -#### GitHub(主仓库) -- **URL**: https://github.com/CoderWanFeng/python-office -- **特点**: - - 最新的代码版本 - - 完整的Issue跟踪 - - Pull Request功能 - - 社区活跃度最高 - -#### Gitee(国内镜像) -- **URL**: https://gitee.com/CoderWanFeng/python-office -- **特点**: - - 国内访问速度快 - - 支持国内开发者 - - 提供中文界面 - -#### atomgit(企业级托管) -- **URL**: https://atomgit.com/CoderWanFeng1/python-office -- **特点**: - - 企业级托管服务 - - 更好的稳定性 - - 商业支持 - -### 平台对比表 - -| 平台 | 访问速度 | 社区活跃度 | Issue支持 | PR支持 | 备注 | -|------|---------|-----------|-----------|--------|------| -| GitHub | 快 | 高 | ✓ | ✓ | 主要平台 | -| Gitee | 快 | 中 | ✓ | ✓ | 国内镜像 | -| atomgit | 快 | 中 | ✓ | ✓ | 企业级托管 | - -### 贡献指南 - -#### 代码贡献流程 -```mermaid -sequenceDiagram -participant Dev as 开发者 -participant Fork as 分支仓库 -participant PR as Pull Request -participant Main as 主仓库 -Dev->>Fork : 1. Fork项目 -Dev->>Fork : 2. 创建功能分支 -Dev->>Fork : 3. 编写代码 -Dev->>PR : 4. 提交Pull Request -PR->>Main : 5. 代码审查 -Main->>Main : 6. 合并代码 -Main->>Dev : 7. 通知合并结果 -``` - -**图表来源** -- [README.md](file://README.md#L121-L126) - -#### 贡献规范 -- 在`contributors`文件夹中创建以GitHub用户名命名的文件夹 -- 将所有代码提交到自己的文件夹中 -- 不要修改其他文件夹中的代码 -- 对他人代码有疑问时直接提Issue - -**章节来源** -- [README.md](file://README.md#L121-L126) - -## 源码安装 - -### 从GitHub克隆安装 - -#### 步骤1:克隆仓库 -```bash -# 克隆主仓库 -git clone https://github.com/CoderWanFeng/python-office.git -cd python-office - -# 或克隆Gitee镜像 -git clone https://gitee.com/CoderWanFeng/python-office.git -cd python-office -``` - -#### 步骤2:安装依赖 -```bash -# 创建虚拟环境(推荐) -python -m venv venv -source venv/bin/activate # Linux/macOS -venv\Scripts\activate # Windows - -# 安装开发依赖 -pip install -r requirements.txt -pip install -e . -``` - -#### 步骤3:验证安装 -```python -import office -print(f"源码安装版本: {office.__version__}") -``` - -### 从压缩包安装 - -#### 下载源码 -```bash -# 下载最新Release -wget https://github.com/CoderWanFeng/python-office/archive/refs/tags/v1.0.6.zip -unzip v1.0.6.zip -cd python-office-1.0.6 -``` - -#### 安装过程 -```bash -# 使用setuptools安装 -python setup.py install - -# 或使用pip安装 -pip install . -``` - -### 开发模式安装 - -#### 设置开发环境 -```bash -# 克隆并进入项目目录 -git clone https://github.com/CoderWanFeng/python-office.git -cd python-office - -# 创建虚拟环境 -python -m venv dev-env -source dev-env/bin/activate # Linux/macOS -dev-env\Scripts\activate # Windows - -# 安装开发依赖 -pip install -r requirements.txt - -# 开发模式安装 -pip install -e . -``` - -#### 开发工作流 -```mermaid -flowchart LR -A[修改代码] --> B[测试功能] -B --> C{测试通过?} -C --> |是| D[提交代码] -C --> |否| E[修复问题] -E --> B -D --> F[Push到远程] -F --> G[CI/CD验证] -G --> H[发布新版本] -``` - -## 兼容性说明 - -### 平台兼容性矩阵 - -#### Windows平台 -- **完整支持**:所有功能模块 -- **依赖项**:Windows特定的第三方库 -- **性能**:最佳性能表现 - -#### Linux平台 -- **支持程度**:核心功能完整 -- **限制**:部分文档转换功能受限 -- **依赖**:需要安装额外的系统依赖 - -#### macOS平台 -- **支持程度**:核心功能完整 -- **限制**:部分GUI功能可能受限 -- **依赖**:需要安装Homebrew等包管理器 - -### 兼容性检测机制 - -```mermaid -classDiagram -class CrossPlatformCompatibility { -+is_first_run : bool -+mark_file : str -+display_warning() -+check_compatibility() -} -class CompatibilityChecker { -+system : str -+python_version : str -+modules_available : list -+generate_report() -} -CrossPlatformCompatibility --> CompatibilityChecker : uses -``` - -**图表来源** -- [compatibility.py](file://office\compatibility.py#L232-L250) - -### 兼容性警告系统 - -当在非Windows系统上首次导入python-office时,系统会自动显示兼容性警告: - -```python -# 自动触发兼容性检查 -import office - -# 警告信息示例: -""" -⚠️ 兼容性警告 -您正在非Windows系统上使用python-office库 - -主要功能: -✅ 基础办公功能 -✅ 文档处理 -✅ 数据操作 - -受限功能: -❌ Word文档转换 -❌ PPT处理 -❌ 部分GUI功能 - -建议: -1. 使用虚拟机运行Windows -2. 考虑使用在线转换服务 -3. 查看官方文档了解详细兼容性 -""" -``` - -**章节来源** -- [compatibility.py](file://office\compatibility.py#L232-L250) - -## 故障排除指南 - -### 常见安装问题诊断表 - -| 问题症状 | 可能原因 | 解决方案 | 验证方法 | -|---------|---------|---------|---------| -| Permission denied | 权限不足 | 使用sudo或--user参数 | 检查文件权限 | -| Connection timeout | 网络问题 | 使用镜像源或代理 | ping pypi.org | -| Version conflict | 依赖冲突 | 清理缓存,强制重装 | pip list | -| Module not found | 安装不完整 | 重新安装,检查路径 | python -c "import sys; print(sys.path)" | - -### 诊断工具 - -#### 系统信息收集 -```bash -# 收集系统信息 -python -c " -import platform -import sys -print('Python版本:', sys.version) -print('操作系统:', platform.platform()) -print('架构:', platform.machine()) -print('处理器:', platform.processor()) -" -``` - -#### 依赖检查 -```bash -# 检查已安装的python-office版本 -pip show python-office - -# 列出所有依赖 -pip list | grep -i office -``` - -#### 日志分析 -```bash -# 启用详细输出 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U -v - -# 查看安装日志 -pip debug --verbose -``` - -### 技术支持渠道 - -#### 官方支持 -- **GitHub Issues**: https://github.com/CoderWanFeng/python-office/issues -- **Gitee Issues**: https://gitee.com/CoderWanFeng/python-office/issues -- **atomgit Issues**: https://atomgit.com/CoderWanFeng1/python-office/issues - -#### 社区交流 -- **微信交流群**: 官网提供二维码 -- **B站视频教程**: 提供详细的安装和使用教程 -- **官网文档**: https://www.python-office.com/ - -### 升级和卸载 - -#### 升级到最新版本 -```bash -# 升级 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U - -# 指定版本升级 -pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office==1.0.7 -``` - -#### 卸载 -```bash -# 卸载python-office -pip uninstall python-office - -# 卸载所有相关包 -pip freeze | grep -i office | xargs pip uninstall -y -``` - -**章节来源** -- [README.md](file://README.md#L131-L134) - -## 结论 - -通过本指南,您应该能够成功在各种环境中安装和配置python-office库。建议: -1. 使用阿里云镜像加速安装 -2. 在虚拟环境中安装以避免依赖冲突 -3. 定期检查更新以获得最新功能 -4. 遵循兼容性指南以确保功能正常 - -如遇到无法解决的问题,请参考官方文档或联系技术支持团队。 \ No newline at end of file diff --git "a/.qoder/repowiki/zh/content/\351\241\271\347\233\256\346\246\202\350\277\260.md" "b/.qoder/repowiki/zh/content/\351\241\271\347\233\256\346\246\202\350\277\260.md" deleted file mode 100644 index b05059ec..00000000 --- "a/.qoder/repowiki/zh/content/\351\241\271\347\233\256\346\246\202\350\277\260.md" +++ /dev/null @@ -1,595 +0,0 @@ -# python-office项目概述 - - -**本文档引用的文件** -- [README.md](file://README.md) -- [office/__init__.py](file://office/__init__.py) -- [office/api/__init__.py](file://office/api/__init__.py) -- [office/api/excel.py](file://office/api/excel.py) -- [office/api/pdf.py](file://office/api/pdf.py) -- [office/api/email.py](file://office/api/email.py) -- [office/compatibility.py](file://office/compatibility.py) -- [setup.py](file://setup.py) -- [settings.py](file://settings.py) -- [examples/readme.md](file://examples/readme.md) -- [examples/poexcel/创建Excel文件.py](file://examples/poexcel/创建Excel文件.py) -- [examples/popdf/TXT转PDF.py](file://examples/popdf/TXT转PDF.py) -- [examples/poemail/发送邮件.py](file://examples/poemail/发送邮件.py) -- [gui/qtpy/version1/main.py](file://gui/qtpy/version1/main.py) - - -## 目录 -1. [项目简介](#项目简介) -2. [设计理念与核心价值](#设计理念与核心价值) -3. [项目架构设计](#项目架构设计) -4. [核心功能模块](#核心功能模块) -5. [技术架构与设计理念](#技术架构与设计理念) -6. [跨平台兼容性](#跨平台兼容性) -7. [实际应用场景](#实际应用场景) -8. [扩展性与集成潜力](#扩展性与集成潜力) -9. [项目特色与优势](#项目特色与优势) -10. [总结](#总结) - -## 项目简介 - -python-office是一个专为Python自动化办公场景设计的第三方库,致力于通过极简的一行代码调用实现复杂的办公任务自动化。该项目由程序员晚枫开发,旨在降低非专业编程人员的使用门槛,让职场人士能够快速实现办公效率的显著提升。 - -### 项目定位 -python-office定位于"开箱即用"的自动化办公解决方案,专注于解决大部分日常办公中的自动化需求。项目采用模块化设计,集成了文档处理、通信自动化、AI交互等多个领域的功能,形成了一个完整的办公自动化生态系统。 - -### 技术愿景 -项目的技术愿景是构建一个"集成文档处理、通信自动化、AI交互等多领域功能于一体"的综合办公平台,服务于职场效率提升。通过统一的API接口和简洁的调用方式,让复杂的办公任务变得简单易用。 - -**章节来源** -- [README.md](file://README.md#L47-L52) -- [office/__init__.py](file://office/__init__.py#L23-L30) - -## 设计理念与核心价值 - -### 极简主义设计哲学 - -python-office的核心设计理念是"极简编程,学习成本极低,工作效率提升显著"。这一理念体现在以下几个方面: - -#### 一行代码解决问题 -项目强调每个功能只需一行代码即可完成,无需用户具备深厚的Python编程知识。这种设计理念使得非技术人员也能轻松使用复杂的办公自动化功能。 - -```mermaid -flowchart TD -A["用户需求"] --> B["python-office库"] -B --> C["极简API调用"] -C --> D["自动完成任务"] -D --> E["高效办公成果"] -F["传统方法"] --> G["多行代码"] -G --> H["复杂配置"] -H --> I["长时间学习"] -I --> J["低效工作流程"] -K["python-office优势"] --> L["开箱即用"] -L --> M["贴合职场需求"] -M --> N["显著效率提升"] -``` - -**图表来源** -- [README.md](file://README.md#L59-L65) -- [examples/poexcel/创建Excel文件.py](file://examples/poexcel/创建Excel文件.py#L17-L18) - -#### 贴合职场需求 -项目功能设计紧密贴合职场办公的实际需求,涵盖了文档处理、邮件发送、文件管理等日常工作中的常见场景。这种设计确保了用户能够直接应用项目功能解决实际问题。 - -### 开放式生态建设 - -python-office不仅仅是一个单一的库,而是一个开放式的办公自动化生态系统。项目鼓励社区贡献,支持独立子库的发展,形成了一个相互协作的功能集合。 - -**章节来源** -- [README.md](file://README.md#L59-L65) -- [office/__init__.py](file://office/__init__.py#L23-L30) - -## 项目架构设计 - -### 模块化组织架构 - -python-office采用了清晰的模块化组织架构,通过`office/__init__.py`作为统一入口协调各个子模块的功能。 - -```mermaid -graph TB -subgraph "python-office核心架构" -A[office/__init__.py] --> B[兼容性检查模块] -A --> C[API模块集合] -C --> D[email.py - 邮件处理] -C --> E[excel.py - Excel处理] -C --> F[pdf.py - PDF处理] -C --> G[word.py - Word处理] -C --> H[image.py - 图片处理] -C --> I[file.py - 文件管理] -C --> J[tools.py - 工具函数] -K[兼容性检查] --> L[跨平台检测] -K --> M[功能支持评估] -K --> N[警告提示机制] -end -subgraph "独立子库" -O[PyOfficeRobot - 微信机器人] -P[poocr - OCR识别] -Q[popdf - PDF处理] -R[poemail - 邮件发送] -S[poimage - 图片处理] -T[poexcel - Excel处理] -end -A --> O -A --> P -A --> Q -A --> R -A --> S -A --> T -``` - -**图表来源** -- [office/__init__.py](file://office/__init__.py#L7-L21) -- [office/api/__init__.py](file://office/api/__init__.py#L1-L2) - -### 统一入口设计 - -`office/__init__.py`作为项目的统一入口,承担着以下重要职责: - -#### 兼容性检查机制 -项目在初始化时会自动执行兼容性检查,确保在不同操作系统上的功能可用性。这种设计避免了用户在使用过程中遇到平台相关的问题。 - -#### 模块导入协调 -通过统一的导入机制,用户可以选择: -- `import office`:导入所有功能模块 -- `from office import excel`:按需导入特定模块 -- 直接使用子模块:如`office.excel.fake2excel()` - -#### 版本管理 -项目通过`__version__`变量统一管理版本信息,便于用户了解当前使用的版本状态。 - -**章节来源** -- [office/__init__.py](file://office/__init__.py#L1-L30) -- [office/compatibility.py](file://office/compatibility.py#L227-L235) - -## 核心功能模块 - -### 文档处理模块 - -#### Excel处理功能 -Excel模块提供了丰富的数据处理功能,包括数据模拟、文件合并拆分、格式转换等核心功能。 - -```mermaid -classDiagram -class ExcelModule { -+fake2excel(columns, rows, path, language) -+merge2excel(dir_path, output_file) -+sheet2excel(file_path, output_path) -+find_excel_data(search_key, target_dir) -+split_excel_by_column(filepath, column, worksheet_name) -+excel2pdf(excel_path, pdf_path, sheet_id) -} -class ExcelFeatures { -<> -DATA_SIMULATION -FILE_MERGE_SPLIT -FORMAT_CONVERSION -CONTENT_SEARCH -PAGE_COUNTING -} -ExcelModule --> ExcelFeatures : implements -``` - -**图表来源** -- [office/api/excel.py](file://office/api/excel.py#L25-L137) - -#### PDF处理功能 -PDF模块涵盖了文档转换、加密解密、水印添加等完整的PDF处理流程。 - -```mermaid -sequenceDiagram -participant User as 用户 -participant PDFModule as PDF模块 -participant Converter as 转换引擎 -participant Output as 输出系统 -User->>PDFModule : 请求PDF处理 -PDFModule->>Converter : 调用转换引擎 -Converter->>Converter : 执行格式转换 -Converter->>Output : 生成处理结果 -Output->>User : 返回处理后的PDF -``` - -**图表来源** -- [office/api/pdf.py](file://office/api/pdf.py#L28-L200) - -#### Word处理功能 -Word模块提供了文档转换、合并等基本处理功能,支持常见的办公文档格式转换需求。 - -### 通信自动化模块 - -#### 邮件发送功能 -邮件模块实现了自动化的邮件发送功能,支持多种邮件协议和附件处理。 - -```mermaid -flowchart LR -A[邮件配置] --> B[内容准备] -B --> C[附件处理] -C --> D[SMTP连接] -D --> E[邮件发送] -E --> F[发送状态反馈] -G[安全性] --> H[SSL/TLS加密] -G --> I[身份验证] -G --> J[防垃圾邮件] -``` - -**图表来源** -- [office/api/email.py](file://office/api/email.py#L8-L45) - -### 文件管理模块 - -#### 文件操作功能 -文件管理模块提供了批量重命名、内容搜索、文件分类等实用功能,帮助用户高效管理大量文件。 - -#### 系统集成 -模块支持与操作系统深度集成,提供原生的文件操作体验。 - -**章节来源** -- [office/api/excel.py](file://office/api/excel.py#L1-L137) -- [office/api/pdf.py](file://office/api/pdf.py#L1-L200) -- [office/api/email.py](file://office/api/email.py#L1-L45) - -## 技术架构与设计理念 - -### 分层架构设计 - -python-office采用了清晰的分层架构设计,确保了系统的可维护性和扩展性: - -```mermaid -graph TD -subgraph "表现层" -A[命令行接口] -B[GUI界面] -C[Web接口] -end -subgraph "业务逻辑层" -D[API封装层] -E[功能模块层] -F[工具函数层] -end -subgraph "数据访问层" -G[第三方库集成] -H[文件系统操作] -I[网络通信] -end -subgraph "基础设施层" -J[兼容性检查] -K[错误处理] -L[日志记录] -end -A --> D -B --> D -C --> D -D --> E -E --> F -F --> G -F --> H -F --> I -E --> J -E --> K -E --> L -``` - -### 设计模式应用 - -#### 单例模式 -兼容性检查器采用单例模式,确保全局只有一个检查实例,避免重复的系统检测。 - -#### 策略模式 -不同平台的功能支持采用策略模式,根据系统特性选择最适合的实现方式。 - -#### 适配器模式 -通过适配器模式整合第三方库,为用户提供统一的API接口。 - -### 性能优化策略 - -#### 延迟加载 -模块采用延迟加载机制,只有在实际使用时才会加载相应的功能模块,提高了启动速度。 - -#### 缓存机制 -对于频繁使用的功能,实现了适当的缓存机制,减少重复计算和系统调用。 - -#### 资源管理 -合理管理内存和文件资源,避免长时间运行导致的资源泄漏。 - -**章节来源** -- [office/compatibility.py](file://office/compatibility.py#L14-L250) - -## 跨平台兼容性 - -### 兼容性检查机制 - -python-office实现了完善的跨平台兼容性检查机制,确保在不同操作系统上的功能可用性。 - -```mermaid -flowchart TD -A[系统检测] --> B{是否首次运行?} -B --> |是| C[显示兼容性提示] -B --> |否| D[跳过提示] -C --> E[Windows功能] -C --> F[Linux功能] -C --> G[macOS功能] -E --> H[完全支持] -F --> I[部分支持] -G --> I -H --> J[替代方案建议] -I --> J -J --> K[用户选择] -``` - -**图表来源** -- [office/compatibility.py](file://office/compatibility.py#L14-L250) - -### 平台特定功能 - -#### Windows平台 -- **完全支持**:Excel处理、PDF处理、图片处理、文件管理、邮件发送 -- **特殊功能**:PPT处理、Word处理、微信机器人、文件搜索 - -#### Linux平台 -- **完全支持**:大部分核心功能 -- **替代方案**:LibreOffice替代Microsoft Office功能 - -#### macOS平台 -- **完全支持**:核心功能 -- **替代方案**:Homebrew安装LibreOffice - -### 兼容性警告系统 - -项目实现了智能的兼容性警告系统,在用户首次使用非Windows系统时,会显示详细的兼容性信息和替代方案建议。 - -**章节来源** -- [office/compatibility.py](file://office/compatibility.py#L40-L250) - -## 实际应用场景 - -### 办公自动化场景 - -#### 数据处理自动化 -```python -# Excel数据处理示例 -import office - -# 批量生成模拟数据 -office.excel.fake2excel( - columns=['姓名', '部门', '职位', '入职日期'], - rows=100, - path='./员工信息.xlsx', - language='zh_CN' -) - -# 合并多个Excel文件 -office.excel.merge2excel('./data/', './合并后的员工信息.xlsx') - -# 根据条件筛选数据 -office.excel.find_excel_data('财务部', './data/') -``` - -#### 文档转换自动化 -```python -# PDF处理示例 -import office - -# 文本转PDF -office.pdf.txt2pdf( - input_file='./报告.txt', - output_file='./报告.pdf' -) - -# PDF加水印 -office.pdf.add_text_watermark( - input_file='./合同.pdf', - point=(100, 100), - text='机密文件', - output_file='./带水印合同.pdf' -) - -# PDF合并 -office.pdf.merge2pdf( - input_file_list=['./文档1.pdf', './文档2.pdf'], - output_file='./合并文档.pdf' -) -``` - -#### 通信自动化 -```python -# 邮件发送示例 -import office - -# 发送邮件 -office.email.send_email( - key='your_email_password', - msg_from='sender@example.com', - msg_to='recipient@example.com', - msg_subject='项目进度报告', - content='请查收最新的项目进展...', - attach_files=['./项目报告.pdf'] -) -``` - -### 行业应用案例 - -#### 企业行政管理 -- **人事管理**:批量生成员工信息、考勤统计 -- **文档管理**:合同归档、报告整理 -- **沟通协作**:批量邮件发送、会议通知 - -#### 财务审计 -- **报表处理**:Excel数据清洗、PDF报告生成 -- **凭证管理**:票据扫描、账目核对 -- **审计支持**:文档检索、数据统计 - -#### 市场营销 -- **客户管理**:批量数据处理、客户分析 -- **内容制作**:图文混排、格式转换 -- **渠道推广**:邮件群发、资料分发 - -**章节来源** -- [examples/poexcel/创建Excel文件.py](file://examples/poexcel/创建Excel文件.py#L17-L18) -- [examples/popdf/TXT转PDF.py](file://examples/popdf/TXT转PDF.py#L6-L7) -- [examples/poemail/发送邮件.py](file://examples/poemail/发送邮件.py#L10-L68) - -## 扩展性与集成潜力 - -### 插件化架构 - -python-office采用插件化架构设计,支持功能的动态扩展和模块化集成。 - -```mermaid -graph LR -subgraph "核心框架" -A[基础API] -B[兼容性管理] -C[错误处理] -end -subgraph "扩展模块" -D[新增功能1] -E[新增功能2] -F[第三方集成] -end -subgraph "集成接口" -G[Web API] -H[CLI工具] -I[GUI应用] -end -A --> D -A --> E -A --> F -B --> D -B --> E -B --> F -C --> D -C --> E -C --> F -D --> G -E --> H -F --> I -``` - -### 第三方集成能力 - -#### AI功能集成 -- **图像识别**:OCR文字识别、图像分类 -- **自然语言处理**:文本分析、语义理解 -- **机器学习**:数据挖掘、预测分析 - -#### 云服务集成 -- **文档服务**:云端存储、在线协作 -- **通信服务**:即时通讯、消息推送 -- **数据分析**:大数据处理、可视化 - -#### 硬件设备集成 -- **打印机**:文档打印、标签制作 -- **扫描仪**:文档扫描、图像处理 -- **移动设备**:移动端同步、远程控制 - -### 开发者友好特性 - -#### 清晰的API设计 -- **一致性**:统一的参数命名和返回格式 -- **完整性**:覆盖常用功能的完整API -- **易用性**:直观的方法命名和参数说明 - -#### 丰富的示例代码 -项目提供了大量的示例代码,涵盖各种使用场景,帮助开发者快速上手。 - -#### 完善的文档体系 -- **功能文档**:详细的API说明和使用指南 -- **视频教程**:直观的操作演示 -- **最佳实践**:行业应用案例和经验分享 - -**章节来源** -- [office/__init__.py](file://office/__init__.py#L1-L30) -- [examples/readme.md](file://examples/readme.md#L1-L338) - -## 项目特色与优势 - -### 技术特色 - -#### 1. 极简API设计 -- **一行代码**:复杂功能通过简单的API调用实现 -- **参数最少化**:合理的默认参数设置 -- **直观命名**:方法名称直接反映功能用途 - -#### 2. 智能兼容性管理 -- **自动检测**:运行时自动检测系统环境 -- **智能提示**:针对不同平台提供合适的建议 -- **无缝切换**:跨平台功能保持一致的使用体验 - -#### 3. 模块化架构 -- **功能分离**:不同功能模块独立开发和维护 -- **按需加载**:支持选择性功能导入 -- **易于扩展**:清晰的扩展点和插件机制 - -### 商业价值 - -#### 提升工作效率 -- **时间节省**:自动化处理重复性工作 -- **质量保证**:减少人为错误 -- **标准化**:统一的处理流程和格式 - -#### 降低学习成本 -- **零基础使用**:无需编程知识即可使用 -- **快速上手**:直观的API设计和丰富的示例 -- **持续学习**:完善的文档和社区支持 - -#### 促进数字化转型 -- **技术普及**:降低技术门槛,推动数字化应用 -- **流程优化**:标准化和自动化的办公流程 -- **创新应用**:为新的业务模式提供技术支持 - -### 社区生态 - -#### 开源协作 -- **透明开发**:完整的代码公开和版本管理 -- **社区参与**:鼓励用户贡献和反馈 -- **持续改进**:基于用户需求的功能迭代 - -#### 教育价值 -- **实践教学**:真实的项目案例和应用场景 -- **技能培养**:从入门到精通的学习路径 -- **职业发展**:提升职场竞争力的重要技能 - -**章节来源** -- [README.md](file://README.md#L47-L65) -- [office/__init__.py](file://office/__init__.py#L23-L30) - -## 总结 - -python-office作为一个专业的Python自动化办公解决方案,成功地将复杂的技术实现转化为简单易用的API接口。项目通过极简的设计理念、完善的兼容性管理和丰富的功能集合,为职场人士提供了一个强大的办公自动化工具。 - -### 核心成就 - -1. **技术突破**:实现了"一行代码解决复杂办公任务"的技术目标 -2. **用户体验**:创造了"开箱即用"的使用体验 -3. **生态建设**:构建了完整的办公自动化生态系统 -4. **社区影响**:推动了Python在办公自动化领域的应用普及 - -### 发展前景 - -python-office将继续朝着以下方向发展: -- **功能扩展**:持续增加新的办公自动化功能 -- **性能优化**:提升处理效率和系统稳定性 -- **生态完善**:加强与其他工具和平台的集成 -- **国际化**:支持更多语言和地区的需求 - -### 使用建议 - -对于初学者: -- 从简单的功能开始,逐步掌握复杂的自动化技巧 -- 参考项目提供的丰富示例和教程 -- 积极参与社区讨论,分享使用经验和解决方案 - -对于高级用户: -- 利用项目的扩展性,开发定制化的办公自动化解决方案 -- 参与项目贡献,推动功能的持续改进 -- 探索与其他技术栈的集成可能性 - -python-office不仅是一个技术工具,更是连接技术与实际需求的桥梁,为现代办公的数字化转型提供了强有力的支持。 - -**章节来源** -- [README.md](file://README.md#L1-L150) -- [office/__init__.py](file://office/__init__.py#L1-L30) -- [office/compatibility.py](file://office/compatibility.py#L1-L250) \ No newline at end of file diff --git a/.qoder/repowiki/zh/meta/repowiki-metadata.json b/.qoder/repowiki/zh/meta/repowiki-metadata.json deleted file mode 100644 index 2b6e9b32..00000000 --- a/.qoder/repowiki/zh/meta/repowiki-metadata.json +++ /dev/null @@ -1 +0,0 @@ -{"knowledge_relations":[{"id":1,"source_id":"1d8d82c2-01e7-4ba2-b939-d15e625944e1","target_id":"74ddfab0-572c-46b6-af92-3ef1d9c5573c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 1d8d82c2-01e7-4ba2-b939-d15e625944e1 -\u003e 74ddfab0-572c-46b6-af92-3ef1d9c5573c","gmt_create":"2025-11-26T21:45:03.9101901+08:00","gmt_modified":"2025-11-26T21:45:03.9101901+08:00"},{"id":2,"source_id":"1d8d82c2-01e7-4ba2-b939-d15e625944e1","target_id":"349c0d56-94da-4bb1-bba8-8615086bcfd3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 1d8d82c2-01e7-4ba2-b939-d15e625944e1 -\u003e 349c0d56-94da-4bb1-bba8-8615086bcfd3","gmt_create":"2025-11-26T21:45:03.9123086+08:00","gmt_modified":"2025-11-26T21:45:03.9123086+08:00"},{"id":3,"source_id":"1d8d82c2-01e7-4ba2-b939-d15e625944e1","target_id":"a77af545-9341-4685-ae85-964d0ba1e2bc","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 1d8d82c2-01e7-4ba2-b939-d15e625944e1 -\u003e a77af545-9341-4685-ae85-964d0ba1e2bc","gmt_create":"2025-11-26T21:45:03.9128232+08:00","gmt_modified":"2025-11-26T21:45:03.9128232+08:00"},{"id":4,"source_id":"1d8d82c2-01e7-4ba2-b939-d15e625944e1","target_id":"3dfa68b0-7f30-4b73-81f8-ffd6d9dd04ce","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 1d8d82c2-01e7-4ba2-b939-d15e625944e1 -\u003e 3dfa68b0-7f30-4b73-81f8-ffd6d9dd04ce","gmt_create":"2025-11-26T21:45:03.9133413+08:00","gmt_modified":"2025-11-26T21:45:03.9133413+08:00"},{"id":5,"source_id":"1d8d82c2-01e7-4ba2-b939-d15e625944e1","target_id":"4c71b51f-c6ab-41d4-8f35-0a15cb0a939e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 1d8d82c2-01e7-4ba2-b939-d15e625944e1 -\u003e 4c71b51f-c6ab-41d4-8f35-0a15cb0a939e","gmt_create":"2025-11-26T21:45:03.9133413+08:00","gmt_modified":"2025-11-26T21:45:03.9133413+08:00"},{"id":6,"source_id":"1d8d82c2-01e7-4ba2-b939-d15e625944e1","target_id":"fa7ca8f7-cd27-4744-9e3f-49126e86dba7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 1d8d82c2-01e7-4ba2-b939-d15e625944e1 -\u003e fa7ca8f7-cd27-4744-9e3f-49126e86dba7","gmt_create":"2025-11-26T21:45:03.9138583+08:00","gmt_modified":"2025-11-26T21:45:03.9138583+08:00"},{"id":7,"source_id":"56f91293-f6b9-4d28-b5f8-49debe410087","target_id":"c7ca23a2-0844-488a-8661-2977fcbce4e0","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 56f91293-f6b9-4d28-b5f8-49debe410087 -\u003e c7ca23a2-0844-488a-8661-2977fcbce4e0","gmt_create":"2025-11-26T21:45:03.9149098+08:00","gmt_modified":"2025-11-26T21:45:03.9149098+08:00"},{"id":8,"source_id":"56f91293-f6b9-4d28-b5f8-49debe410087","target_id":"c81359c0-6bff-4c28-94fe-e050557bc920","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 56f91293-f6b9-4d28-b5f8-49debe410087 -\u003e c81359c0-6bff-4c28-94fe-e050557bc920","gmt_create":"2025-11-26T21:45:03.9159839+08:00","gmt_modified":"2025-11-26T21:45:03.9159839+08:00"},{"id":9,"source_id":"56f91293-f6b9-4d28-b5f8-49debe410087","target_id":"f624fe10-99a5-4b5d-af4b-ab7830b4c10f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 56f91293-f6b9-4d28-b5f8-49debe410087 -\u003e f624fe10-99a5-4b5d-af4b-ab7830b4c10f","gmt_create":"2025-11-26T21:45:03.9165254+08:00","gmt_modified":"2025-11-26T21:45:03.9165254+08:00"},{"id":10,"source_id":"56f91293-f6b9-4d28-b5f8-49debe410087","target_id":"bdb13c92-a348-4dfa-8972-300c876e554a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 56f91293-f6b9-4d28-b5f8-49debe410087 -\u003e bdb13c92-a348-4dfa-8972-300c876e554a","gmt_create":"2025-11-26T21:45:03.9172315+08:00","gmt_modified":"2025-11-26T21:45:03.9172315+08:00"},{"id":11,"source_id":"56f91293-f6b9-4d28-b5f8-49debe410087","target_id":"08df5fec-89a7-4a0f-83ae-3bec3ef20c3c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 56f91293-f6b9-4d28-b5f8-49debe410087 -\u003e 08df5fec-89a7-4a0f-83ae-3bec3ef20c3c","gmt_create":"2025-11-26T21:45:03.9178457+08:00","gmt_modified":"2025-11-26T21:45:03.9178457+08:00"},{"id":12,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"dd9929a8-8e29-4c3e-8088-a60a1af13615","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e dd9929a8-8e29-4c3e-8088-a60a1af13615","gmt_create":"2025-11-26T21:45:03.9183749+08:00","gmt_modified":"2025-11-26T21:45:03.9183749+08:00"},{"id":13,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"f227d1b6-572f-48e9-b229-f0c199a7a12b","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e f227d1b6-572f-48e9-b229-f0c199a7a12b","gmt_create":"2025-11-26T21:45:03.9183749+08:00","gmt_modified":"2025-11-26T21:45:03.9183749+08:00"},{"id":14,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"c489fee6-73c4-4e7d-92a3-9b9ff7d8f832","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e c489fee6-73c4-4e7d-92a3-9b9ff7d8f832","gmt_create":"2025-11-26T21:45:03.9188962+08:00","gmt_modified":"2025-11-26T21:45:03.9188962+08:00"},{"id":15,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"ecddb2e4-0daa-4608-90da-10a79e0feb62","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e ecddb2e4-0daa-4608-90da-10a79e0feb62","gmt_create":"2025-11-26T21:45:03.91942+08:00","gmt_modified":"2025-11-26T21:45:03.91942+08:00"},{"id":16,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e 284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","gmt_create":"2025-11-26T21:45:03.9205691+08:00","gmt_modified":"2025-11-26T21:45:03.9205691+08:00"},{"id":17,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"e6fbcc68-971a-411c-afd8-679daa6dc933","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e e6fbcc68-971a-411c-afd8-679daa6dc933","gmt_create":"2025-11-26T21:45:03.9211071+08:00","gmt_modified":"2025-11-26T21:45:03.9211071+08:00"},{"id":18,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"ad5d0e45-2bf6-483a-933f-b63cb790ce04","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e ad5d0e45-2bf6-483a-933f-b63cb790ce04","gmt_create":"2025-11-26T21:45:03.9216426+08:00","gmt_modified":"2025-11-26T21:45:03.9216426+08:00"},{"id":19,"source_id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","target_id":"ad28dff9-75e2-49cb-ac4c-56f70245f922","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f735a428-9c4f-4cf5-89d6-a3d0bd795632 -\u003e ad28dff9-75e2-49cb-ac4c-56f70245f922","gmt_create":"2025-11-26T21:45:03.9216426+08:00","gmt_modified":"2025-11-26T21:45:03.9216426+08:00"},{"id":20,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"542a7d48-66f9-4805-b91a-519eb600f3c8","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 542a7d48-66f9-4805-b91a-519eb600f3c8","gmt_create":"2025-11-26T21:45:03.9221758+08:00","gmt_modified":"2025-11-26T21:45:03.9221758+08:00"},{"id":21,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"9ffcbc81-fcf6-4b7b-a8ca-cc42395e2be3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 9ffcbc81-fcf6-4b7b-a8ca-cc42395e2be3","gmt_create":"2025-11-26T21:45:03.922726+08:00","gmt_modified":"2025-11-26T21:45:03.922726+08:00"},{"id":22,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"b9479976-43d9-4248-8aa2-baea7fe52ebd","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e b9479976-43d9-4248-8aa2-baea7fe52ebd","gmt_create":"2025-11-26T21:45:03.9238129+08:00","gmt_modified":"2025-11-26T21:45:03.9238129+08:00"},{"id":23,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"cff11294-3efc-4dbf-8833-0f1dd156a57e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e cff11294-3efc-4dbf-8833-0f1dd156a57e","gmt_create":"2025-11-26T21:45:03.9238129+08:00","gmt_modified":"2025-11-26T21:45:03.9238129+08:00"},{"id":24,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"da354123-1637-4f00-a866-81d93caa95ce","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e da354123-1637-4f00-a866-81d93caa95ce","gmt_create":"2025-11-26T21:45:03.9243439+08:00","gmt_modified":"2025-11-26T21:45:03.9243439+08:00"},{"id":25,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"40155efe-3b03-47ba-a8f9-198b3e17d5b1","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 40155efe-3b03-47ba-a8f9-198b3e17d5b1","gmt_create":"2025-11-26T21:45:03.9243439+08:00","gmt_modified":"2025-11-26T21:45:03.9243439+08:00"},{"id":26,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"2c59b87f-ecef-4e59-b37a-ca9c4feb3279","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 2c59b87f-ecef-4e59-b37a-ca9c4feb3279","gmt_create":"2025-11-26T21:45:03.9258755+08:00","gmt_modified":"2025-11-26T21:45:03.9258755+08:00"},{"id":27,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"cc722f8f-49c2-4a6f-be4d-253f9086e8ca","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e cc722f8f-49c2-4a6f-be4d-253f9086e8ca","gmt_create":"2025-11-26T21:45:03.9258755+08:00","gmt_modified":"2025-11-26T21:45:03.9258755+08:00"},{"id":28,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"9dcfe98e-31e4-4f55-8900-901703d569d7","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 9dcfe98e-31e4-4f55-8900-901703d569d7","gmt_create":"2025-11-26T21:45:03.9268896+08:00","gmt_modified":"2025-11-26T21:45:03.9268896+08:00"},{"id":29,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"4c0924af-6db3-4bef-b62e-7957fa59a8fb","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 4c0924af-6db3-4bef-b62e-7957fa59a8fb","gmt_create":"2025-11-26T21:45:03.9268896+08:00","gmt_modified":"2025-11-26T21:45:03.9268896+08:00"},{"id":30,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"99b0e33a-3526-4eac-9dbe-fabb07369596","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 99b0e33a-3526-4eac-9dbe-fabb07369596","gmt_create":"2025-11-26T21:45:03.9279043+08:00","gmt_modified":"2025-11-26T21:45:03.9279043+08:00"},{"id":31,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"2a37ce53-23f7-4418-aaa9-db3f44030062","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 2a37ce53-23f7-4418-aaa9-db3f44030062","gmt_create":"2025-11-26T21:45:03.9279043+08:00","gmt_modified":"2025-11-26T21:45:03.9279043+08:00"},{"id":32,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"127e41c8-f873-4404-a905-7c8254dcd90f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 127e41c8-f873-4404-a905-7c8254dcd90f","gmt_create":"2025-11-26T21:45:03.9279043+08:00","gmt_modified":"2025-11-26T21:45:03.9279043+08:00"},{"id":33,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"3c93628f-739b-4d72-8697-ad459115df79","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e 3c93628f-739b-4d72-8697-ad459115df79","gmt_create":"2025-11-26T21:45:03.9289056+08:00","gmt_modified":"2025-11-26T21:45:03.9289056+08:00"},{"id":34,"source_id":"c659096c-e870-4a30-aedb-91afaa51e219","target_id":"daf94220-6f57-484d-867b-8387db839510","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c659096c-e870-4a30-aedb-91afaa51e219 -\u003e daf94220-6f57-484d-867b-8387db839510","gmt_create":"2025-11-26T21:45:03.9289056+08:00","gmt_modified":"2025-11-26T21:45:03.9289056+08:00"},{"id":35,"source_id":"74ddfab0-572c-46b6-af92-3ef1d9c5573c","target_id":"c2821340-8601-49c1-8361-e9b96efa63a6","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 74ddfab0-572c-46b6-af92-3ef1d9c5573c -\u003e c2821340-8601-49c1-8361-e9b96efa63a6","gmt_create":"2025-11-26T21:45:03.9304088+08:00","gmt_modified":"2025-11-26T21:45:03.9304088+08:00"},{"id":36,"source_id":"74ddfab0-572c-46b6-af92-3ef1d9c5573c","target_id":"b9eb55c9-fc40-44c4-8be7-2786f07c7f54","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 74ddfab0-572c-46b6-af92-3ef1d9c5573c -\u003e b9eb55c9-fc40-44c4-8be7-2786f07c7f54","gmt_create":"2025-11-26T21:45:03.9304088+08:00","gmt_modified":"2025-11-26T21:45:03.9304088+08:00"},{"id":37,"source_id":"74ddfab0-572c-46b6-af92-3ef1d9c5573c","target_id":"ca6668ef-402d-47a3-8877-8415bb3d3bae","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 74ddfab0-572c-46b6-af92-3ef1d9c5573c -\u003e ca6668ef-402d-47a3-8877-8415bb3d3bae","gmt_create":"2025-11-26T21:45:03.9314207+08:00","gmt_modified":"2025-11-26T21:45:03.9314207+08:00"},{"id":38,"source_id":"74ddfab0-572c-46b6-af92-3ef1d9c5573c","target_id":"bd5aacea-8d7e-4cc5-8758-c7129fc1390d","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 74ddfab0-572c-46b6-af92-3ef1d9c5573c -\u003e bd5aacea-8d7e-4cc5-8758-c7129fc1390d","gmt_create":"2025-11-26T21:45:03.9324252+08:00","gmt_modified":"2025-11-26T21:45:03.9324252+08:00"},{"id":39,"source_id":"c7ca23a2-0844-488a-8661-2977fcbce4e0","target_id":"1dfe4121-5d3e-44c3-8285-cfcb956ef9ef","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c7ca23a2-0844-488a-8661-2977fcbce4e0 -\u003e 1dfe4121-5d3e-44c3-8285-cfcb956ef9ef","gmt_create":"2025-11-26T21:45:03.9324252+08:00","gmt_modified":"2025-11-26T21:45:03.9324252+08:00"},{"id":40,"source_id":"c7ca23a2-0844-488a-8661-2977fcbce4e0","target_id":"a4570c89-1501-4477-b851-8661b4220a82","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c7ca23a2-0844-488a-8661-2977fcbce4e0 -\u003e a4570c89-1501-4477-b851-8661b4220a82","gmt_create":"2025-11-26T21:45:03.9334275+08:00","gmt_modified":"2025-11-26T21:45:03.9334275+08:00"},{"id":41,"source_id":"c7ca23a2-0844-488a-8661-2977fcbce4e0","target_id":"03a391b7-8863-44aa-84df-c270a407f459","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c7ca23a2-0844-488a-8661-2977fcbce4e0 -\u003e 03a391b7-8863-44aa-84df-c270a407f459","gmt_create":"2025-11-26T21:45:03.9334275+08:00","gmt_modified":"2025-11-26T21:45:03.9334275+08:00"},{"id":42,"source_id":"dd9929a8-8e29-4c3e-8088-a60a1af13615","target_id":"85ca43c5-dabf-466b-a687-3518c9caacba","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dd9929a8-8e29-4c3e-8088-a60a1af13615 -\u003e 85ca43c5-dabf-466b-a687-3518c9caacba","gmt_create":"2025-11-26T21:45:03.9344193+08:00","gmt_modified":"2025-11-26T21:45:03.9344193+08:00"},{"id":43,"source_id":"dd9929a8-8e29-4c3e-8088-a60a1af13615","target_id":"17415957-366b-4688-957a-62f158818037","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dd9929a8-8e29-4c3e-8088-a60a1af13615 -\u003e 17415957-366b-4688-957a-62f158818037","gmt_create":"2025-11-26T21:45:03.9344193+08:00","gmt_modified":"2025-11-26T21:45:03.9344193+08:00"},{"id":44,"source_id":"dd9929a8-8e29-4c3e-8088-a60a1af13615","target_id":"a3fb88da-78ec-479f-b655-720ec594a982","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dd9929a8-8e29-4c3e-8088-a60a1af13615 -\u003e a3fb88da-78ec-479f-b655-720ec594a982","gmt_create":"2025-11-26T21:45:03.9359295+08:00","gmt_modified":"2025-11-26T21:45:03.9359295+08:00"},{"id":45,"source_id":"dd9929a8-8e29-4c3e-8088-a60a1af13615","target_id":"3a56b7b2-ed16-4467-9c6a-7d0fe923c790","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dd9929a8-8e29-4c3e-8088-a60a1af13615 -\u003e 3a56b7b2-ed16-4467-9c6a-7d0fe923c790","gmt_create":"2025-11-26T21:45:03.9359295+08:00","gmt_modified":"2025-11-26T21:45:03.9359295+08:00"},{"id":46,"source_id":"c81359c0-6bff-4c28-94fe-e050557bc920","target_id":"41647d8f-357d-4645-b667-d1651f365121","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c81359c0-6bff-4c28-94fe-e050557bc920 -\u003e 41647d8f-357d-4645-b667-d1651f365121","gmt_create":"2025-11-26T21:45:03.9369317+08:00","gmt_modified":"2025-11-26T21:45:03.9369317+08:00"},{"id":47,"source_id":"c81359c0-6bff-4c28-94fe-e050557bc920","target_id":"1d6a15c4-c2f7-48b1-9432-f71d03a1fe8e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c81359c0-6bff-4c28-94fe-e050557bc920 -\u003e 1d6a15c4-c2f7-48b1-9432-f71d03a1fe8e","gmt_create":"2025-11-26T21:45:03.9369317+08:00","gmt_modified":"2025-11-26T21:45:03.9369317+08:00"},{"id":48,"source_id":"c81359c0-6bff-4c28-94fe-e050557bc920","target_id":"b818d801-231f-45d2-8598-103204f34bcc","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c81359c0-6bff-4c28-94fe-e050557bc920 -\u003e b818d801-231f-45d2-8598-103204f34bcc","gmt_create":"2025-11-26T21:45:03.9379316+08:00","gmt_modified":"2025-11-26T21:45:03.9379316+08:00"},{"id":49,"source_id":"f227d1b6-572f-48e9-b229-f0c199a7a12b","target_id":"aaa46704-cc2f-4250-b2a8-b97ea772c518","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f227d1b6-572f-48e9-b229-f0c199a7a12b -\u003e aaa46704-cc2f-4250-b2a8-b97ea772c518","gmt_create":"2025-11-26T21:45:03.9379316+08:00","gmt_modified":"2025-11-26T21:45:03.9379316+08:00"},{"id":50,"source_id":"f227d1b6-572f-48e9-b229-f0c199a7a12b","target_id":"d936a8e9-d2c4-429c-8b61-bb009a7264c6","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f227d1b6-572f-48e9-b229-f0c199a7a12b -\u003e d936a8e9-d2c4-429c-8b61-bb009a7264c6","gmt_create":"2025-11-26T21:45:03.9389309+08:00","gmt_modified":"2025-11-26T21:45:03.9389309+08:00"},{"id":51,"source_id":"f227d1b6-572f-48e9-b229-f0c199a7a12b","target_id":"dc9ef5a7-c78b-4995-b72f-027c9713d195","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f227d1b6-572f-48e9-b229-f0c199a7a12b -\u003e dc9ef5a7-c78b-4995-b72f-027c9713d195","gmt_create":"2025-11-26T21:45:03.9389309+08:00","gmt_modified":"2025-11-26T21:45:03.9389309+08:00"},{"id":52,"source_id":"f227d1b6-572f-48e9-b229-f0c199a7a12b","target_id":"9eb45266-5d6f-488e-acff-ef37fc792cba","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f227d1b6-572f-48e9-b229-f0c199a7a12b -\u003e 9eb45266-5d6f-488e-acff-ef37fc792cba","gmt_create":"2025-11-26T21:45:03.9389309+08:00","gmt_modified":"2025-11-26T21:45:03.9389309+08:00"},{"id":53,"source_id":"f227d1b6-572f-48e9-b229-f0c199a7a12b","target_id":"cb08505a-d31d-46cd-b836-a93d18a464b1","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: f227d1b6-572f-48e9-b229-f0c199a7a12b -\u003e cb08505a-d31d-46cd-b836-a93d18a464b1","gmt_create":"2025-11-26T21:45:03.9399313+08:00","gmt_modified":"2025-11-26T21:45:03.9399313+08:00"},{"id":54,"source_id":"a77af545-9341-4685-ae85-964d0ba1e2bc","target_id":"51e9c2f2-3dea-4422-9909-f7ffbc855032","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a77af545-9341-4685-ae85-964d0ba1e2bc -\u003e 51e9c2f2-3dea-4422-9909-f7ffbc855032","gmt_create":"2025-11-26T21:45:03.9399313+08:00","gmt_modified":"2025-11-26T21:45:03.9399313+08:00"},{"id":55,"source_id":"a77af545-9341-4685-ae85-964d0ba1e2bc","target_id":"d4781a43-4527-4e01-90f7-20dec2901739","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a77af545-9341-4685-ae85-964d0ba1e2bc -\u003e d4781a43-4527-4e01-90f7-20dec2901739","gmt_create":"2025-11-26T21:45:03.9409307+08:00","gmt_modified":"2025-11-26T21:45:03.9409307+08:00"},{"id":56,"source_id":"c489fee6-73c4-4e7d-92a3-9b9ff7d8f832","target_id":"2910f084-d37e-467a-8290-43ad6bb67a81","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c489fee6-73c4-4e7d-92a3-9b9ff7d8f832 -\u003e 2910f084-d37e-467a-8290-43ad6bb67a81","gmt_create":"2025-11-26T21:45:03.9409307+08:00","gmt_modified":"2025-11-26T21:45:03.9409307+08:00"},{"id":57,"source_id":"c489fee6-73c4-4e7d-92a3-9b9ff7d8f832","target_id":"10e09463-ae87-4160-a549-c41b043be8c9","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c489fee6-73c4-4e7d-92a3-9b9ff7d8f832 -\u003e 10e09463-ae87-4160-a549-c41b043be8c9","gmt_create":"2025-11-26T21:45:03.9409307+08:00","gmt_modified":"2025-11-26T21:45:03.9409307+08:00"},{"id":58,"source_id":"c489fee6-73c4-4e7d-92a3-9b9ff7d8f832","target_id":"e85972e1-0a2b-4105-8d30-2caec7de162a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c489fee6-73c4-4e7d-92a3-9b9ff7d8f832 -\u003e e85972e1-0a2b-4105-8d30-2caec7de162a","gmt_create":"2025-11-26T21:45:03.9419303+08:00","gmt_modified":"2025-11-26T21:45:03.9419303+08:00"},{"id":59,"source_id":"c489fee6-73c4-4e7d-92a3-9b9ff7d8f832","target_id":"322050f2-17da-4288-bde0-32add9481bfa","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c489fee6-73c4-4e7d-92a3-9b9ff7d8f832 -\u003e 322050f2-17da-4288-bde0-32add9481bfa","gmt_create":"2025-11-26T21:45:03.9429319+08:00","gmt_modified":"2025-11-26T21:45:03.9429319+08:00"},{"id":60,"source_id":"bdb13c92-a348-4dfa-8972-300c876e554a","target_id":"7202cd78-0156-4e66-b07e-19173c989ca2","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: bdb13c92-a348-4dfa-8972-300c876e554a -\u003e 7202cd78-0156-4e66-b07e-19173c989ca2","gmt_create":"2025-11-26T21:45:03.9429319+08:00","gmt_modified":"2025-11-26T21:45:03.9429319+08:00"},{"id":61,"source_id":"bdb13c92-a348-4dfa-8972-300c876e554a","target_id":"9a53bdb2-8e7f-46c8-9141-6bee7bc191f9","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: bdb13c92-a348-4dfa-8972-300c876e554a -\u003e 9a53bdb2-8e7f-46c8-9141-6bee7bc191f9","gmt_create":"2025-11-26T21:45:03.9429319+08:00","gmt_modified":"2025-11-26T21:45:03.9429319+08:00"},{"id":62,"source_id":"bdb13c92-a348-4dfa-8972-300c876e554a","target_id":"a7bdc95a-cab8-45cc-b6e7-bb58959459cb","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: bdb13c92-a348-4dfa-8972-300c876e554a -\u003e a7bdc95a-cab8-45cc-b6e7-bb58959459cb","gmt_create":"2025-11-26T21:45:03.9439315+08:00","gmt_modified":"2025-11-26T21:45:03.9439315+08:00"},{"id":63,"source_id":"bdb13c92-a348-4dfa-8972-300c876e554a","target_id":"c79f9e2c-4db3-4bd0-945c-cbb2f2e16692","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: bdb13c92-a348-4dfa-8972-300c876e554a -\u003e c79f9e2c-4db3-4bd0-945c-cbb2f2e16692","gmt_create":"2025-11-26T21:45:03.9439315+08:00","gmt_modified":"2025-11-26T21:45:03.9439315+08:00"},{"id":64,"source_id":"4c71b51f-c6ab-41d4-8f35-0a15cb0a939e","target_id":"a18ba16b-48e8-4beb-88d4-666167c3d5ae","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 4c71b51f-c6ab-41d4-8f35-0a15cb0a939e -\u003e a18ba16b-48e8-4beb-88d4-666167c3d5ae","gmt_create":"2025-11-26T21:45:03.9449312+08:00","gmt_modified":"2025-11-26T21:45:03.9449312+08:00"},{"id":65,"source_id":"4c71b51f-c6ab-41d4-8f35-0a15cb0a939e","target_id":"c85a941b-03d4-478f-ba4d-3eef6d640041","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 4c71b51f-c6ab-41d4-8f35-0a15cb0a939e -\u003e c85a941b-03d4-478f-ba4d-3eef6d640041","gmt_create":"2025-11-26T21:45:03.9459299+08:00","gmt_modified":"2025-11-26T21:45:03.9459299+08:00"},{"id":66,"source_id":"284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","target_id":"6769c917-c2ce-4da6-9ce4-08b0412eaf3c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 284c4a0a-1d3c-43ec-92f2-e9bb19659fd1 -\u003e 6769c917-c2ce-4da6-9ce4-08b0412eaf3c","gmt_create":"2025-11-26T21:45:03.9459299+08:00","gmt_modified":"2025-11-26T21:45:03.9459299+08:00"},{"id":67,"source_id":"284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","target_id":"3a81a86a-5c40-481b-99fb-288522713b05","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 284c4a0a-1d3c-43ec-92f2-e9bb19659fd1 -\u003e 3a81a86a-5c40-481b-99fb-288522713b05","gmt_create":"2025-11-26T21:45:03.9464352+08:00","gmt_modified":"2025-11-26T21:45:03.9464352+08:00"},{"id":68,"source_id":"284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","target_id":"3cd2e237-4eb0-41b8-8efe-1a3abd8ac6af","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 284c4a0a-1d3c-43ec-92f2-e9bb19659fd1 -\u003e 3cd2e237-4eb0-41b8-8efe-1a3abd8ac6af","gmt_create":"2025-11-26T21:45:03.9464352+08:00","gmt_modified":"2025-11-26T21:45:03.9464352+08:00"},{"id":69,"source_id":"284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","target_id":"c37ab3d7-a842-4e37-86c1-ae799ecaafa8","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 284c4a0a-1d3c-43ec-92f2-e9bb19659fd1 -\u003e c37ab3d7-a842-4e37-86c1-ae799ecaafa8","gmt_create":"2025-11-26T21:45:03.9464352+08:00","gmt_modified":"2025-11-26T21:45:03.9464352+08:00"},{"id":70,"source_id":"284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","target_id":"97f8451f-ca79-464f-a26d-0926992586e3","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 284c4a0a-1d3c-43ec-92f2-e9bb19659fd1 -\u003e 97f8451f-ca79-464f-a26d-0926992586e3","gmt_create":"2025-11-26T21:45:03.9474356+08:00","gmt_modified":"2025-11-26T21:45:03.9474356+08:00"},{"id":71,"source_id":"ad5d0e45-2bf6-483a-933f-b63cb790ce04","target_id":"edd09072-fa8b-447b-b71f-f5280c94be46","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ad5d0e45-2bf6-483a-933f-b63cb790ce04 -\u003e edd09072-fa8b-447b-b71f-f5280c94be46","gmt_create":"2025-11-26T21:45:03.9474356+08:00","gmt_modified":"2025-11-26T21:45:03.9474356+08:00"},{"id":72,"source_id":"ad5d0e45-2bf6-483a-933f-b63cb790ce04","target_id":"ca0244f3-0cff-4615-b150-2195b52dda45","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ad5d0e45-2bf6-483a-933f-b63cb790ce04 -\u003e ca0244f3-0cff-4615-b150-2195b52dda45","gmt_create":"2025-11-26T21:45:03.9484376+08:00","gmt_modified":"2025-11-26T21:45:03.9484376+08:00"},{"id":73,"source_id":"ad5d0e45-2bf6-483a-933f-b63cb790ce04","target_id":"01d96125-9660-42f9-af4a-61f61a18ca04","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ad5d0e45-2bf6-483a-933f-b63cb790ce04 -\u003e 01d96125-9660-42f9-af4a-61f61a18ca04","gmt_create":"2025-11-26T21:45:03.9494483+08:00","gmt_modified":"2025-11-26T21:45:03.9494483+08:00"},{"id":74,"source_id":"ad5d0e45-2bf6-483a-933f-b63cb790ce04","target_id":"1a271850-e715-4316-922b-941c8fd51f9f","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: ad5d0e45-2bf6-483a-933f-b63cb790ce04 -\u003e 1a271850-e715-4316-922b-941c8fd51f9f","gmt_create":"2025-11-26T21:45:03.9494483+08:00","gmt_modified":"2025-11-26T21:45:03.9494483+08:00"},{"id":75,"source_id":"7202cd78-0156-4e66-b07e-19173c989ca2","target_id":"3e54013b-34cc-4b99-892a-4dc18f5a2798","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7202cd78-0156-4e66-b07e-19173c989ca2 -\u003e 3e54013b-34cc-4b99-892a-4dc18f5a2798","gmt_create":"2025-11-26T21:45:03.9514398+08:00","gmt_modified":"2025-11-26T21:45:03.9514398+08:00"},{"id":76,"source_id":"7202cd78-0156-4e66-b07e-19173c989ca2","target_id":"885d983d-b21b-46e2-8226-15a7ab20608c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7202cd78-0156-4e66-b07e-19173c989ca2 -\u003e 885d983d-b21b-46e2-8226-15a7ab20608c","gmt_create":"2025-11-26T21:45:03.952438+08:00","gmt_modified":"2025-11-26T21:45:03.952438+08:00"},{"id":77,"source_id":"7202cd78-0156-4e66-b07e-19173c989ca2","target_id":"b476dd40-cb2b-40db-bc7a-32826c3af6a2","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7202cd78-0156-4e66-b07e-19173c989ca2 -\u003e b476dd40-cb2b-40db-bc7a-32826c3af6a2","gmt_create":"2025-11-26T21:45:03.952438+08:00","gmt_modified":"2025-11-26T21:45:03.952438+08:00"},{"id":78,"source_id":"7202cd78-0156-4e66-b07e-19173c989ca2","target_id":"ec3f17a6-41a7-4b4c-8c59-b2946b52c731","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 7202cd78-0156-4e66-b07e-19173c989ca2 -\u003e ec3f17a6-41a7-4b4c-8c59-b2946b52c731","gmt_create":"2025-11-26T21:45:03.952438+08:00","gmt_modified":"2025-11-26T21:45:03.952438+08:00"},{"id":79,"source_id":"a18ba16b-48e8-4beb-88d4-666167c3d5ae","target_id":"beed0ade-0995-419a-800f-79bb27c10f00","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a18ba16b-48e8-4beb-88d4-666167c3d5ae -\u003e beed0ade-0995-419a-800f-79bb27c10f00","gmt_create":"2025-11-26T21:45:03.9534385+08:00","gmt_modified":"2025-11-26T21:45:03.9534385+08:00"},{"id":80,"source_id":"a18ba16b-48e8-4beb-88d4-666167c3d5ae","target_id":"36d5887d-5c74-411f-b858-f25fe448afb0","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a18ba16b-48e8-4beb-88d4-666167c3d5ae -\u003e 36d5887d-5c74-411f-b858-f25fe448afb0","gmt_create":"2025-11-26T21:45:03.9534385+08:00","gmt_modified":"2025-11-26T21:45:03.9534385+08:00"},{"id":81,"source_id":"a4570c89-1501-4477-b851-8661b4220a82","target_id":"36093fae-b1c9-41c6-8ca8-dc09b2336df4","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a4570c89-1501-4477-b851-8661b4220a82 -\u003e 36093fae-b1c9-41c6-8ca8-dc09b2336df4","gmt_create":"2025-11-26T21:45:03.9544377+08:00","gmt_modified":"2025-11-26T21:45:03.9544377+08:00"},{"id":82,"source_id":"a4570c89-1501-4477-b851-8661b4220a82","target_id":"f45d5fa7-09ff-47a5-8766-2e361145755a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a4570c89-1501-4477-b851-8661b4220a82 -\u003e f45d5fa7-09ff-47a5-8766-2e361145755a","gmt_create":"2025-11-26T21:45:03.9554392+08:00","gmt_modified":"2025-11-26T21:45:03.9554392+08:00"},{"id":83,"source_id":"a4570c89-1501-4477-b851-8661b4220a82","target_id":"9042f44e-bbec-4f68-9de2-5d854a2ce824","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a4570c89-1501-4477-b851-8661b4220a82 -\u003e 9042f44e-bbec-4f68-9de2-5d854a2ce824","gmt_create":"2025-11-26T21:45:03.9554392+08:00","gmt_modified":"2025-11-26T21:45:03.9554392+08:00"},{"id":84,"source_id":"a4570c89-1501-4477-b851-8661b4220a82","target_id":"92fdb66a-658d-467c-b39b-ba25c1ec7463","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a4570c89-1501-4477-b851-8661b4220a82 -\u003e 92fdb66a-658d-467c-b39b-ba25c1ec7463","gmt_create":"2025-11-26T21:45:03.9554392+08:00","gmt_modified":"2025-11-26T21:45:03.9554392+08:00"},{"id":85,"source_id":"d4781a43-4527-4e01-90f7-20dec2901739","target_id":"d68488d0-413b-449f-8659-d4f7fa2281f5","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d4781a43-4527-4e01-90f7-20dec2901739 -\u003e d68488d0-413b-449f-8659-d4f7fa2281f5","gmt_create":"2025-11-26T21:45:03.9564378+08:00","gmt_modified":"2025-11-26T21:45:03.9564378+08:00"},{"id":86,"source_id":"d4781a43-4527-4e01-90f7-20dec2901739","target_id":"538de21d-090d-4cea-81c1-42d310d5d543","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d4781a43-4527-4e01-90f7-20dec2901739 -\u003e 538de21d-090d-4cea-81c1-42d310d5d543","gmt_create":"2025-11-26T21:45:03.9570209+08:00","gmt_modified":"2025-11-26T21:45:03.9570209+08:00"},{"id":87,"source_id":"d4781a43-4527-4e01-90f7-20dec2901739","target_id":"bed8df5a-dca4-423f-8d96-c77e3d66734b","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d4781a43-4527-4e01-90f7-20dec2901739 -\u003e bed8df5a-dca4-423f-8d96-c77e3d66734b","gmt_create":"2025-11-26T21:45:03.9570209+08:00","gmt_modified":"2025-11-26T21:45:03.9570209+08:00"},{"id":88,"source_id":"d4781a43-4527-4e01-90f7-20dec2901739","target_id":"775dd4d2-4bc0-464d-9d51-c076de51e905","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d4781a43-4527-4e01-90f7-20dec2901739 -\u003e 775dd4d2-4bc0-464d-9d51-c076de51e905","gmt_create":"2025-11-26T21:45:03.9575402+08:00","gmt_modified":"2025-11-26T21:45:03.9575402+08:00"},{"id":89,"source_id":"d4781a43-4527-4e01-90f7-20dec2901739","target_id":"d83bad12-fbbe-4a47-bd9b-77a98bb1a972","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d4781a43-4527-4e01-90f7-20dec2901739 -\u003e d83bad12-fbbe-4a47-bd9b-77a98bb1a972","gmt_create":"2025-11-26T21:45:03.9575402+08:00","gmt_modified":"2025-11-26T21:45:03.9575402+08:00"},{"id":90,"source_id":"d4781a43-4527-4e01-90f7-20dec2901739","target_id":"851254d3-f877-41fd-9cb0-0f1fa3a4794a","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d4781a43-4527-4e01-90f7-20dec2901739 -\u003e 851254d3-f877-41fd-9cb0-0f1fa3a4794a","gmt_create":"2025-11-26T21:45:03.9580607+08:00","gmt_modified":"2025-11-26T21:45:03.9580607+08:00"},{"id":91,"source_id":"d4781a43-4527-4e01-90f7-20dec2901739","target_id":"26d01094-d27a-4af8-93a6-5baeaaaf60d5","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d4781a43-4527-4e01-90f7-20dec2901739 -\u003e 26d01094-d27a-4af8-93a6-5baeaaaf60d5","gmt_create":"2025-11-26T21:45:03.9585784+08:00","gmt_modified":"2025-11-26T21:45:03.9585784+08:00"},{"id":92,"source_id":"9a53bdb2-8e7f-46c8-9141-6bee7bc191f9","target_id":"77a18b2a-2c18-4a70-814e-048c21e5ed5e","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 9a53bdb2-8e7f-46c8-9141-6bee7bc191f9 -\u003e 77a18b2a-2c18-4a70-814e-048c21e5ed5e","gmt_create":"2025-11-26T21:45:03.9591438+08:00","gmt_modified":"2025-11-26T21:45:03.9591438+08:00"},{"id":93,"source_id":"9a53bdb2-8e7f-46c8-9141-6bee7bc191f9","target_id":"7942c084-7600-4863-8db1-1ceea9483817","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 9a53bdb2-8e7f-46c8-9141-6bee7bc191f9 -\u003e 7942c084-7600-4863-8db1-1ceea9483817","gmt_create":"2025-11-26T21:45:03.9591438+08:00","gmt_modified":"2025-11-26T21:45:03.9591438+08:00"},{"id":94,"source_id":"17415957-366b-4688-957a-62f158818037","target_id":"4a6a1d4f-4733-4a3e-885d-541e6ba2d528","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 17415957-366b-4688-957a-62f158818037 -\u003e 4a6a1d4f-4733-4a3e-885d-541e6ba2d528","gmt_create":"2025-11-26T21:45:03.9597183+08:00","gmt_modified":"2025-11-26T21:45:03.9597183+08:00"},{"id":95,"source_id":"17415957-366b-4688-957a-62f158818037","target_id":"3a7c7ed0-842c-4596-9361-bb7178780087","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 17415957-366b-4688-957a-62f158818037 -\u003e 3a7c7ed0-842c-4596-9361-bb7178780087","gmt_create":"2025-11-26T21:45:03.9602769+08:00","gmt_modified":"2025-11-26T21:45:03.9602769+08:00"},{"id":96,"source_id":"17415957-366b-4688-957a-62f158818037","target_id":"2623150f-3ec1-4728-b010-a8dd733c231c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 17415957-366b-4688-957a-62f158818037 -\u003e 2623150f-3ec1-4728-b010-a8dd733c231c","gmt_create":"2025-11-26T21:45:03.9607978+08:00","gmt_modified":"2025-11-26T21:45:03.9607978+08:00"},{"id":97,"source_id":"d936a8e9-d2c4-429c-8b61-bb009a7264c6","target_id":"7eb2ae79-9ebf-40d6-b8e2-c88170d6b076","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d936a8e9-d2c4-429c-8b61-bb009a7264c6 -\u003e 7eb2ae79-9ebf-40d6-b8e2-c88170d6b076","gmt_create":"2025-11-26T21:45:03.9613393+08:00","gmt_modified":"2025-11-26T21:45:03.9613393+08:00"},{"id":98,"source_id":"d936a8e9-d2c4-429c-8b61-bb009a7264c6","target_id":"e2792a3e-a166-41bd-8caf-e81122ac0ab9","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: d936a8e9-d2c4-429c-8b61-bb009a7264c6 -\u003e e2792a3e-a166-41bd-8caf-e81122ac0ab9","gmt_create":"2025-11-26T21:45:03.9613393+08:00","gmt_modified":"2025-11-26T21:45:03.9613393+08:00"},{"id":99,"source_id":"10e09463-ae87-4160-a549-c41b043be8c9","target_id":"90eb969b-89e6-4606-8ce3-57f55f3ff20c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 10e09463-ae87-4160-a549-c41b043be8c9 -\u003e 90eb969b-89e6-4606-8ce3-57f55f3ff20c","gmt_create":"2025-11-26T21:45:03.9618591+08:00","gmt_modified":"2025-11-26T21:45:03.9618591+08:00"},{"id":100,"source_id":"10e09463-ae87-4160-a549-c41b043be8c9","target_id":"c462672b-5122-4d41-8955-9ac0a6e83766","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 10e09463-ae87-4160-a549-c41b043be8c9 -\u003e c462672b-5122-4d41-8955-9ac0a6e83766","gmt_create":"2025-11-26T21:45:03.9623824+08:00","gmt_modified":"2025-11-26T21:45:03.9623824+08:00"},{"id":101,"source_id":"10e09463-ae87-4160-a549-c41b043be8c9","target_id":"fc25ad4c-a5fa-4302-801f-872afeb1ebba","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: 10e09463-ae87-4160-a549-c41b043be8c9 -\u003e fc25ad4c-a5fa-4302-801f-872afeb1ebba","gmt_create":"2025-11-26T21:45:03.9629029+08:00","gmt_modified":"2025-11-26T21:45:03.9629029+08:00"},{"id":102,"source_id":"a7bdc95a-cab8-45cc-b6e7-bb58959459cb","target_id":"74f4d03f-01f4-4ba9-9c89-758a5f7caa13","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a7bdc95a-cab8-45cc-b6e7-bb58959459cb -\u003e 74f4d03f-01f4-4ba9-9c89-758a5f7caa13","gmt_create":"2025-11-26T21:45:03.9634562+08:00","gmt_modified":"2025-11-26T21:45:03.9634562+08:00"},{"id":103,"source_id":"a7bdc95a-cab8-45cc-b6e7-bb58959459cb","target_id":"609fd0ae-6729-47fa-848f-9a8ef77ac374","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a7bdc95a-cab8-45cc-b6e7-bb58959459cb -\u003e 609fd0ae-6729-47fa-848f-9a8ef77ac374","gmt_create":"2025-11-26T21:45:03.9639886+08:00","gmt_modified":"2025-11-26T21:45:03.9639886+08:00"},{"id":104,"source_id":"a7bdc95a-cab8-45cc-b6e7-bb58959459cb","target_id":"b0583f04-a370-484e-b6cc-6ce4ab1cf3c2","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: a7bdc95a-cab8-45cc-b6e7-bb58959459cb -\u003e b0583f04-a370-484e-b6cc-6ce4ab1cf3c2","gmt_create":"2025-11-26T21:45:03.9646115+08:00","gmt_modified":"2025-11-26T21:45:03.9646115+08:00"},{"id":105,"source_id":"dc9ef5a7-c78b-4995-b72f-027c9713d195","target_id":"128f3492-ff56-46fa-bea4-a3aed45201e6","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dc9ef5a7-c78b-4995-b72f-027c9713d195 -\u003e 128f3492-ff56-46fa-bea4-a3aed45201e6","gmt_create":"2025-11-26T21:45:03.9651439+08:00","gmt_modified":"2025-11-26T21:45:03.9651439+08:00"},{"id":106,"source_id":"dc9ef5a7-c78b-4995-b72f-027c9713d195","target_id":"0bd844e5-f677-4a06-a354-27e6b9c7f051","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: dc9ef5a7-c78b-4995-b72f-027c9713d195 -\u003e 0bd844e5-f677-4a06-a354-27e6b9c7f051","gmt_create":"2025-11-26T21:45:03.9656735+08:00","gmt_modified":"2025-11-26T21:45:03.9656735+08:00"},{"id":107,"source_id":"c79f9e2c-4db3-4bd0-945c-cbb2f2e16692","target_id":"96c5e080-e224-4793-a8ba-f89e86a69e6c","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c79f9e2c-4db3-4bd0-945c-cbb2f2e16692 -\u003e 96c5e080-e224-4793-a8ba-f89e86a69e6c","gmt_create":"2025-11-26T21:45:03.9667796+08:00","gmt_modified":"2025-11-26T21:45:03.9667796+08:00"},{"id":108,"source_id":"c79f9e2c-4db3-4bd0-945c-cbb2f2e16692","target_id":"41b0ecc1-6db5-4c08-809f-bc4186acbc2b","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c79f9e2c-4db3-4bd0-945c-cbb2f2e16692 -\u003e 41b0ecc1-6db5-4c08-809f-bc4186acbc2b","gmt_create":"2025-11-26T21:45:03.9673032+08:00","gmt_modified":"2025-11-26T21:45:03.9673032+08:00"},{"id":109,"source_id":"c79f9e2c-4db3-4bd0-945c-cbb2f2e16692","target_id":"5d154d33-563c-4faa-8cfb-f9a39e2049f6","source_type":"WIKI_ITEM","target_type":"WIKI_ITEM","relationship_type":"PARENT_CHILD","extra":"Wiki parent-child relationship: c79f9e2c-4db3-4bd0-945c-cbb2f2e16692 -\u003e 5d154d33-563c-4faa-8cfb-f9a39e2049f6","gmt_create":"2025-11-26T21:45:03.9678989+08:00","gmt_modified":"2025-11-26T21:45:03.9678989+08:00"}],"wiki_catalogs":[{"id":"0860412a-4350-4bf1-ba2b-fc95740fb0bd","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"项目概述","description":"project-overview","prompt":"创建关于python-office项目的全面内容,重点介绍其作为自动化办公解决方案的核心定位。解释该项目的设计理念:通过极简的一行代码调用实现复杂办公任务的自动化,降低非专业编程人员的使用门槛。阐述其架构设计原则,包括模块化组织、功能聚合与独立子库的平衡,以及`office/__init__.py`作为统一入口如何协调各子模块(如email、excel、pdf等)的导入与兼容性检查。详细说明项目的技术愿景,即集成文档处理、通信自动化、AI交互等多领域功能于一体,服务于职场效率提升。结合README中的特点描述(如开箱即用、贴合职场需求),提供实际应用场景的概述,并引用`__version__`和项目文档链接等元信息。同时,为初学者提供清晰的概念引导,为高级用户概述可扩展性和集成潜力。","progress_status":"completed","dependent_files":"README.md,office/__init__.py","gmt_create":"2025-11-26T20:50:26.6639909+08:00","gmt_modified":"2025-11-26T20:55:20.4046795+08:00","raw_data":"WikiEncrypted:0MI1/XkBoMl0lTbK6t0Cn/+8FdvqrJ62ianMLvZj02elJtBUgH0Ns0veIx1WPtM9wwkxI+/XAqHLxJLlHB8wV7ojrH0+b4JMz5OewwhBN1GhegUQu7Qozg2+RoFSHGJz1M36zgVcz3sjhUXqZi0E1w6pUdiZ4/WTxLystGe2wlMmbTpJNDOxsI+YUwjG3cTgcSK2m8LvyedxHTEW2xBhR3EZHvS5ewZQPgM6Knm9FGrCNgTcpfKuvdyN70TRyv10NZymeSESixkSJKmgq4y3yehWdtT0XZOrcNNThjBFy5/flxNpkbT9tnFpa9yhZ6InySH7bCzLaLt3GsqqT8DLP7MjqhiE8MFiNTDifXbQb3Crq5TYqEDqO3z6tAwoxZQ2OGPJ5Rva5tzFygSeJlkoURJ1dwVGdG14jV3rhqczhWBV2MAN2E4N92+TBbvFdDbHYMa5jGFAwSQDScvYaGiYCkjwd0mretY0v/V1VRALLEgRF7hODyQFnfp8Fy/Uocp3/uQFcHLzmMd28iMpPHdsHsVFi9a7MqoUsswj+sA7UBP8CIoFJ6KmpyyNVHjNSOXmjjtEbRg3Nxx1q0oKI2x5D5mdmb72a0jajQ+1darJmEBPf6FDJC+zHuS2x+9cheUJLSudUulaJDMDDhlvp4e+n01cXmupCE9V6FHfnWo8lKonmceokpqF1417YdOcpvsraqY4iXslIDSx7eAnWbEvEMeR7eYgy04Xp83WqVueN5wpI7JZp5E/JfeZ04He7v1IitqUlZcGqs/nBW3YA3+jqHMo1F4gj5GR3bSgjk1YzYPfgQTAklFaf7xKV2tnEvZ2Lnk6EjWFzk0YYDY+wD6O88IjoH6HhL+KOSsZINreRIZ0aLa70KaB0UqaWC2YK1a3tsIHaUub+B/TpzjpQIejwEf/83TmhY3HKtd/YvbEr+APZBRQTvyxzo5/l8kkkG4cY55G6DmnuAxgsb20OAiPmc5PO+LmsG4albbVscBBEGGskW0SR4i48Jn7CbbOBZmnLBbUro+pWzAaUVW9LIhIrzqlXYLZZHEtVUhPm+5CIfqBBj2ExAyg9E0JzO35hBpuVIZuZS/on83sMKoLbmOAW2AN9M2UOweArXYkJRRhO0G4+ULc0L9ms3XmtxePe7obC+4eemxXhlLd2nOPNJKCW+EMmFfvvJD81q5NTcVBjCbf3FqFCb5wxnU5dCAI7bnjEoFxSH4Y+A3QRR0BGKm1GmLaqRro81wMENDwtDM8LSukDCnVYsYVwjBI8te0MCbutLS+PBy6wCqWXkFcaFZwI2sor+Xc+VNCSiIe6T+z95htcHYsoiBWoQVQgOTyNkMwPCT9q9doMz5lSp50277JMR5nx+kN/tRCol/VEvsJ5J1+5Ttz0fOWo1M5Ai9JdzQpLgtSECkSkXzvAysJOq89gc1fF7BxoEXClMEVSx/7tOn2cTsIbFTKtKTAfNbPAqGXFn4Kzv3JMTFmfWZLu0vcrJWRXV3B430uNSyOWbNLOeVRI9zmF2KuZR24CMrtKpRtMHAioudKjiQCGScZHCgSGw=="},{"id":"b38da97e-0ae0-4dc5-8bdd-d53a1218c22a","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"GUI版本概览","description":"gui-version-overview","prompt":"编写关于python-office GUI各版本的概述文档,重点介绍version1、version2和version3的设计演进。说明version1基于基础QtPy实现,提供基本功能封装;version2采用Fluent Design风格,集成QFluentWidgets组件库,支持多语言和现代化UI;version3处于早期开发阶段,仅包含主入口文件。分析各版本的技术选型差异、用户体验改进以及向后兼容性策略。结合代码结构说明如何运行不同版本的GUI,并指导用户根据需求选择合适的版本。","parent_id":"bf12cfdb-30f2-4b0d-bc87-c1bd097570ef","progress_status":"completed","dependent_files":"gui/qtpy/version1/,gui/qtpy/version2/,gui/qtpy/version3/main.py","gmt_create":"2025-11-26T20:50:50.2950733+08:00","gmt_modified":"2025-11-26T20:59:25.723623+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwJegzPBRNRzlsYj/R9Gpc5SpKxH0xdxJtvHdOj8qbipqCo6UtoTjCbqqPtvq+B7kf2yiUZ8GJIniYJnWbRVNYXk6QdFyJkZlXiwqs2j7SOV4gQ4uEoOWCcjqMrTgEzMP+bynMUFEoyiD8+p3OfmXh6pVuQe2BnDxxxR9/mNvNorTqSDmB/B6reQkrg5JWNUw+DlQJ5jKKGSYyVxdq0SSskcT3hDADAG0sHU41/5KdqlBIAtMZv+SelTnSUTAsRxTZZkm2yYwM7MeKSRkxQ3aE3+8JKV3gjX3oTsuqWWSXNUUyn54+l5jmxAapQNnmcXgYkKcozW6tSvIi2P/pwPOvuP43oGGtNOc86spsRJGcdvFg5zUaAY7EYbgGEdFS5avPRwLQmylnA7RdqNzUl9q9EiymkAzFOYawm9/XZDWmL/GjWYOqcd1xhhkCNhuTGTr3oWQg7Iy0ok0KnP+JI86BpZiDRvpi7/ofanozF/ouSzqUkqc/llsvktHmgjtQ6ghiRIul8Hagcv3uwcIHKPehG53UU5bTrBljJGg2DOp1FNPz7ZaqJDyR6p0V/GUUV5hB23kD1yiZ85NebuSxqIAad30nNTaEYL1ZR1CNGDCrLvnJSb0k6t7jImOvm9omAoZNGlCvQkY/TCMmpx310CFMltgp/Mb4lrjzhHmPE9hYtdQZ5uTw1dEb1WLXf9wmVPIIJSC4zVeWZO/d5xUouygqOmS//mTfQKTba9yQvmYDDWv/P1xltKFOK2faPwVMVlRL6H6aMk6LsBTUwey/XQfB0SPTRCoh1iKQE/49Ccvg7xX9gzh/R6eQiMn2KAahUfRNDBAsJP0ETHUgc6LMmh7jliVwjoo/8fK52MQXffXl6TyYUOcbMtyEBKyZRBlg5zBZoHdGy9acbmSGYrV0kK3ZFhTjMDixJPnc4Lwt0sDmGxht/O8PVT/o2a1MMh6k8xpB2tr9BCJ0nuuDHEQ/z5jJJL8oer1vO7e0zzjAuZeQ3GtfjMbfaAPPTTQxwEB1ITd8armMdzajlou3q54IJUuJTsyTJHMdkpJXluwPuc/VhYU9HE7aLrXGFBjNLh7lCBZizCw5Sq9zru6FuUvWII6NjurbHFRH07y+X096yl3qE30","layer_level":1},{"id":"f7bcfd40-cf6d-413a-b3fa-59f8cc0f5a06","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文档处理","description":"document-processing","prompt":"创建关于文档处理功能的详细文档,涵盖Excel、Word、PDF、PPT四类办公文档的自动化操作。解释每个模块(excel.py、word.py、pdf.py、ppt.py)提供的核心功能,如文件创建、格式转换、内容读写、合并加密等。结合examples/中的实际脚本(如Excel转PDF.py、合并PDF.py)展示典型使用场景。说明各模块之间的共性设计模式,如统一的输入输出参数规范和异常处理机制。提供代码示例演示如何调用API完成常见任务,并指出性能优化建议(如批量处理大文件时的内存管理)。文档需为初学者提供清晰的操作路径,同时为高级用户提供扩展接口的使用指导。","parent_id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","progress_status":"completed","dependent_files":"office/api/excel.py,office/api/word.py,office/api/pdf.py,office/api/ppt.py,examples/poexcel/,examples/poword/,examples/popdf/,examples/poppt/","gmt_create":"2025-11-26T20:50:56.4183222+08:00","gmt_modified":"2025-11-26T20:59:01.7148554+08:00","raw_data":"WikiEncrypted:UrGmrKxrZ1JTrlkVwQ+kaRsXTTYYtmd+vLRWggiy+fYU7Pz5P8ZihSfmss/rl4l1SE6HlBfchfqovCoS9EnM5aDydwpe8vkBXELfsi0S07n0QdV9SJSV0TFt19ijiRbZKOYPnM/N/wX85TyGP6C/GZHYDKEbAVmaYGSpe2AgKH4gtjC717MxlgTkHK8zRJtR2xnxuklVR51MNKsQf5fbFv2gvSo89uO6gJdvVcmPVHAT0F1EAclDBhsBaDe8XX+iTTPtsy+dmSU5fWrWfeTbwidGL4tifXufB2qLQUVLLUG0aCrkdm7+Y+ICB1BNbTsYo9HGHkgzgLfakdjLrRllSCf5sPKyi8e1FtwDOhJXPYNfneIOTkm6MPjPoSamtzxB6KpJGTAT85ENLdkK3ft1bF+yjO9ZyO3uJvzkhvBrsZqEjhCPI7UzqOF8hXD6SERRBuW8AirRic/YwYOxVKX0XyK0bbdII9FBy0v9jMi1gL+NKYH5wFubb/QPP6rx6M0geHTEd4g77QLYrFWZnOeKMMdVSQH9HwfnYWP3oygNHPs5RA9w55EU4LsrANZEXGs25yF2WwdoXPx+zHdTt3dii7guE9WQRrAzKHnuF28UrBSCli5Fro+k2o+T1K4pA+lAvl3EEhUAcAT0znuafhEF1zPmJLrpbdezPYb5iAIT7GHxe/hW602R9tRlzWadZv5xdXgKKItQWJEldiL64NIT3cPhs5SRpymhxFM9GD2oOEXFlhaUFeb3aVWCNg8h/MId8DORq0Zn6hr4yJtl3r9xLF1G3VT7EnJJ+QDqfnta1r4DXL5Ah79ZpLD1ukBVAePx8nMQqAXO+BkR1JUkZq1HvRTI4V5W5iO4Z4d12DVj0R3tB+asKkGKLyHbuwOB1C3e8JiNTfXqWfpPCMndYewCLgCie68rfJPIa/S0ZMJyqs825GjoJGiIVrrLS4LYcnt+eP/69RxhLNT8ydKIiMeg+oAqzAqWKMDspS9QtbgrMFCWdT17kTkFxTgzLN+EPbrJE2P9qE9Lt0PRygKzjY6Em8j7k1gSv2+20wlQi4NUn9RzFgb/OO4X1BacbyxyaqAwwLB6esveK0/Zyi/MgObVxsoPRwE6CMJj/1Ffxd5qhFA4njWVOVwcWfTtqN4LjwuHTGdHpMIaxtHvx3KhSlGmljRKfQ3xevOkNOPYscT8n45uEI4C7EWtAMIBoqR2RCuzaIwRyLAw6DI87iYbaif0RBzx61DsAAkLDaEGzgxBytP5yFx2bOBKDx7EV9w1odrAxejhoOEKF712QaJ1PYi6Jg/ljtIeOLt6onHiE+GZd5yCq0SYyY+2qbMCd94KuY6lMS3M8ixhFmLqL0JUCl8/C0TEKdUGeTGwylrGn6p7G01ps1Hu0XwFceY40HYDThUJrw1b+OQx7qw9hcwKyfqDKkdVgtmPlibleNfoosQQGq1X3PnS4WQDZohywwO5BHAKgPL7whwYTd87jJqE7T/HrZYNq0MdgE+a6NGY4y+5sWz+SjLpt2eR5Q6JKIxtagyb7m717XegMzfxodECGz65Dk/+3R44KWHs0lXCllqgPA/6dbO5f0FaZaAlfN/543Pn","layer_level":1},{"id":"e751e9d9-3ee0-40ee-b1dd-bc751c843370","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Version1 概述","description":"gui-version1-overview","prompt":"编写关于python-office GUI Version1的详细技术文档,重点介绍其基于基础QtPy框架构建的桌面应用架构。说明main.py作为启动入口的角色,FinalWidget.py实现核心功能逻辑,ui_Widget.py由Qt Designer生成的UI布局文件。分析该版本如何封装基础办公自动化功能,实现简单直观的操作界面。提供运行环境配置说明、依赖安装步骤及启动方法。结合代码示例解释信号与槽机制的基本实现方式,并指出其在用户体验和可扩展性方面的局限性,为后续版本演进提供对比基础。","parent_id":"b38da97e-0ae0-4dc5-8bdd-d53a1218c22a","progress_status":"completed","dependent_files":"gui/qtpy/version1/main.py,gui/qtpy/version1/customizeWindowPyfile/FinalWidget.py,gui/qtpy/version1/customizeWindowPyfile/ui/ui_Widget.py,gui/qtpy/version1/requirements.txt","gmt_create":"2025-11-26T20:51:13.5129005+08:00","gmt_modified":"2025-11-26T21:13:11.6997137+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwNqc2gWEsv++WPkxX2qkEzNJ9K6BMEWxgITsDlRIyLzfZ0xSnPF1V3B5SGVzyAb3504V7hxwtpTtEE1ke3VHfSJwRKciRqUUn6a1gj+Iw+6USMVvsA31KXrbrVka6h66Ok2e99HW8QNBvrfnaz1iH7lHvZ0VoEifsE0Ju9D26Q2t/i4k8CvMLKg2oGB9CDj+xtT0DoAQZ1jfe+aImv1Zvao+QnbGIAGnxMjWIMENNv95nnMg3YoD3D/GFmQSElwRRQ5MuieLSjk14XoI/1wsmtLI0mBbZslmNxJU9wykobqm20LjwSrfokd5TkNixatzjp1Sm3SK8Nd7Z/9qsROUSh10AobquBL3ayVMOcT3vyRR5VRG7eOaJ8LAu4p5AVJPABLvqmk/inJw5+3CBWWZl8ZohqjoSWP6Z62ipncjQJ56fRyfqU6iqpoasihPdP8faCRwJMHhq5GVKQW/LFMOSvusaeFlDNxGerYjcKHBXjKdMKEkzUXy/gUmONMxMh3YkaXtEgnIZXzU7IcqxZ9UWgH8cDrO83UcUzm9kDcTUB/NzEJgpSZgn7htc3PfGzxgpxexv1kOC1qWc/IjZmOYtLy6rEcY8+x/dPISEkd5jfT4/s6owmII749YGyl5aECWPRQroBX42DM5KyF1I24SQxQMkeAbdeZFU8oKy/OoxZHGyGZvtIVk+olVc4GWMWYCIzD1qkM9MlsY3Xg5h1M7PXsZnlf+km/EbatsbXEiH8zie5rXrxCNb6qF4hzCsAdZGQsgGL1QIjMpOacCA10D82p3dwaw/TcLe4H1JuMl6Gj7sg/lBfwSF9XvPxTY2aCCA9N4NQLWsDJLxirCOKDfrLLYWkugKiDkq+gILEb/4nlPo4gWT9k/Rykix4pLQc9b5kVJdJV8qzWQCfu+NVCfCpr3twrfPJGHCRBIiYmFBIZnh40ToYI7wULMjajXu48Zxy65NPh+Ym4g0HQxhu2oZkqAtgEpzysNUXP7QoZXGAM4af0fHp3+OUFn3xfNzr1ujsrZH3OQge0ZVBC9BYSsSsqF6y1fd1RCsUT6YMDH61WbOfRWVfeXDugscl8hniX7JrOa66iFJ6iJf9vuopoK06uMc+Orb7goaaKnPeAaCAhiX8ljMhDMdeIYFEuM19YsRXufuVm6mabtY7hiHsuMLMFzNfpJ0BZ+OIKyv7rHCf6a+WNA9KWQ41QI6vHpKmlpbs/uINOMiVZ4egfRL9v8VNSxUB16T/TF3BEBWhLcDQVXGh1ZwZUI+4mkTl15U4T1MbMJnEA4mw3hcULn/um9ebkx4S4MD3ZiGqGrwwR0CdswbZqYTvDi/sc5IvrcDKdZGw==","layer_level":2},{"id":"e957a9d9-adcd-48e2-a36e-b2b4beae2ddf","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"邮件API","description":"api-reference-email","prompt":"创建详尽的邮件API文档,聚焦于office.api.email模块。详细说明send函数的参数,包括sender_email、password、receiver_email、subject、content、smtp_server、smtp_port、is_ssl、attachment_path等,解释其类型、默认值和作用。提供纯文本邮件、HTML邮件以及带附件邮件的完整调用示例。解释SMTP服务器配置逻辑,包括对主流邮箱(如QQ、163、Gmail)的支持。结合代码实现,说明异常处理机制(如登录失败、网络错误)。指导用户如何安全地管理邮箱密码,推荐使用环境变量。说明该模块与`office/__init__.py`的集成方式,确保用户理解`office.email.send()`的调用路径。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","progress_status":"completed","dependent_files":"office/api/email.py","gmt_create":"2025-11-26T20:51:18.1844023+08:00","gmt_modified":"2025-11-26T20:59:49.9259025+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg8Ktp8bEcvPe1iOPCEY6cG/9K34ZN03mK34myeCD7K0fv5YfxAJM7/PrgLVN/z5j1ktvVJFswqmj1gKuHZwFeOAOQXXhxsloGGystnKPGJE3VCttwMHtGAI7wxSK2uLBxH6oR38V9pleRBPpE6OGEpv3FG3LUvYIHNrpTZBy8dk4MOJ/GOekBcsIsxFFaqNBUJCppV90yexMabWkOu3PYFEpLkDAE9uT4tBXwb8w7IP5DmLyCvaNguFn+tN1bOHbwn3oeDjRnZib1TunlqOlweDWIquU5o5yXRFqYxJiqSrsgVmkmAx2KZD7V1qwgZlLVS717nFlJQfquSuy5Gxqudk0Mv/vmkUs8yTYwkN3dQ7FwfAL8PBkFLqZeqDwhBRSfjaphosXYTpKabS03RawalfcOES5WndwjRPO3ltiwD4W728YYgHVDZpHWVemVK7LQRddCxSwO9MsaFEiLwfsl1yfedSKI6HLWDhKxwgyzlwdEP4df+LlT1VZ8oAWRIymf05PtxrqKJ94OqQ/gJGpYy/XTfZGZcRu26KAmG6a98mzX405APmQaVVeXCsldZCb9ibRZ3R7VnyDPinlb1S709oktQLKLyjDn5t/x4oLnqepEtf5Yw1MLf+FzdTJhA5jx3e5TBeLZVeYxcaq970MXj/cOg7OZgzlaFSk1j3opjaHDvpgCrUzYAa8/63UH8Mb8Gp/sGbpimLS9TWySK/tjBiFrcuxbs75UkaK888/t2qBJOTNI9vC9gnL0ANupQ+F5uUoQv+nv7TqHyEwrhE6PzyVfO4RTFV0Zo9uBUYU3fCYCT0DC1jm1mGvEEqUhT5eRZF0LkJ0n3tNf+wnZtpJcHzI6tFgVNQcZcF2CCTiJISMdsYOCLcxyzDRsB+BpBnt/X3jHuwGgoFcHnX1DjDATbvuCuuqZZKOnFW6GIbjMXJ9d3u2STw9w+AunEnISXM2XT1SZPF7T+dmRQGfvdkY+hWxBxchYrxgbMvMX6j6r+WgfGPEL90ZcBmCxyyR2vBOWStng8uZfcww3r2m6g4XdJYvNUSd/jwgPPCRVx6zgVMr55V8Kp1sHnlOECZCRLvzY2N8/gSGrvXxmgMMOxHVWQayOVG/u6hzmbSBOMTvu94MC1tLkKcxcd1SEJ/DhscSjAcunyXegN5So9wYyYElZLge7LnoiNJ5bNEyqNTRFWuwthM3r5R0JOSlcWtJo7wn5gWu7iF6gS2p+Yelq2rfYlPa5V/kv7Gcdu+HRtQAbolJKglpAeaOFB5gOF8w2SEUlg==","layer_level":1},{"id":"25cbcf29-42d4-410d-b72e-2c345cf71be5","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"微信自动化示例","description":"wechat-automation-examples","prompt":"开发详细文档,介绍微信自动化相关示例脚本。涵盖从基础消息发送、文件传输到关键词自动回复、定时群发、批量加好友等核心功能。解释每个脚本的用途和运行方式,提供代码关键片段说明,并指导用户如何配置微信登录、设置触发条件和处理会话上下文。重点说明011-chat_chatgpt.py和012、智能聊天.py中AI集成的实现机制。包含常见问题如登录失败、消息发送限制的解决方案。强调这些脚本在客服、营销和团队协作中的实际应用场景。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","progress_status":"completed","dependent_files":"examples/PyOfficeRobot/001-发一条信息.py,examples/PyOfficeRobot/002-发文件.py,examples/PyOfficeRobot/003-根据关键词回复.py,examples/PyOfficeRobot/004-定时发送.py,examples/PyOfficeRobot/005-自定义功能.py,examples/PyOfficeRobot/006-独立版本.py,examples/PyOfficeRobot/007-收集群消息.py,examples/PyOfficeRobot/008-发消息换行.py,examples/PyOfficeRobot/009-批量加好友.py,examples/PyOfficeRobot/010-定时群发.py,examples/PyOfficeRobot/011-chat_chatgpt.py,examples/PyOfficeRobot/012、智能聊天.py,examples/PyOfficeRobot/@AutomationLog.txt","gmt_create":"2025-11-26T20:51:26.233733+08:00","gmt_modified":"2025-11-26T21:00:33.4437774+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tCA56wtAVt/9nhwL/SE6Sa+BHpYNCHM6XndVnG2Q13+H2DhDRzpy5saK1Fr4OMgC/+GUEEG/QubdNT3ZTXO5bapD48Yi0FvOh/aBFhM0l3GtbJo+tAgLnZSlNF/vvXr4w8VcqpbNNbWcelv51Uux3APT58hBxw8AconKVNYgJLxbyNcJZODkhz6qUJjw2YAIGnpntytj30Wsp0FT1trCObdctGeO8vuEcX9g02zkY6dMgArjaBuLhnsILLDtbZRbGJ6rCaZ3jwvDtW6MZN/nNqEuNm/d3p+QNnf1JWxLmXrCo5vj+oSc2C/CWzgTkpZWGAW941d/uWkb+dUnoloro/4mepyeLOq247CL0Wqb2zhACRm2nawgnqPHks0Ghd5Jx3dHnSlWd4mwSD/QN74x4YWnLtI8fMswg8vnKshqVrUVMdyy/umggh3fYxzoXOBtDHaoB6DN6sOQvLvx2pyP43NeIoL32xCDLME+4vWS7M5jCSjoF5rjS7LCvMUthitjZPPXbUcU2pYzUHbg37a5LsJdMcb4TjJyjKv/ZtfD4r+36MhjrAU3ysyLFkD6kB7Hxz1Y872uYBUw4Bw5ThneH7i4q2d62eUTxQRv/Ho9+Umdb+SPNA9x4IFvoSLemkPQ4c+FprkWNYMwz4qyAz4HoDvLoYuMIxlNSDJ3roXpaHPP3p52IeecZ8ReqBXiPJg6zDrBB8rztkVsl9Ef/jP3j043d/aKlOOif1UFC4TLIbFsN2PJ+rpD6ysJnZYtwnmjXVgryZPwqlyRWfwrnLd1xtEksEbIbVFk2RIJnxVXl5+K8cV1mmglB3arwYs7+mZvyIazqi8OVceSMOMUpQzXongEd/CzenAXD4rMKRN+kaHQ3DIH0hsxb3qJivXsoc/oaNTClAHHaEYjRsyfU0SKjjPAzl+HAvM1JiAxUTPbjet7CvMuE3oELltHEFCY7zSl0YmwfT7IByZoUVcefmTAzpWGk2kYV+2LKF899NjsUNtpidiKYeWD5hK1wXhmhquwWkHVcFRx905ibm35a3Ka4Nu8fkhnyQnHTcb0APgljW6RK8wXoP3q4idvByPNoDKY8bx5F5TA2YxVyP6tK2PWhT3Fzor/PD33fh0j/4YVwcpplg2NaqUG0BhJutha6I/gQt67O3cB641E4ie9KqNRpHyuvJJJ+4uheLyo/kmKMmDcrVcOE/I1FnCAoINHIvdG3E2xa72NhXVrjNlubyV7JSUxtC39Kb8ObIY0fK91pURLtaXlD/p5XYBOtSpYNR2JbLeRwaWuGAEGZcJUt+LCCOeJoZcH4LiSAeaQypPjOPa3M4numGKd3vaicKLAoPCrWhYGcRsc2nQwxMWV3SawhAYw9H+zwY8Pf417XsNzPQmAT+e3HP6ypa3SHvHoOjcVVwE6SpfmokKJGJMvne9S7/UF70Vm8gGQHy4yLkr9Rk8Z5jbxY2vsZP6nuxHPmdzdzoqFEPxjI1gcpZ2DNg/c4AFMWeGoIKlrJFvkhU/ixLCS/Dbh6IEWkex8ip7MqPPSXnVKOJzanZxZZe3FMGDGZI7dQGX4OjMCHuJU9zRSn+VdYS6F7Hf5tN/htN1gpFKAsfiM4AVMHksqCmoZLUSd9W+pL5lo4bJbSeh3SGoHd6IitUwu7HwDNm7bGyrHfvxGLoQPPfP1Kb9+Se+gTvfjpPcBtjXyfootxGCgT3NThS0HjmfWSEF0c+bNEChP1kK1WXAK2bKCjkCgX8gV9q2oJAkkTZOI9rRVAAxxKzbBOxgnEt3+MQMR87YwDn6oJb/DfGDyzcr6PnMuoItcqQI1w6v47aXitphul095i09c4mTA21zYlzbBAhDKIP4/2aucqa3GP8xckPUdDSehATq1a+6pIl0ZA2UwfkvtQ6H/iq0IRIiaP/7uarqCLuLNaH4PmS1S4U43RDdYdBCK0Tlk+2LCn4KnDc4DTGNfe2irhCAJ","layer_level":1},{"id":"63a5de97-9650-489d-b2e8-36c46be6fccb","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"主窗口架构","description":"gui-main-window","prompt":"详细解析main_window.py中MainWindow类的设计与实现,说明其作为GUI主容器如何集成导航栏、标题栏(TitleBar)和多个功能界面(如HomeInterface、SettingInterface)。阐述窗口布局管理、界面切换机制以及与信号总线(signal_bus)的交互逻辑。结合代码示例展示主窗口如何响应用户操作并协调子界面更新状态,解释其在整体GUI架构中的核心调度作用。","parent_id":"efdcccf6-6375-4180-abf1-f90510945ed1","progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/main_window.py,gui/qtpy/version2/gallery/app/view/title_bar.py","gmt_create":"2025-11-26T20:51:30.2180909+08:00","gmt_modified":"2025-11-26T21:12:57.7477109+08:00","raw_data":"WikiEncrypted:eNoLuopvj4dwuFHZZacGfLhwZEGAQUMUNYDcr70lZ7mnE+FY5BInj4mI8VGNEdUE24dEbuLmifCcwjo2KZdtU1GA4m5ZrPpnu9JlkvYcRvnwESJLx2TyM+D5gXkFZl3BFvq4Mbq5nLPGl8reLSCGWC0jZs+bI52y2NmxEPCCru/NPprgnbNkaDvJCnjpMPwxgJ4orwjsg32Bgkba5KCXrrBCXt8Ib3m0CLaBkSRtozXkY6OKY7nLcNuNjtAp6OoWPdnjRf4Zsx8LftQDWKyqlez3P6MtwVwcc2W8BPyzlN72CVYix1/lwWDPS/ZRkwoNEuoc98oWFjg5Yu6RGJAODYtX9/A5RGX0KbIULMk+nbD5I8+D040ojAVVaqngEp1SoZJVjRUR/bSlucnBqEN+CAeFpN+HIvIjOV48mYToiR+ylLQPjGT1OtHlYNQbyEfmQNwyO/PzGSKML9d89TKWSs2uDRQ/f9Tt7xJeJNzkZzLO0gs8MLHso5/bBKTfTYzcqGpKQXODp5bNaY+SwDzBS5w647EHEEMOmb/FZg27oLFhGPXTKKJvswSylU9WGBT+LCWw6i6MxTCXkX8WVChNI/2H5DHqAme7sAZlHBU285O3+No7rsGMTBnv59/rQXVoUdDjeNwZbbMaOuPzxjU+1hb0gZRxInXQQhrkYDcBVl6R1mxulJvdRvCrD4TChvx0CSmzpiV7vc83YChdQUjbIkt8LrpPzewAjTYCZIfYi8hnHxTgTkwFByS6vKCkRTz8RZ72tlLUfsvtk7oTZUGCeZNhpaGRx3Oep+/wcoywam0jgcxJ7OuGPhueNTTBe0QDIea0F2MLoFB+sQwmsJHxVZDBaHp+DCiUM4RsiQfGmUtA0WW/Rqw4MXjph5YPOuvCNWTjuoRy8SwAEsl0cqQ3Hh5D5v4yMMDHkh6BVwuD1j0KXASTJS6agvSi9eQWUNShQTRZWOYA0YKZsaY+o24sJ6fOjrAyajfS5YKU/Ipcd/JoPtI5WlFVsJul7ZzEGmNc","layer_level":2},{"id":"a4bd1c46-ef48-4bbc-80c4-8708947bde3f","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文档处理功能集成","description":"gui-doc-processing","prompt":"详细阐述GUI界面如何集成文档处理功能(Excel、Word、PDF、PPT)。说明basic_input_interface.py中界面组件与office/api/各模块的调用关系,包括参数传递机制、文件路径处理、异步执行策略及结果反馈方式。提供具体代码示例展示从界面输入到核心API调用的完整流程。分析当前支持的文档转换和处理功能范围,并指出潜在的扩展点。包含错误处理和用户提示的最佳实践。","parent_id":"e2f3c078-2962-4624-ac55-a7ae4ab1ba48","progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/basic_input_interface.py,office/api/excel.py,office/api/word.py,office/api/pdf.py,office/api/ppt.py","gmt_create":"2025-11-26T20:51:43.5361803+08:00","gmt_modified":"2025-11-26T21:14:24.6013739+08:00","raw_data":"WikiEncrypted:A2w59vd2disgg6HPIE7ipv3KnCYEgn2t52fievK0lBuFfPuyfvN1+03INLS+0b5gpfxXVHNMaTPpuxH8E/gB8X//Eisf6aBStdx5dcXSW5K1uzgiiJYEHUohx9Fp4nPFoy2WVl0oKnv0WBKqZqTaqufeLfs9RBe/6h/QH1LwN/vyQYeYs/6qKPz3yTwdjuO+1MSOiEGURfOMa2exfmLAHzmRhUTzBJf0t7zjB1knkeTVkeX35RyUpTZZqD/w1KZgZPD78QaaIdv5sNDqKm5c/9QE+tZY2AYr/flqMALumOktQbl25H/ZmobGw3InugMbuiVL5X4KVCph+jO4kfyBHD9TMbaP1KSfOudYj/XUu0uBVoCvJ7mR5TuAHaqMHILGe3TRjXazEsqz7a21DoGiaWK2Je1iuK0Xy5KK4Yl8c0nodH89/KKqxXljlK7EjNOARdIxeKd6QElv9zWiNFZ5E6OJ9kP3WntTk4tn5sHEaEolHx2/JE/CAIGqiDuiAO8jOWXHZiVKuFUub/dKsMyxlhenv8EekqPSlOLVHL5Ov3j2JCUWN6umg+tav8n5RofTQtd7cRf0NHnxLcXcxA3Wfuv+YrliOQO7g6fovMBZ9JQZjxEFMlzdBzEeufb1Eyv3YMw1Q9bSyA8Ltq7Zg0hV+KE2nW21KTf1snzbrXwxzH717lF4ejX/53gfGLRnEqJNkwVsdm/3a87Ob/hTd/4+37Z9FuURYPHtJS2eTmc/CwjpD9+i2G7hKM4z8mFn0NStUkFO2F13fPcphhkichzSmwkF5sMndMiAcLXKZlJQwszaBnExnIUX8VCxsqdJDd2zTkw7mMKi29jA4Ffm6at4dOyimLVDWaeCN6CsAanzR2aigrLS6W/9uNYbKUd0mt6OcGYtpXt96DtELmqW3c8i6Km9CZNIBj6IBpBcXMsYgL4zasmJRreV3st/RENfB32EOiuA3ajC4vgvOJHz+gr6JjDJl/z/C425IP47cQdm/LLMY7lrIZOoa8eb55Hn5ZNp167SDOiemqH6kO0UQKdRCL8pxNio72ZIPooEyrPezL6xaExWhsWMP96jMNsjWyods3NMV7Osbdmp8xxxXcUtdAl/ad0TiGgkVRGUJnJKOf2ya0emxDvJX/XIkM70aqvQ/V5FERTcGazMEgm8jKYVrP+PJ8ZMCmy5tK/jt6t8I8o=","layer_level":2},{"id":"d4a17f74-f33f-4367-8cdc-fc17c2168564","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"邮件自动化","description":"email-automation","prompt":"构建邮件自动化功能的详细文档,聚焦于email.py中send_email与receive_email两个核心接口的实现机制。深入解析SMTP服务器配置(如QQ邮箱465端口)、密钥认证方式、抄送功能(msg_cc)、附件支持及邮件内容构建策略。结合poemail/发送邮件.py示例,展示如何配置发件人、收件人、主题和正文内容,并演示HTML邮件与纯文本邮件的发送差异。说明Mail_Type常量定义在poemail.lib.Const中的作用及扩展方法。提供常见问题解决方案,如SSL连接失败、授权码获取方式、反垃圾邮件策略规避等。文档需包含安全最佳实践,建议使用环境变量存储敏感信息。","parent_id":"d2ac020f-81e6-411f-a866-ab1d3e411da2","progress_status":"completed","dependent_files":"office/api/email.py,examples/poemail/发送邮件.py","gmt_create":"2025-11-26T20:51:49.3463705+08:00","gmt_modified":"2025-11-26T21:14:11.5935452+08:00","raw_data":"WikiEncrypted:/tgmwByRb9hMFGCVx/eV992bnXbfDEV7Uk3cI1Z0w76eUf571xeu94t6lzniZHCXnwE8Q4BDcm4Rc/u6bJiLakBy8ROTVDKbxLsjGA92/tpuodwdq26nEbiiwytHGoUZya3zpK1GR+gpWNtROjKGdqXc4mo1n6dnO0caieaOmYCK4WHD0aq8m0bcbViwW9G44f5g4BbSTumNjEZGe/23EvspXR8qoQdSHlfIo6Zgn3QV23fG7LQ/MqMhZh3uPbSJq4k2clNeM5SINj2JsQ/1dZ8nGgihDgtHFIhPa6I1ublKINb4/nsy6gPQdqaR+Ia5dcRbF099sZu7ZrN+f1OcfJSusBzPdVIasqZEB/R9gB/L0pON/p4Cs3d/mhfdupkddnSfDE3yQHxOiJ01D7E90IU1GwRQ78Jq2g9z5uwfW+mzsefx/C9jHMZI6etvRgp0C1/L93WAK86zmUvmtCylMqTaEJo0Kpkes3YMuEcqWZ1w+8vL9VpYC8SItmuZDQnvbqvnj8nyiTXSCEjIpF7vu7mZV4kXMjPa2sqq1O0tFlHm58Ey+p/h1Nx4K3qyI3WnYPut+Wn7O/Deuv1q0+B1e84DgpFCGsnBenJ94aABPVWU+307m5NDf75DtjIv2x+jfoy/9RqbsHYRH3/FAejgQHFfSSYv1R9uJ/UhIoJt0RX6GNKh6/eFQaQ/prAGjqXKYfOe5NalzOYG9RXrvI/1DZlXKP4NH/CdDoOOyKcBfo7FsZiEHHqx1pxsV3uewkJIGtYksBhfXIjnVA57UaZn23JRnEGjZtrLZgSY4zBDZ7cYI6BrM9ewQn4fr7HYHhPQK5jvBOV0LZbIcts/HEEU9eIVyES+kzyTkteOiih6MWCsupbKndXRNTkWSoIfNpReRgyCV5IzrtVGPQFC0HYKCTgnGhGa7eacD1a7jDKjusCci1KiYD/C+rmli2lxQchb/wnDhXlPpQi7wyDWAy6XYjO26vT/gb3JplJuIOKLxW9tBpVAC1cHxtBiO9a7vAZ2kJcsK3GQLLTwKUwz68qC6YEp975I5GKBOC9+bzEv8B0QjnFQUasG0kdYY85XeEQ8g/v5iOJWHkisxI464OLcWyWJKhgHOmtMqW3oR5ol43yiKUAc1bSmJbmjVqWlKmlVDSb52B1i7CYBmCVvB10sDJYjE8kxHT4jSSDCvTB7t8B4HX4ovDH5o2umDbC5YoZkOMLNYZ7uMRNgPeamD0gYkiOSlI3FDK5cZa25zAElV5wgSzFeOXssa7l49Nlg1o51KKg5+0oZi4l76aKryueRmeo39/n5TGthAYsMB3NNC6Yjmm0lamCx3IOvC4rhjGnLZr4JgdJ3IjrxS5I7kDzEKakkZF0KRv0Q9uvDEuh5QEpBqkRzp6SDOesWwUvBNAK+","layer_level":2},{"id":"cc27c795-85ae-4b83-8279-5c1fd1f80186","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Excel处理","description":"excel-processing","prompt":"开发Excel处理模块的详细文档,重点介绍excel.py中提供的功能,包括创建Excel文件、读写数据、格式转换(如转PDF)、合并多个工作表或工作簿、按条件查询和汇总数据、拆分列或sheet等操作。结合examples/poexcel/中的实际脚本,提供清晰的代码示例,展示如何调用office.excel.create、office.excel.merge、office.excel.search等接口完成典型任务。说明参数设计逻辑(如file_path、sheet_name、filter_condition等),并指出常见问题如编码错误、内存占用过高时的解决方案。文档需涵盖从基础写入到复杂数据聚合的使用路径,同时为高级用户提供pandas集成建议和性能调优技巧。","parent_id":"f7bcfd40-cf6d-413a-b3fa-59f8cc0f5a06","progress_status":"completed","dependent_files":"office/api/excel.py,examples/poexcel/创建Excel文件.py,examples/poexcel/Excel转PDF.py,examples/poexcel/合并2个Excel的内容到一个sheet中.py,examples/poexcel/合并多个Excel到一个Excel的不同sheet中.py,examples/poexcel/把100个Excel中符合条件的数据,汇总到1个Excel里.py,examples/poexcel/根据内容,查询Excel.py,examples/poexcel/根据指定的列,拆分excel.py,examples/poexcel/批量模拟数据.py,examples/poexcel/统计Excel打印出来有多少页.py,examples/poexcel/同一个excel里的不同sheet,拆分为不同的excel文件.py","gmt_create":"2025-11-26T20:51:54.8820376+08:00","gmt_modified":"2025-11-26T21:14:14.1265221+08:00","raw_data":"WikiEncrypted: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","layer_level":2},{"id":"2add2cae-512d-4dec-acf0-6cd787932142","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图片处理","description":"image-processing","prompt":"创建图片处理功能的全面文档,涵盖image.py中封装的所有图像操作功能。详细说明add_watermark函数的参数配置与视觉效果优化策略,结合poimage/图片加水印.py示例展示多场景水印布局。解释del_watermark去水印算法的适用边界与局限性。深入解析txt2wordcloud词云生成流程,包括文本预处理、字体选择与色彩映射机制,结合文本转词云.py演示自定义样式配置。介绍compress_image压缩算法的质量-体积权衡,提供不同quality值的性能对比数据。说明down4img网络图片下载的异常重试机制与代理支持。涵盖pencil4img铅笔画风格转换和img2Cartoon卡通化处理的AI模型依赖与调用配额管理。提供Pillow、opencv-python等底层库的安装兼容性指南,列举常见图像格式支持列表(JPG/PNG/GIF/BMP等),并给出内存溢出和编码错误的排查方案。","parent_id":"f14f8d32-b1d1-4726-84ea-35edbe9520a3","progress_status":"completed","dependent_files":"office/api/image.py,examples/poimage/图片加水印.py,examples/poimage/文本转词云.py,examples/poimage/下载图片.py,examples/poimage/图片去水印.py","gmt_create":"2025-11-26T20:52:02.8124821+08:00","gmt_modified":"2025-11-26T21:15:41.445126+08:00","raw_data":"WikiEncrypted:vw8SwXDMWAcq3MVrbhINPHyvGrJeI96Hcz+9ovGB29iaZy6Ow/LFJaupIKS+1bOI+MkkJl0EbcYEIRe6WNHeX7isZpujGeb2TT5U9WIOSFltFaiDf0zXbpmi5ssi2yE0CNhfWDJK/Z5FgewICjZrI2qDJBkHOLhBrDc6Jsc2DaQery8/dkiRg3TCBojSlHSG0FY0c7ouMqKAqBjlB7ZZEMjSM0+HynAwQ930f/RtaljFS8YSQSPhsfDGhkzQ2RgDGmoGsW6ANUy2OiMgPmEy04zUhIHMuVSUay0+ALaspqpAUXPehCAMxr2FVJ08ZIa3pTB1hjCfJtFGlDcnqgUcYqG8g0KMNfuMx0Kwm30lY82K0RCeSfWvpJO/BZvxrC6drsh3NKyRtnCoBIpOFWy4MiF869Yx78ycajQXS7Nv6PHG7JqV/NLyalIursf1ghOSyNHV0810FXgyOE9A8zSjru0zUS9MqaEtiyoMTBrXbcIng5UjrXWG5hLngUoUX81Ir5l0Y/BbihtgljrkHEg71Qb3cuBRs5Lb+FTH+GYrxQ5RKsG35m2PhNfsdk3+aJyRa8fL9jDuRA60EDWSfZSV2HsX7TYVNq5uH/hq2RoaSNYhLjE324t8e/T40QCt+2BYD8J5wu/kFICmZBFU7JtzG29Wjw105xTG3fwc0ZmHQAY/ldZ5maYvWjM1TBuFRCCso2CwrewkX64CkHHjmjDl2xlt3OhdQkiBdOwoO4M484rz+V9e0DwUbENKIOWWVUio1k1aTibsLM+Cr4QsCBNt8oiu3tYyh2Xko311u1Ufmo6Ck/yaJgtimgwnBIoWwvdBpeZ5A35BrulR+95JorokvM1VWBp+ZiOFJN03e6CsWarvfkL2pVOtpdmP4+SX49sXWTmRoxXRTCHMzcyClWvSrCOBDSPSMJBvRR8ZWMpIWR1sp9iR+VX0Fw020myqurIgUZ1icduWHxzIfwNB82kO/4cKnc5ikzvPzHkrWaZP/T0q9mt5wdFfYdJpL6BjQw+LoQBoKCeJcOidgqiAABCRG7cB21VKnUjDbo0x8aRgmMyxTxfTowFEnEVo24bf5JvYd9NTo7B5SmYEdOFNLgHyRysu+LizJQnpiElKg6xrEzE6EW/c+2TMmAQ20oxycNCWjvb036mHGM+bX/8ktVSPEkqLTEEgb5OyY3k2ttct84k1DRr4U8cpQr/0s2slbkjnu9vHDGfV+cm4n7IFQvqls8+UcQcldQz3khzdAqwpsW1VuZ1KLD3S+oWVy4FPVHXRWEkci/NZ5vLdL47z07Ljrjp7RHc+aQSdnVKzL6Zn2d6oXBq6WGX1i0YTMcIU4GaylvCaQGcpyjgJ6MRDt9/Pjr5bQEqpqAzVkSm1YHhibSyhEVWaXOHBfttLNTIwMfbhM/5M+o1NKpVdC6R21riFLK5AnQCV6Ovkd1M7H9gv87UzJbC0wFBltK9rc4U6dXfMj8as4upoz8kB2jyIGLebE9D2t7/J3cetHx+RC9pgl8uiXesbnHIG8tQXkaEWm1rQ1lB906D5DHIt0Qn6TUMoJ9zzLJ6Vv0ph3hVCmH/rbwj3cIHS740CFP4+UTmtMnKlxHA8TxF0MBDxv67TpgSnC7e1VDEpu+Q1fdr57YkY6B7FB2BUrr4AgETCzFwOBtkCeq/6R/ThIrqMgRvtdXJq39b44L9hrShRpsspzXGSm6Ix5utSFHOwEwpCeh0BHhmFxTyBhnuy1NLGfZr6ZXF9TIAMufUFWn4ZtkFz0JNxPgVM2GoLd8ynNCTswIqoVggXy8wIn8xJFOItm7+3xa0p+/uq72v8YUGSzFK24ifxFMSnXFgyimel9iHw0hpHExD3X+AiklhtONtrpaprzIRrRg1TVJ/bF6qfJu/x2VV6CKO2RPwN58PVI0vWFc89QCmq","layer_level":2},{"id":"796fb214-7e2f-46b1-a370-80dfa4c07b1b","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Version2 架构设计","description":"gui-version2-architecture","prompt":"创建关于python-office GUI Version2架构设计的详细文档,重点阐述基于QFluentWidgets的现代化Fluent Design架构模式。说明main_window.py作为主窗口容器如何集成各个视图模块,config.py中全局配置的加载与管理机制,以及signal_bus.py实现的事件总线通信模型。描述系统分层结构:视图层(view)、组件层(components)、通用服务层(common)之间的调用关系和职责划分。提供组件间解耦设计、状态管理机制和模块化扩展能力的技术实现细节,并结合代码示例说明初始化流程和生命周期管理。","parent_id":"fb4b14d8-a3c9-4f17-8f24-10e8bfdb747b","progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/main_window.py,gui/qtpy/version2/gallery/app/view/main_window.py,gui/qtpy/version2/gallery/app/common/config.py,gui/qtpy/version2/gallery/app/common/signal_bus.py","gmt_create":"2025-11-26T20:52:14.1913779+08:00","gmt_modified":"2025-11-26T21:30:50.5605508+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwGhGGvGnK0jlN4u43BbM4PeKmBHMTbNcsSzHJxWD9+Lf7K8eE3nOA7AFloerqitZhxYW/XMoNZdukRlNDPUcN4lgEigTQF9os147aO4rpeWN+BBbaLNr2+ESp34SnnEzzcWP1VXzwYJ2J92Z8TY5+pWTHCbiSEOgOkHW8kyam5v+XW5zCAPAYEOeBdtKs1nIhzJaGrMnnn6lnsBDgxx7iNcOKcNWKpVvAGsDxHIuDcz6rV5ZWtWcXpfJMZQoNPYkmb1DKGYebnBTdUo58JRTzbjHG0vTfXScCc7HLa8/v3Fs8OWbguz73e1oW8BL6mya6t8CRe0b2ZA0T2MnLYv8TO9AerlOK8P6LQbu/IoTtnVtGyFAB+9nudtl39qnYC0hXft1IhW2yrrsIIuXQHJldvfHLewP15CXopTJvUWRnJfQVTZVbcr3+gmC/V5nAHOhj8OWyGtT9UxqPe5r9QgYJns0aqeDlswznOLoUnkAvFjr3hNXCgUYrT122YpK5AlEkcKX5yhn0WOFLPuARrh3OZCG32x8s/H8ghK5YIMGQzkeKWTmNoOoB2Enedx3qRRzNjlvnuo0olUQXITBLohDugX6lKPqbstmLcYRoT8F4DOQcXzLDNot94LfuyIBirIlLZEua9y5OK4JNKiq62i6QRP07Mr6a4+n0qQk2K18eMEfBxm90CsWauDTrz9p++GBH/qe+WEdkEbQuUCUmtygGkGQvrc2aunPX9sGIu2ig+4DUbSpgzmSOqeKbHuZ3NFlnXA9gXmiBlVA9L1GInRj0mFqLdfQ5NxYfawhFUKuAFXopXcs8EUzkbvitxIeEHnOjn/c1AFMKOG0P6yRJnPW7cLq63erlfsEPxCT3UvVbsXRoT8AC2yYeL0FwxJcLNFdDIt+XyrkMTvGnsVumQhsfvZc0byai5ZRfDUTX4xSt4GBecN5loxSwRTe8lmLGqDZUO957S5PEtEMelifqQwJ7y5LudsHa+6zSfGRO1aSDuFnKUDPTPN4M+HiEgwa8gDB99bKFXBUSDmnhU4jX/4BzgRVS0co2yzg5sbJ9bNPY5kThvJME9PYm5bRZmno/K/IcGw2Y/oXFq129NPiuso3fZw9cGtFRYVVXXP6Lws1auk8/EriR/yZgZZmtCniUM3rFYaPavX8b+J6KZLs3zfyIbVCsheNSkGHFSBIlrzzFIwc2qh+K0PsqN4d4N+yfzlncVY3OJ1zL4lOUzRGDHif7hri3nITqyaVVI9iqq7X7WZkAZe7ka4nTHH8E484+VqlHF2HobsWKKWwrY2tw05/Swcc6HGrX3mCAZwwgo+6lfvs3L8LGj+MHO931i7QlpbT67zH7Aar2WpF96hl9clIQpWoVGkMcq/7Ht5z2mWJtwz/","layer_level":3},{"id":"ee1472df-2281-48d2-82ec-971b66d7dfc5","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"基础通信功能","description":"wechat-basic-communication","prompt":"开发详细文档,介绍微信自动化中的基础通信功能。涵盖发送纯文本消息、发送文件(如文档、图片等)以及消息中换行的实现方式。解释每个脚本的核心逻辑,如如何通过PyOfficeRobot.chat.send_message和send_file接口调用底层自动化机制。提供代码片段说明,展示参数配置方法(如接收人who和消息内容message)。指导用户如何正确启动微信客户端并确保程序能正确识别窗口。包含常见问题如消息发送失败、文件路径错误的解决方案,并给出实际应用场景示例,如自动通知、日报发送等。","parent_id":"25cbcf29-42d4-410d-b72e-2c345cf71be5","progress_status":"completed","dependent_files":"examples/PyOfficeRobot/001-发一条信息.py,examples/PyOfficeRobot/002-发文件.py,examples/PyOfficeRobot/008-发消息换行.py","gmt_create":"2025-11-26T20:52:21.1777906+08:00","gmt_modified":"2025-11-26T21:15:16.9649424+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tC5RalnDOB/YJZPPYM590oz6QwgGj4wWc4fJnRwE/rE0pmoN020SiQYbIU/5mKjyeWuO3mRToGmQyDQhYZUG0YSN4biLNyw0UXolw30YQUYn8Qi3hz0bnlmkWWdWveRGr/sRQgkIoI7jZd1oNkzz/ESCOKYvjQB62pIL87AjiSKYRUlvTPZRAhTXKgJWNaMfLcCEskq8Y/neFMwmvMRigT13cj6cseL5/1bMJG0pTftJWF4f0HNBIkEnjxbDfDWRUjLA8gTb80Esr4gAwp4cAMsYUMWFC/Bi0G7fuyujfEiT/CsfKj/lC8GG9sIeyY+J/ZA8o4cP2Y6VAtuZFxOKp4xew7lAe0XCy0UgA3PcAQt8O8weENtDcO0KFUFq8ngjYPudB776C2L2AFFzj9yD2zYDMP8ZhkeLZGnL3m6Jg/hP1YdNAT7FWj4oIfrJ/OCky4xrBptrQnBeKwNHVfi+kGs6ub3XiqmIGsm7VOqjwo3DCXimy0R5Qj8rIZnoUJpeHhziXYtlYHNA4XVNqtutSeQ86Razwlg9Ti6vBtCkQuGmgQTEQVWPbS84exoXn4AAhPso/58WdM5yNxV6dSbbfRQenRTUTEgp2O/WxS47iN6qzWT7pgEzlQbAYey3Ko6rP3IaQeBOBg7XE9daf4u13z9Q7kN9xeZupCnR+BMHotHJ6QHonZz4lfmLhnoio5uogcg8nlAqvbY/Zx0alSTBjiDOkpzHffCmijb2e1WbxXhI/71VczpV+VbhVmWtZWDSmHdrjQFH7nySIDeFyPy/HbPRmwRVgfzr+QCMmYEEwiUeWq4DBFcU6PAgzU+oFGnGtaN1B/jyH8FnjO+O3UfAh0A0tR8PHj7DjBhdZKf4cAn8D2Bh1L3b16HbqT7jlGhlB11RxdcR5O5SlwslnUFX72MOsjAukGmXa5PUDl7KQRO0Z0E/CHxvgPO8VBBuoMdADkT+JsB3O+WJQlpSm+WGDLcPmqhPc+Ie512VYvQIVWNluN5ebdC9nprt4VVxnLXNy7myEE0a2Z52ZzXG4Zs1c5PggW6UaaKpGnTs4D+klsOeCfCygiH9sHcoH0XlCqElPfY8ZyeOh/ups8Af1fL8sYR3wGGFjRW3flI8YIeDx6eNGlNLbwVDu0JN8U8LmgK4wV2eiwn8h5feJvjdNFbpR25JHmiyhjLucZCmtOod0/wyFLgQDOfTHlwP48uuUfa3EwSEjVrdNwZggGeVcFCZj+HzGYe6Z1yAS4Mia1J3kD7xi7USwSn7sIeyO3JZZKGUhN0uKt2BSKX2Mg4GuhxJrFGingRtEcuf7+fimbXao7Kl+h4IPpYdTZJ8rjMj6h/da1Z1xz12IS4gWwp0jqfbsLg=","layer_level":2},{"id":"27d62374-4a28-4795-8159-b990f56abf80","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"创建Excel文件","description":"excel-creation","prompt":"详细说明如何使用python-office的fake2excel功能快速创建包含模拟数据的Excel文件。解释参数columns、rows、path和language的具体作用,并提供中文与英文数据生成的对比示例。结合pandas底层实现机制,分析该函数在批量测试数据生成场景下的性能表现。演示如何自定义列名以生成符合业务需求的模板文件,并给出常见错误如路径权限不足或列名非法时的排查方法。","parent_id":"3aff6fd1-b9c7-4eff-b8f5-26462a3f14a1","progress_status":"completed","dependent_files":"examples/poexcel/创建Excel文件.py,office/api/excel.py","gmt_create":"2025-11-26T20:52:27.4970849+08:00","gmt_modified":"2025-11-26T21:16:10.439055+08:00","raw_data":"WikiEncrypted:8x3JSVErdDUDs2nXur+vXfZckhDG4Y1Zconyd1SMKdNw7NByQVNC/HU7E5TLH63uutfcs8p6fM0qwzzithToX6cIrZGobKo0qK93zPDEhAH8MrG8PIoacYuz4AQc1HIu3iDI1wxUNXFAUfLvKyXZppHY5zecHo4FSBXI+JIf4lzEh7YRMxWmvX5EM4pV8RT0EovEVWJsBH1nGVP5AQ1PAVH+fyWonPJTyJRU6s/0RAPF+IlN41o50wAJKya0NVVEpKyI0F25wQD9EhjzCVrJy/oZrCDIwZyuJtqOTUOwd9yJrX+PXRxYMTQQn5DcqGD4nZv061D38XgK5JnWZt2FxKf8DYxxDKUkGpX9UsZNR6R61PznDmqytOm3Q223t/WecSn3cB1K/dgZCVN3dIeMoyPkxEHpSEE7kYOwjyiNpg/oUaPwlY1InG7sZSpMgEi8SPc4V+ASvmxPi30wPCyPvO/csnthvXsyKTvvY8OgEOSvKI3tYEix6Q/sgSiOVOoIRpMFxo6TjT1lrxAeajHcf91YVK8b5QS3wCu5wZafna71pJInwPuvyuyzvyuQuOrsU0JP9C/EAX0nPnkfK24/CYqt+Kx774Bf0ddUVSS/frn+oZ3BiPdxcAQ97Q4SvHIYXBtiV9HozonoWFOGrkcS28cJR1RvCVPcYExhAWkvCF2dnU/5ajAJjm5zHxkmHHHV8cyM7jLlK4DUtXWr1QWtSthgfH8DYYXbB4Q8I/AUZN7o7yGYF27QVYuxoOinqmxQ3kZvshxVqpw9Ywr7LJS+EgDqWyE/OR0Te1HCu20VnrM/4R2jUEY2g4WTlNoP8fS/koT2GgSavAaHzKTjFoT41EClMyllpagJQrlgjGqQuo4balbwb8e8Gr86V5TU6OF7/dKF1sIiCTK7JSFcsrbMCO237KnfA7jJ3SrztxONHn/dXX0thfgdXxa1Ll4J1fxaSUaDKBcmh4NUXgLyMOYKYCVNkuLn768Rvvmfgi0tb/8Lw7rFKbdTEMxiRsgFsZLz","layer_level":2},{"id":"a4a97fbe-2696-40c2-afcb-ee7387132362","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF安全操作","description":"pdf-security-operations","prompt":"详细讲解PDF文件的加密与解密功能实现。说明如何通过`office.pdf.encrypt4pdf`和`office.pdf.decrypt4pdf`接口设置访问密码、控制文档权限(如禁止打印、复制等),并演示处理加密失败、密码错误等异常情况的策略。结合代码示例展示对单个PDF文件进行安全保护的操作流程,解释底层使用的PyPDF2库在权限控制方面的机制。提供批量加密多个PDF文件的最佳实践,并讨论不同PDF阅读器对加密标准的兼容性问题。","parent_id":"5235253b-7037-4298-b76a-147a71088bbf","progress_status":"completed","dependent_files":"examples/popdf/PDF加密.py,examples/popdf/PDF解密.py","gmt_create":"2025-11-26T20:52:38.0453006+08:00","gmt_modified":"2025-11-26T21:16:55.080625+08:00","raw_data":"WikiEncrypted:l725GTMCMhvHxdLnrEq9J89cgTIDOag2YsnmnGU22Hs8gg2rvF+j0ckrTKG8OY/RlkrbmiWKjqy+F2FvUdWhc1nokqX4+Wk28FOOAvApArgduCoQEhvEycjKdbRxjIP44KHr/pYRRwpcjARk99FOe4P35j3zcjjP3+VVOinO6S3dCVrLfKDpfOh982xkU1LBYihhQN48H861RNHnZt6CQ7OBZAEtG+OlAb86Pc2Xd5rWqBAuoGwhIRs5ZQEBEVffmgXdORc14DpJFJ19E9eLlx8dP0fUzGv0xEgYbp66u/vKGEVVdkziG6EN7VvHHLSa+aOvbBP4uom/aHd8ZT9rF9ZJ7EZRt3noAr8a4wExs316S0qNJrm1BfaMyBiD1V7XvSUuokMuMIFO5FVTBBFDwQB3rACqTFIhbyQ/esT/kSoZS38WFzkdjEPmnds4G2DAGwTEA7cIFtKzjX9FILIdEKw73dwPh7OcdJ2XXd9bjbL7c1TK2s5UCcGUp6FTVbjp2gNrjKWV33ReyPR6rAw/mtf+V1h+0nkrWzB/S2972plAWJYU3OAv0Dzi9CnRxFEOUdd+cDOt/sWUQaH9F3iYaoVfv2rtnNBDnlCyDZldB6hM2UcPg6JGkdUPsQ1j8A6ot6rivnd1D0BSjpze8+p7Dc+rUHk+FigE171i1w7m9c0j4leQGKb3XXs1K2WPtEcbmZ1tGCluSZfylT+f+5wA7/m9Xe8Zzw0g3X0dc+9KC7IqpFH1n38nFBaexDJ/tLYjFhLBrbPtdmINgRh5j7vF36ObklN3fOOmAgtzK5QQMfAsPA13B2YVZx/yBn6Zd4lgGFL+WWaKCngTj+kThWy1OlOjyEI7RTMe3kJ4Kw9rYk3tbx0a8k81W2NZ8efX9PmhKY/AVLbLtijo7NZZ/L6ByYbfx5eE7LYjcppuYOQSfHDsUxGazozAQ3naC/JQDC4G/QX6jfqgGPXZCTWGyqzO1qW4c4KPkirYwURl30DV4oWSN4KTsDd/D6F+noCX/7U+yyn97PdMuNu5gO8DT257KabGf0PDq5dAJ9eG6pX5eewz3213KzyR1PkXyzlCbnE1FpZHa4GH5V1JSDdStBrH0Ost1ljpWovR7bLpi2WRFTNP/llu6syfHZoQ6Xu/vqDFda7rJ60+SsvIcPnaEpptDg==","layer_level":2},{"id":"f2cbffed-9820-4f3a-9dd6-9c0fa4f28246","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图片下载","description":"image-download","prompt":"详细说明如何使用office.image.down4img函数从网络下载图片。解释参数url、output_name和type的作用及默认值,演示如何自定义保存路径和文件格式。结合代码示例展示同步下载单张图片的完整流程,并提供异常处理建议(如网络超时、无效链接)。介绍底层依赖(如requests库)的工作机制,以及如何通过代理或重试机制提升下载稳定性。说明该功能在批量获取素材、网页爬虫中的典型应用场景。","parent_id":"e11e3a92-fe01-4716-8371-3f718d2870ee","progress_status":"completed","dependent_files":"examples/poimage/下载图片.py","gmt_create":"2025-11-26T20:52:46.6705974+08:00","gmt_modified":"2025-11-26T21:17:10.8627587+08:00","raw_data":"WikiEncrypted:vw8SwXDMWAcq3MVrbhINPLAMmtfB7lOCl9gs4fVjA4ik15p2VkL7oO4/fX5xAd+R408XPPlePwGPBuGC8YJ33EBmfciuRHmt+cLtRlfN13TZQfvLrO+f9Vc0HmJLxCQvI6cPUkvpqe7OQy/B/Xj4R5gt5lmDssH1zHOrzSMb8foRct6jcy6QYQ/ECA56ltAUQWOOpuTEYEhIet+rN3KOqzJVyKU94XmKVdQjPl4c9y6Mrgf9MYBvyeUT520XvKpUZQFhOu6ZBJtJDxR/f2ug19Zawhg5ke5oQVyrgO6aCchBNYVZ5J6se6Nm9Gw3q5+0Hti0SdaUn4APcV1elLIfVbs/6U3Mm3MyNfM+6ZW7BgxaexyGK4wUqGdcCGxcTQS1sRs9mKyA7LTKfN8hbumQ316DItUTM/bgljy6NibooN3PmvrHYK9sChvM0SjhJ/ioqUoEwMh3qNHCIbVDwugYWF/0ghWyqMuf15q1jp++v5mSL1bxTlw6ncVHN3H9b+xbxZPmzssr4Vk6Q5TTkd7ElqRoFI7HrVlGKEObJjJegnHwdAPh4hig/hCleG3Oi9GTxCC5jvtq/IWza1I4yA7kCkCFcQMDAhkoO3pS+zJ1Z4h/HpLne3t4hjXe69DG/p9jalgMXovjyuYUOrDAbl60Mx7cT/71jfSVOhtSl59n4zkmHFmYZRl8Gae70x+i+pOqQg9jEegsKkTyP9jd5CjQnr0afoiFkX3VO8aKvvLuIpcDpWLC1cI+NRgi+RWCfu51MDx1N63Oscvel3tmO0Y1ohgZ1vpxUwpW1UeyAZzV6yvj8rbI3in+EYwdfoBPTtBlHZ4S+zMN8MhKTdllM0w/ELbz+ja6kTyBWt0alaA1bXQDEAEi16oszY6aL6gqbp0mMwS4P/GIevUIk1Ru0ssTG6locj53W6p3eRY/r8Yn1mZ6YdcQNrJ66HIoDclC5crCS/gRCL7zHxXcBC4yA754QavrDwOfLRAg1Jf0He6QPWb9GrNE+DMxd+4q4e+cFlp0","layer_level":2},{"id":"8b90388e-177e-4c76-bcf9-934b0d151316","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"OCR文字识别示例","description":"ocr-integration-examples","prompt":"深入解析基于百度AIP或腾讯云OCR服务的文字识别功能实现,涵盖银行卡识别与通用文本识别两大场景。详细说明如何配置API密钥、发起HTTP请求、解析JSON响应,并处理识别结果中的结构化数据。提供图像预处理建议(如分辨率调整、去噪)以提升识别准确率,同时展示如何将OCR结果自动填充至Excel或Word报告中,实现发票、证件等文档的自动化信息提取。结合代码示例讲解错误处理机制与配额管理策略。","parent_id":"9f1b3695-d545-4923-baac-47827243ec01","progress_status":"completed","dependent_files":"examples/poocr/识别银行卡.py,examples/poocr/通用文字识别.py","gmt_create":"2025-11-26T20:52:49.0241847+08:00","gmt_modified":"2025-11-26T21:17:54.2436383+08:00","raw_data":"WikiEncrypted:ft7zH+mHwZ+DN9fAq67hOsRSCaWEhomjhliImae6gKGfjdbiXjubuSWyOLVBmX6e2Kui7q6R4Ft9mipHWHAZ6uZRyQdcgGoEbJu+LKyN5eoY+uPKTQfG+OpOt8f5OQGfhi4T/SP4fDqAYNUDWPwRu1JB/TzqX0gAZLHCCFIIFC92qUdWmpplP9LiOWjwjUfipt+jdB6eIEOt1zbjo5IwFR8uEFZ6Fh3Re/AKayAT0krMR9vWl7zNrPaQh3v8dTthT21kfAIi/H2QqqgnypGgd4AhpAAyRtXXmfIXW4fyDQqUZUUh1w+lhqLd/7PpBwN3EyVHYuMGnmcr0UywzFNArfHN1zZRFHjLP/ShkkDA4bI/meLTAYuzQIB5+ea+XgoE5lMdzvUbp5TD3r9xmxVfEu+uEfcweYOvs5d53VxLtE2CnyjpBwDjlXI/9BKC1wocoCOnwcK0NW1uH8ClTQk738r0e1HDK9I1cSl3t4vVExl3YooEFag/A5IHGr92B/YZkC4P/Yt84jjrW5JSpSN/IUDAj2W0hjObqKCr7B/nbbfJmCu9aqBtE7R9xjZ2sBgL31Gf2jC3bX0DhpuToXSFnnwfzT+eMT7mUuPEdR2OIIMr4lDXKoOsH/vE/oH6Di7yfBE/JyXQ/t5f1j+5jWFiGAIXVTGqn4Ty5MmepNExhy6gUTTHfoBIKE28eksSX+hFZpBOxUQRNZ8tfozLETrZsvG1nMtmoDJ0Blt7RkCb0qUH2EqgLTZD2g1FRqyGqw4XbrSHl0PGShFMH8dApYWOq8+2NqEAS4QEZPqtKIphuqPXegZVzIR7GaDlQa4ZC/SVu4auT2KbZzFx8hyO5YhoAUaNy1k3Fv0Dd5QIttbSMlY5VneZIancpz05AkFsr+GTVub9XwF+MaNR7bmMlQ05ZLAz6NTaoON87jyl7Z6taBseP8aL9qSZ+UIH1MPJFXlwaRpbUQPWWe9NaBuWlgeZ4bPQw08oFB66kl1ZnyvfBfg/GIzpYr5hfdOoZTd/SS3wQHbLLPEorUQx3g5fghuKUjlGvNMZ9ooKOdcyUL4P+8coBpNrEcHP8viXj9wyZ36kxdnrceiPJ6z8T6y2MhH79OPz6y713cpFYTbsdCD95BvQheSBU4UWINPfS8cCTZ6YU7JTQNfrZn6Vg/iGY5Cjppkt2jsyQ4FjTF07CreWt7I=","layer_level":2},{"id":"0a6c6324-68ec-4624-a4ee-dcf99fc9eec1","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Excel功能集成","description":"gui-excel-integration","prompt":"详细说明GUI界面中Excel相关功能的集成实现。重点分析basic_input_interface.py中输入组件(如ComboBox、PushButton)如何与office/api/excel.py中的API进行绑定,包括Excel文件读取、数据查询、格式转换、批量处理等功能的调用流程。提供从界面操作到后端执行的完整代码示例,涵盖参数传递、异步处理、错误提示和结果展示。解释支持的Excel操作类型及其限制,并给出性能优化建议。","parent_id":"a4bd1c46-ef48-4bbc-80c4-8708947bde3f","progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/basic_input_interface.py,office/api/excel.py","gmt_create":"2025-11-26T20:52:54.801759+08:00","gmt_modified":"2025-11-26T21:31:21.2233298+08:00","raw_data":"WikiEncrypted:Uj4pRYr2f4JgWbWYCXeVgbGSfr3Oa0RzQJPHbNppSsKOiUlWniydJNRtcF3f6hjPH8IIFMnEpSUA6OE8wr/2D06eB+DA6eXqWjsx5uc8FjrHFXz8Ud1F/+oy9FFDLbSObEeSywMPRzi2M1oHDwyxG6YagH/f8Yj78gXMTdgFpfnY5njUvnDH/WaMYwEFPhX7C4kwOvfpS/ZoxKHdsbwdYYX3QZCOW8us1kA9ciw3p93yrWd4PhV7558MmTsFP2Xa9j7rKr1ZqBAZ6ZRhcQ7U5y27a6VQVrsM77Zhk/03xeB51R2ZkDXnkvnpjPKR33DWLaRoPCYp78ajyQSd6chuOfyB2I5J1D0I7Uk1tFkjUkdL0uefvUOkabEp944hCTzqrebmPcnJiL4ole9knnqOjshA7D0TBZMt4QETYz+BnkU17I/nsbF1wcLeICmuaMbt9rWgwpvJXG/b3tlE2X6PoJOniBs2H4DmqD7aCpjYjwfH/VtXKVKlqxzJnShp9fZQmPo8amjkwwA3e4OjyHn+7qJJlJIxu1vXhg64OPLFQXUFJvi7uDdsXLUhKmba3Ir3mxg1WcACVT9p2FgZeqNk203rxvwv0Iw+p1zrhCyeY9OkTFuUZcks2mR4FNIIMX0SyXLBTpmAmbU6uuI09hsePuDm5BPw2/s+jQ7MTH/rsTixG0HMNr6glEN8YmDz5bQ/WfYUQsj4pKZBXsQxGrVRFl4gujiAtlE/L5Y6/oNk2TdhIYHfOPvUgoStrPxu8xa8DUgqNTFMwCWz7ZG+PXDXfnUjh6G5b7XCjTUxPy1tPPfAXWIWfQgMJfM+7LOiCNO5PcfM2LVnPuMPf1nnyh3rui5HfyRsWaFKvI54UqhwBus5dSeJiIyfJpdkw3DosTVPtBbVX5SB5a2rban44j2rGhThNvXOjbyKjSBXSRD0rwMSGwo2RqZ4zJxAOab/7mtkWuXYP1m+VKxUqseq6zQyTgf2raCmKm5d4qbJP1whyuhnAua+3T6iy3BOajflNTK/rd49lSgW5sSiN0lytlTdcqweO9ysL+pv9n8xW5l9c1tQMb+/C+xhuwUQhG1NyMMP","layer_level":3},{"id":"e1a64950-db92-468f-b420-ac15fd32fea3","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"邮件发送功能集成","description":"gui-email-integration","prompt":"深入分析GUI中邮件发送功能的实现机制。详细说明dialog_interface.py中的按钮事件如何触发office/api/email.py中的send_email函数,包括参数传递流程(如发件人、收件人、主题、内容、附件等)和异常处理机制。提供完整的调用链路示例,展示用户在图形界面输入信息后,数据如何被封装并调用后端API完成邮件发送。解释SMTP服务器配置的默认值与可选配置,并说明如何在GUI中进行可视化配置。包含常见错误(如认证失败、网络超时)的排查方法和解决方案。","parent_id":"1be2325d-d01c-45e1-9320-c2bf7aead663","progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/dialog_interface.py,office/api/email.py","gmt_create":"2025-11-26T20:53:00.2745523+08:00","gmt_modified":"2025-11-26T21:31:10.0434512+08:00","raw_data":"WikiEncrypted:x2mSWaNcMj6fML/nZmoxNmKBb9qCNkSUJ2KpdlWDUwtimeRwJUPOayhRACpsV9fFoMbCG7S0mgnlc/csR1ky30aAWPQYesk1VQZ/y2b7k4xAWK4LMdaxli1kkQ0yfAWwnd07/ArUZygMjnlQraq1ERS6358TjZ0TyLkO1H0XB5tktRswktfoM2VahXjA/KbHgBOrXJh7Y2d/V7kaUi2rV0rwaHzpK9e5mcIX5fOE0ZZDYF7xYFeOLVYuZKA1+r3vQM6jOHxx0joxsikRU8QTS1x+cMJyT7rx8jKu/VK34P37eWmoWCtj+foBu82roiKLt6sxdI/DV+eGlNQam9Afbb1qO7SUf3h7SUPQGTclpgFDodbGmBx5F+4UM10MM+GiOXfnjZtdOSFBpgrbz45CYG/kzJ/YgRGEd3KU2O+QACEd3S6xX8zQT3bzg4xs+J39PYvPEVYszO1hutdaEf92TkAyN818p2sCBpF2GjoKQl+KhwjXKHrq9CkvzqekaMwvIcRbS+Ffrsb24GOy8s1R9dwSdEWy79CLoLNYEk4/wPkKrHIs+BbzpzhW9jutOrQBdmY+eenouBhVYBe93ANExEHmp/OdKWIOMLzRaytwRAa080oKFCYFQXjlW3VJauhranDUxFm/EiAwVTQTxbJVljGy6Tro+nz1vAmRgfUaqdzfcpGseNqfVJqrFlKW8LOsfU3NnUkT4RiUIEMWBQa3OCMAOkBk0afNj31BMhwYG9PjVAbwJHnLRJrwGUfPJCOqQxyfBqaWqvUNVv3zIoA8cprsxtdGzINdcY8Qa5lcZEyAKBeIyKQtlsnt/Qa3cJwJwTsW7MpGc0H4i2WIb1N95tNLTmmOXqM5MQcBgf3hsGO29zyuNUKeBwkhCrIvPCqYvoRot8dK6jCtc7Y6z8nzCodo6EgZFvNZeb7zHyWrdK41/GeY/4VRvyGSsBG/ZF6bURhKsJ+SNMdXde6IR3VUvkVCSMVOogadXk3tzDPVkIIvD7MS6luUMsZ8BsqfCZhZ4xRSALTl2tauK2JZYVp8UgMQXJ0S9hyTRnYUsY9v8xjoCx2VjvE2AV/bXQdSDMUCcDI5tU2ZCxlCwQ1YTsMtJK0ZFVr050Q0P7V8A+l0fh5/+adTazHTSOW1Ui5eE+dEFhPNPz2cEOrpfJokICY/W3RpMSQKV6DngKEe06nbXtHFZGfEi2AEyDMP5vgRCjJ6nA0ccWvqCU9JPtCRJg3cEw==","layer_level":3},{"id":"5e77d3d6-2f94-4e74-a774-25e3af8f9260","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图片处理功能集成","description":"gui-image-processing","prompt":"详细说明GUI界面中图片处理功能的集成实现。重点分析text_interface.py中的输入组件(如LineEdit、TextEdit)如何与office/api/image.py中的图片压缩、加水印、去水印、生成词云等核心功能进行对接。提供从用户界面操作(如选择文件、设置参数)到调用poimage模块执行处理的完整数据流示例。解释如何将add_watermark、txt2wordcloud等函数的参数映射到GUI控件,并展示处理结果的反馈机制。讨论大图片文件处理时的性能优化策略和异常处理。","parent_id":"c8b75962-2412-4786-a59b-a3d2969e09c0","progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/text_interface.py,office/api/image.py","gmt_create":"2025-11-26T20:53:07.1585881+08:00","gmt_modified":"2025-11-26T21:32:00.8035793+08:00","raw_data":"WikiEncrypted:8S9omGuVowFk4RVYhPXijxiTyccYmdtEWukMLtd7mSEhKcDnI0YPd4d4qVZ7V/WXl3ya/BjaSJEJPeafjmrrkStiqToedkVTPCvl+7+GgsJZ4jAGcT03eS7WqBv/deh2noTnUukJn5bIFQoIjfJHYP6z5TDx033DOF78jhh8rbJPXTHdpiiKy8x0IYUyVd0RvqKpLRGJZQVW61Ckq84NN2Jc6MTTJtp1KO8bgBJIFEa1W/QPCcNMijwVfr+0E/glszgiiFUkO5Va/YAiJqnV/eBw19PUQNkeOCnvjqqYNtvt/Vk3ImzwtyzCQAuPj+35P2w5+DNpQZQ9g8nlYWl57J+gWeTtInkBtWiAdUyqFwzVJ29IKy7gzxxnkqlmFRUyt32DWy8uScOHL2XSCFk8GDqNIeVdTIF9Br8hvNcMA1fT/8vEi++cgicHhZRHkwMl38dk3gKf9qIbA1RbSCYzbR4TzXckPzz/r3f5Hf2V2AMyrtgPoKBnlms2zZgW7oeyDq+3cYnajSj4HPs3UyZ0IyvDl36m8xr6CkX2G9KxuwL4n8eRuxfwzE90oJY89MKJ1TMNIc21BKHIYt10MfNVOrtBCE/fMAbJSY5gOTObyxie+V7Njr8bRjnxlaO6hivqw2Gxj2ZucRHTB8agpFJOngzdaAznOY7DTXN0TctBeBGDkUUcKCP4tPN6eZDHcnHAGFOvUCgNC/qft8Xh5VPRzPorvtHXUv3WZEzBsKLOkKhG6GME9iYHWBJWkLD7ASj2ep5t594Sb0MMzI9PdWXj86SkOQvv15GsCNJ5ijHc8CTLg6N9GNC1pCJERHwRu48Hc1p7wg8SrMxu2OQyOFPUAT4fjkhX1jjqnPR5Jhh5T2JfSoAHsvpfWxi4pOCH1v6vJsXfEouIyFkfzc1QAmCFX2AUSYtEqjX6jIyYV1FvokVgsjr28LBkiPZfEuuZ9N5+khNWbYk8zpKiduH5GK1Dub22PgzvtnbnOFLNDuWEAWH2eeobUu3HZ8rJYcqvcBG/ileCZ9p0QKY2PyEZV6VFEy51I0UEY5RiCz/eNXlLsU0KriHf6tH/HWlKz317WQEClmJQAqYKKG9CMR5CIk/obVzjTUqEDYw2r7kvIS967MpzNqZB1qOUXbWlzlVseXsKsKUpmkBOlZKeFxzgi3m9oSy8sr5AQD8gv+CYwCTdtvDkSNoWRxcEyyOKUhK0Fca3dhgzJ/2MlDHijWXBpssyZw==","layer_level":3},{"id":"3da53eee-fce6-448b-824b-8bb3baf2a723","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"财务计算功能集成","description":"gui-finance-tools","prompt":"详细阐述GUI界面如何集成并调用office/api/finance.py中的财务计算功能(如t0做T收益计算)。说明status_info_interface.py中状态提示组件(如InfoBar、StateToolTip)在用户输入参数后的反馈机制,包括数据校验、计算执行过程可视化及结果展示。提供从界面输入到后端计算再到状态反馈的完整调用链路示例,并讨论异常处理策略和用户体验优化方案。","parent_id":"ca6067ef-5206-4e99-9e65-628a084a2c9b","progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/status_info_interface.py,office/api/finance.py","gmt_create":"2025-11-26T20:53:11.3262685+08:00","gmt_modified":"2025-11-26T21:32:40.8469317+08:00","raw_data":"WikiEncrypted:52b+wgulExSuILQLn0mCKi3kwXM7pkA1TdJCyxilf6utEOPL8w2W6pGEPMJbNBfPc4QnlF2P5su2idQbMV/8BA0/f5Af2Mm7wmxnOuCyPFunls7kzMlc6kG/Yb1VS/DumYFPEufQZwtA0CorFhaqB3U4btPEBBIXmWzy4xQ47EhRrEpsATxNYBYLpe6WWpxZ+U9qapILxTQpmAJJZnggpwcKCYlWJDSzaI5kAtsPAAWLlXovm7abbldi8NSlQ+mM3kqzqvpV07Tu+BU4sJPfnLyIep/hWpWX0tvjvTOM6K2br8SI+NAWo97LgnhDcv6dk1kll+t33j0prYcZ6GTmDDSKEN0IFEZD5tIi6wKPyseQnmX6V1WPDDXRhFEIx4s56f9wl7DputTFcVeoMPaDz3ahizfytLuK+EOutox0zA7gmqwLjJR7pajhj7ZcTAQxFgSKgo7IG4TiHRcU4azfen4UFQamro4491HWGhxMfyCD0MZcEPrnie6LRJt3EGzAZiODiahE/OG0D/RQbqLHlVfx6IbMmaXcjGeKG3qEe/PzCXv+DMNQ9L0oMVV4QnZtcyKqv/eYKglfGMrQbAUP+rfwqkCQlAkFo0TSSOm2iP+TO8q+1AbhCXSiSMTxiEBbkFmdKGMTAfyJMr590l+IuB8SUoiCu0WDJ43XjKF43ubR9/be0dSAq/DC15tiaVsGVWRlIsym5S8ouR43UWNs8/olOG5Up6rm0s2dq+zlLPfOeULiiit42A1QsCF+P8ikl4l9aKI60CwpO6uHbUNJ7pZQRpejwOzku+StjTJZsv+fgsGmPxaZQ/4dOpG79n1RfCyW2VHEK9ROqnbn/31pJ5z/H4lt1eWz3sOe0v6h6nLd4KAsgmQgaC1w7WK1SH2fRqn42L9raidRfiwmUcMmId3sOicqzxT2s3Axk/+1bL5K4mRGtu2RwEBnbXzYvd6ukPaQPslIEMWkBxmvdhYrTgNdicEOe79QlDSkExMcAwU=","layer_level":3},{"id":"102e2f7a-71e5-468a-ad01-f1b2cc2c4519","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"发送消息","description":"wechat-send-message","prompt":"详细说明send_message函数的技术实现与使用方法,基于wechat.py中对PyOfficeRobot的封装。解释who参数如何匹配微信联系人名称,message参数支持的文本格式及特殊字符处理。结合示例脚本'发一条信息.py',展示基础消息发送的完整代码流程。阐述该功能依赖的二维码登录机制和会话保持原理。提供常见问题解决方案,如联系人名称识别失败、消息发送延迟等,并建议设置合理的发送间隔以避免触发微信频率限制。","parent_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/001-发一条信息.py","gmt_create":"2025-11-26T20:53:29.3883993+08:00","gmt_modified":"2025-11-26T21:32:14.5024131+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tF9HVCVOcGrg4cy9NjPZtej4IzMz3Ho8mmNpCcfqRcdBswlEBDuVZG2VDX8/Y2oFAwmI0e+UAcSdBvJnrDSHibn5btMMpfNYNKXa7vdxZdrcqZj+GdD6JyWIaSIPsI4/zrBnrOps1VCU00bTgPhdQWghvkZvH4PaWL2u4g4364cQNRSOG4R4nkq66EtpvSJ0QkKPdyIIXUt/XKxUYFnjGb5n7MZe1Z1ZsMqKIL8g8fIitVa0QgthbJz1zYilpI/u6lpL8Df4yl1qScQRw/Qv4a8YXD5foW07uEJU1++Ov2RjRRcxpPnduf8h5giBx/TGGT2tgdBGf5/tU+dQ2ClpWBwaEqBI0j4hOcNMLHb4wKnPubrLszm0+GS0K4PAs0C7e0knWgmGzZibjct/HVdsGaoj4t0Y5DeNYfcL54PV9fLmfpfAXPedx//9itWAxIl2Q3wHR5zPY1D6UtycFk0JX0vmqXRAq6/ipOOIsEHb1n7QjT2uJ2Ay40a1LInvGcv+7T+XOCCgNytOpq451l2Qzw4JOzwCRVBzHrUWP9hrh8Ipx9pGTbJ+Ij9ZrLzsh1Ivtm0VWXDpRovtBpqSUa6pJdiXLacl3nPVuwyWhLJR35epsHlsj/yHv63jdf62iSI9U6hblMIBtobIvFHAcfuOSs9uNFZ13QuGLh/BwmtOArtH74yGS6534YV4D0leD8kY1ynp2c3UFjQ3ObJ+c9WWKxQypkMQmbbPvMqWXZPAIWXR4KSDOq2k3VD+vtVt7QSLc+R+oLGzR999b/N4xLAR88c1wnDyJcFWhynjTgV5to5z22wWy9qWR5ApmTyp0GW1Ge0069pg0JNDLNxna1F7vrmYV3PP1qO3oqUcs05vstt9z/ZZe6XA+jiySl1zZoQg9rqplX6bDxbq56WcTJTzV1q0767jNGQSVVqyVn4F2dSfpA1kDJ+zYZ4rbWGpLdu347UCB6q+AeWRkClXF7B9tOMz5SrqOa297x/4EA7+VSXi0D/UqQiYPmPKNwqekRAs8phdRQjTNhpzoFrlOvMJV0jCYffvuQDSsLiK2SebzuUXrt6mJ0FZeOtFnJ6zHhA0Xb1BX76B0X5ZZW3FCA5u7cKAPabL7tLqcq+NEM7W9AvylWDDmtBM5aAumoq/D3Y6tA==","layer_level":3},{"id":"d681de07-c2c4-4428-adae-1524ba8f2379","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"核心图像操作","description":"core-image-operations","prompt":"创建核心图像操作功能的详细文档,涵盖add_watermark、down4img、del_watermark和compress_image等基础功能。深入说明add_watermark函数的参数配置(如color、size、opacity、space、angle)对水印布局的影响,结合示例代码展示不同场景下的视觉效果优化策略。解释down4img网络图片下载机制,包括URL验证、代理支持、异常重试逻辑及文件类型自动识别。分析del_watermark去水印算法的适用范围与技术局限性,提供典型失败案例的排查方案。介绍compress_image压缩算法中quality参数(0-95)对文件体积与视觉质量的权衡关系,给出常见图像格式(JPG/PNG)的压缩性能对比数据。结合Pillow、requests等底层依赖库,提供安装兼容性指南和内存溢出等常见错误的解决方案。","parent_id":"2add2cae-512d-4dec-acf0-6cd787932142","progress_status":"completed","dependent_files":"office/api/image.py,examples/poimage/图片加水印.py,examples/poimage/下载图片.py,examples/poimage/图片去水印.py","gmt_create":"2025-11-26T20:53:30.6714231+08:00","gmt_modified":"2025-11-26T21:33:26.2115505+08:00","raw_data":"WikiEncrypted:NMpG4jhY8r9zsYBp1pIpU+Ulz3qKf0gHZA3rFZ2WjjlhR4EcA/jagJOBSlr2hPYn6foOHIzFFkDcACFCMihOLM6kpE7mvlsZG53O+1AiXeGXs/BLof89t3CVbBthHaIAxVnJUI0FJpDsrPfYrSEFmbn/DfarNCCHlpGEu244emuJubBq8wprc5l/yGqvGCjTIA4Zd553AdnxM4IyjNKxsufZBexed8GBZ51rUsgyVBxUlm9OQiF59EUkQkd6xhjPPEz57dbBVpc5VsklsvUkapQU7zuMdzael/if6QOSXknSAf42GmJqBz77tj1NiHeXcHoXsw1u2ltnk4ZgJm/ugrJJtD6vIyboJDJzSAkw6jUg3wtEISfRgeMOWGs1WEpNN6IvYwed+8q5ziWK4CxFZ9RrzmyoOiMZkp+JGPtNJbBqt4De6d4xstR31DjoX+FtGS9rUAfcqzma6pu/It+L7oAE0Hl8kKAezz5/B9o5nDmnmrZxruYJpnss1hC0I2r079LYpAxPFuNsQeqtC+r4/HfpfO13LC++IX/FZRir2arWH/kiM46KueWS6MqLEDeSes6Yu4uwbg/vIhIKjq83Z8yUf4retKBQPqt1URsU7wzvXGVkupEbev9BGStRu//BCqAHDjFaKsP5GFzimJpAhsitUAxn++CLCxBNfdW7x9vDGs5YgWtDS12HTSa5W/Qocgnmf0ppdmY904OvFeMIhcWaIYZRhZfQKlyXJSIIVsGXjD6MdyzY6pY9T81syR0oclJ87MPLCeJy1jTkbpzej9VdqtwEANYq/n4tMFu50bhaqYU+LSdpROVsOGhdnpsnWS3nz4zhmYYhEJdLc3TiCg2d5HkTac8SAeqphWBMm3l2MRds0wbIU6jMbYdDYVJdQy3SE+GcN9oaHvoo8dg5b+c1Yk8VNRmO4hLI7+r4n2SGrhZ0rU/b7H9aDUYTEikyENFTP3lMJDXLJFjQSVVlkGfHnj+noY4+hQG/AjTW0M4SrXw9KvJF7aZ61ae7dqynSLkKIdUlkGWjOJgaIFjNiorlPEtwAmf6r+6osMF3Kmb0fbTwI+vHZOQtou5JNBPCr6gJOn55IFE8Ot5H97X0gzkqPmxcknbQ4g8cGbHuvpNmdfhoHsq/kEj45tKYYGzKkYOtBEQYK/h+1NAQxFh1zDrndZKWAPICSc3mmDbB+DaZQ8WsqrhCXECKIksw5NG8kNBZSNqPh5+kOud55mtUgLtDhW88cwcCOyEurKdgBdIDxUl160jwuEGApr3mtNf8F2XM8PkdsLO94DKsFgGK8EVNotcn3X8hhW4mQUWQEjXy8hSKCZEouvwhxqoafJZrzWZVtmEYyiAoPrPUgn2dzS5fq5dXMHgf1hXMg6Gv0pQjB3XUHVEpsocd2S5dr6AcssSnhXk2n1buZliMjNziADdtar73QJmOoA3ibcuveTdWwQ/BOcfepZtWzfgwEVOd1Dp8FmlfT76R0V0hKQfWDgyAAV7ZmsUL1xRfgwtrXBVPuYGsD+PsXrrcFwyhGzN30gO4IgX7bzWT0cqqqcI5s0kl9Tsu7UrywxhTXFFiOBDA7TuMGcuVyoW/LoIImgRNVzUE3nn/PB5pXD7kBsn80n8VL2IGNqp245mfwu1oYQka5eIT0fSqr7B5MfjlElstNeIdhJWm5ueoQ/GJn2GveEzvEAKi6m76W6/iUWeUDlE=","layer_level":3},{"id":"255c772e-d376-48c7-9a2d-7577fed76ad0","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"关键词自动回复","description":"keyword-based-reply","prompt":"开发详细文档,介绍基于关键词的自动回复功能(chat_by_keywords)的实现机制。说明如何通过字典结构配置关键词与回复内容的映射关系,解释函数参数who(联系人名称)和keywords(关键词字典)的具体作用。结合代码示例展示在客服系统中的应用场景,如自动发送报名链接、处理常见问题等。提供正则表达式扩展匹配的高级用法建议,并说明当前实现基于PyOfficeRobot底层库的封装原理。包含异常处理策略,如关键词未匹配时的默认响应设计,以及性能优化提示,例如避免高频触发导致账号风险。","parent_id":"0d3591e6-05eb-4c99-8c4b-77afedac49ea","progress_status":"completed","dependent_files":"examples/PyOfficeRobot/003-根据关键词回复.py,office/api/wechat.py","gmt_create":"2025-11-26T20:53:36.3500974+08:00","gmt_modified":"2025-11-26T21:33:51.850633+08:00","raw_data":"WikiEncrypted:nw+4BVPr9Quqg1OIBceJE0ehed2m8PzoHaPi7XIOXEKkxkolwCPr29dv4bLO2UL+Fslxwc+dtGFA3pbCYUq/v2utclx0aNSS7dlGM5PGMNE6oSgBqOkYSCmuDrdDrChQvRyYjUOKO9fox2c3O+Evwm3EyyAdWBAqYcY/WLKl4dO0ADJb50oZ9vKPxHiuolQczB+linFJ3sc/nliPXs3nvQXILKhad9zEetxjH8vFWpqbu/QxS079SFMnUa8vrr9qgCRW3JAvBWltE2iyHhTN4soZQcFQgo9EummOpd/SlyzvAgl2PX/r/K7ImJZzMgBQKzgZaSo4sFSL/gK2Jrg/KqoZmlaAQOSPPRXpx5XdXMyJjar2Wco1Je3pdEnOq82wgb1/JpM+JxbV1EQICrerN/3RenJ1d7F5Kw39W3epIcNFDsi/IdgJ/Rs6qul2BB8EvenObcRFiKZ2PeRj6B7JugSj2jOIPmKvjn2wb8dKzzH/LxQ37E10PxbSZOyzovl3Cc5OO3IfKf6RJ2cUvu+PqEIOYxbdZEASdD7dQQlk/Nj7QXHmGs5OxFWcbOi8wd89TfPtzkf4B+4+4ucQcu+/42U0j5beGLntYmdMiIdNLIPu6hxCx08+TWZW1hiZcypG5K51OiAICaOp3N7yGAuXHBa3nHcTESRQ8PuChcsFD/g9CVG5CQXjSPNszYgxugRv3PM3PC3ZaprSfhc3dIQ7g3U1Ht/kY+0KVOnFkpnsxSHipKCQH5ljEUv1gDEVsyKq3sw8mtrSPgzdjgofBmNgOMcKmbrqEASANWoMyX26kiqJxLnTiFBkYsdCF9CR6tlZWNCxTSDmrkiVo/j/1rkcKhNezP9V5/2X845OczxbnCTORNTBj5SKd4KzPy3dzTcEyOO2eQxjDnHlzGKZCK6hBvFwKjLYWyceXnCa76g617DgSWrgnQed0mXy3ODYgI36AezFfh5jCCkIt0puznMdNcNCUugmM/C60e142kkOIRHkNw9AEr559dRL4pHu0fRTvb57bKDwyPnnu1mfRlHl21OspyfMU5JV5I2NsharJ+6PpDVAJn40zrUpdHwc4AmZX5LsSStRTcnzFaBeIYgKvKuLidoYtlSTUA4JvbzbWP8b9IPe3MStF+7KO3xvPRCthZbG3FE3vw8CPdQ5M2w+HADjCnt1VXvYEWOAWVRdzlvBJ5MgQpQxnyrTeg8U13i6VX/69RAYerA+NK35L3P5MxkzsevjwRN0K1X3GWrwakTupI+Zpen/t5yRIzj5wJHz7e2K2FpXfynHEMi3iHkfOe64qIFRrGU0qz3neg8lTZgl5iMjcWbJZxX+EmNd5LSD","layer_level":3},{"id":"c44e2b9e-7e7a-47b7-95ac-ecff8b8c3873","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"合并到不同Sheet","description":"merge2excel-function","prompt":"详细说明merge2excel函数如何将多个Excel文件分别放入目标文件的不同sheet中。解释dir_path参数的目录扫描机制,output_file参数的命名与路径控制策略。提供实际调用示例,展示相对路径与绝对路径的使用差异。分析在处理大量文件时的性能瓶颈及优化建议,包括内存占用监控和临时文件管理。说明该功能与pandas.concat的底层集成方式及其对文件格式兼容性的影响。","parent_id":"2bea2dfa-9a57-4c02-9f82-5f8267fb5caf","progress_status":"completed","dependent_files":"examples/poexcel/合并多个Excel到一个Excel的不同sheet中.py,office/api/excel.py","gmt_create":"2025-11-26T20:53:43.266618+08:00","gmt_modified":"2025-11-26T21:33:54.8856472+08:00","raw_data":"WikiEncrypted:S7kEndY/dAdtskAMee7DvqJzZMkyi9ZG/BM30enRAIJoQh7n7M4xtKON8EQ/EQa4gmMu8KkLC0qGY8JTtOBcpHC3bF5dl671tIqSIbvjAUM5d3wyd5B48XfvNniEWi94bWHzx2XiPYeGCJGnwiLOSIoxIzustiYVP+HGJmJYbjIkz2nkhjnYXb16UIYiXkIl3mJBGvy4VrHaXfwwlwyeueIERkeq4WKe/gbktL9WItydyYBkh/IR/yyh1klqC5fJxvwGcoIDuTHx8VsNJanHbVTtmgoKEAFlXuZ+2poCAhaLqVgu4WwHb55Q5eKgObAVwzy/2G3Mjfz7v8u5uzkCqWm2aCMG4EStBz9LQr/WDgUGV2Rf0F4XyrtbLQg92bdEKLCKIDM04SVT2K3KdKkhUg9cQSdpd3z02fcTBJJIHdMwaZVb2JWsMNs4ULjrx4T4FvUe9R2ixKbkrBDEU6OaE3o/WX8vax4b/o5J7rfiICtSmGwv2ub/p31HLA03wSTAu3VON+YMdOrJikhgABEbrAKJ9pFYQtgOM/DLwWrgbLuAFvdWjM1VbLdNVUmtKbHE4oJwIUsbDCb3SEn7/oMKrjY54iOAw6GEy+MMV2Vyg+LM/wdd7aEAv/IvbtK3mx6ZrBAJIBQqIqWSBtFcoNM4QeU9Q9+9jFYctzZHwk+P8gesRBM1MYcKtEiYNK5p6tTzR0C8irZrQrKhyIaTdrEwwCnCFYKwwOKP5nfsUEGwLgrWIsHlgnOLBzGhlONMjokmW729sWFjrJalhj296ztrZouuX5DVnzapEjfaBwsytd89+BjeeRYTlrbUN49dXoca8Pm5BrPh7JjIGr1j6Y9It73CMZ9JItgpec0e6tYinQ22MRoffhl7MWS6nVq9eeGMzwuD/yBo5m3UcjYlv/eYclIjlnnz/tWawvzBkeNLswnP4NBSBSIaPQODyUSY2SMe/vp592nyTpVbufL0C2v/smaqxSmXwfmYjRhcZV1v5N4oRIDtIO94dpWISygdKRnZMBbDl8j1A8lBDDKd6zYjQh8D/omPj9tqK8raALAOBw7sYnOAh0PQ4WgBGpavhDab","layer_level":3},{"id":"d640bbc9-b47b-4a12-910f-3dddb8b96cc4","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"按工作表拆分","description":"split-by-sheet","prompt":"详细说明如何将包含多个工作表的Excel文件拆分为独立的Excel文件,每个工作表生成一个单独的输出文件。解释openpyxl读取多sheet的实现机制,展示如何遍历workbook中的所有worksheet并独立保存。提供代码示例演示文件命名规则(保留原文件名+sheet名+时间戳),讨论处理隐藏sheet和大文件时的内存优化策略。结合实际场景如财务报表分发、部门数据隔离等说明适用用例。","parent_id":"faeb2733-9b92-4fc8-83ad-70bb5688ee30","progress_status":"completed","dependent_files":"examples/poexcel/同一个excel里的不同sheet,拆分为不同的excel文件.py","gmt_create":"2025-11-26T20:53:44.1034871+08:00","gmt_modified":"2025-11-26T21:34:42.9885528+08:00","raw_data":"WikiEncrypted:6Cd3HTNJl6XP3zH7snBMpXsQfa4kYg+vZOYpBS565zCXxWFjHnejOWn7iVSnwv68fYnHL2QlnVJzopzdgJWA/B+9abHoZbY+z86hBhaxl70mwdOWwIKVxuKOqa/4RLud2K+b9L3EGA3nEU22aGplCEx8k0zVl4UMCh2xAdkvG3/Hgjy8sboamBPZrjT6v6N1QI86NLCRYg+x5hpftBv8wvU4W4RCrtscwfUrWpiAqhXO2mOGWUZvZF811AGICQWawcPhf/3A43BlTPTDXL8cRwdfGCLRfjVueCfjKrv/wizPrFc+tlHNjJurVDwmVzBPu3aIyAuY2CBBUaeVOTop2N5or5jSdM5nmq11df2j7JD8gA/kE3ajbGtnOoUKCXKBfJ8UObRGG3qplBsjj4bXLGH0xYSU76JTNaDw5hwuNm8veBZ2QE9d4YUHBpviUYxQEufFsCH4tIm2dSDCnjWQOrHfgNxU0Zc7c598WdBoShTZJhcHhKvGZAH05YGgr52t16M9LO+Z9OammBT/MIhDFjo+1DV89aoaIsjlIZjtCohURc60iAXZ/iCe8SOFeEbV9QuJ3NMfQv02+jsCdceJfMfImgaOK6WbRKcLWGXuqA0s8GXP7zdPFI1zH4pT/UTxyVJb/5MigKf2+WfT28CBlVCG9BWU+Su8kpHYRg69xFlLvZdTOr+u231X6YlN/3Ty1ESuHnBs+XjplSjU5cu7lgZnTT6UEViJZvfebdFa0h01wFVYuMm1WTwoORtXQL5mVpkG58zbztjjkEvmTC+hlhEe6H+ofadaXZoNxonGj+ccrut/HvJYQnXK8HU9JFfJNiMFQLtysmpBqCDruNKnaoH3YsVphDKWINxATB3427k4FjPLfx1/2z/r1kfxTlWZb3Y+3l4cMe2AxoiJo1ibqvXDp/6zSAIGRSW9muYUekxoshsr5iO/7roZYgG5w13dIa6wm8wijGEOCpObDsr+YfTtawGefJtYEqJ2Uw5yJXjgvkJZFvtLSR5LJPpp93EobtEt68mLwhPUyppVpl5xD5VEH2NMwxhHH0fwJesD2bVq4bNeFNm6phG53q2r71jX","layer_level":3},{"id":"356d68f9-38fa-4840-a820-b88367331c99","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"TXT转PDF","description":"txt-to-pdf","prompt":"详细说明如何使用`office.pdf.txt2pdf`接口将纯文本文件转换为PDF格式。解释函数参数`input_file`和`output_file`的作用及默认行为,展示编码处理机制(如UTF-8支持)、字体嵌入策略以及页面布局控制方法。提供处理中文文本时的注意事项,并通过实际代码示例演示从读取TXT文件到生成高质量PDF的完整流程。分析底层依赖库popdf的集成方式,说明在Windows与Mac/Linux系统下的兼容性差异及解决方案。包含错误处理建议,例如输入路径无效或文件被占用等情况的应对策略。","parent_id":"be0c69a6-6c67-4442-958b-7c6fb66891ca","progress_status":"completed","dependent_files":"examples/popdf/TXT转PDF.py,office/api/pdf.py","gmt_create":"2025-11-26T20:53:55.877152+08:00","gmt_modified":"2025-11-26T21:35:22.6410418+08:00","raw_data":"WikiEncrypted:swyjfGYfJLhr8NM7v1ElZe198q2yxULY+/+5FD2RRMEWjRSaqrKZ6nz1fzuTG8VmHihLMhhGoKr7SykyEav9zCBkJ9/PoGcZ16AqcQL1oRayMO3HjdD/hP8/ED2BS+UNvgfdQD41MfrgufvqMS+45RenkYk3Z6QVcmFTQcHBAeUW0dyOaKgRNmd9xMBwkDJI45hcG2mYzypLrrDR7a8ZZy8f4EyZfttoQUBQ308aNvPcX8MHHr9MrItGno++4YPHhc+bopDV+JiAg2h21veRMJOg65MtcCr3UNMXjoWsmWsa6bkVE3sj7dHAHm2JpHIVNvYh87DhaaUazVicfF84eKdTBDjtIR72JCdtI4j+W2cBtPlCUL313ur6S8UXtPQW1xo/8fevgWD1QdpjZLkjWFhscg3VClQiYXMpeztFDJR9mIjibTYL48U8uYqLzlSXngNPrT3vl05oHgd2SzoV10ZVBm7w834nnSb1fBYnddUwDntdli3brCmQrWAwFyCcQoHg27fodjKMNGVtTl47c/CvimDwVvP/TNwQhOldCVy4BZrhfF/9nx2n8lyG4bnOdQQuvk/0CSWWrFARPjZN9JWa6DGOI1z39dt6bvOu8mb+yMthYxN3qYDcjZuwbUKbVDMODRnyPYMbSBXI2S1guxKIzKKXtfuwENaIPaxEhyY0qfWR7n3YMthOWIUHUyrtoAqVTfQbOKDqAXPlZsJbNM7wqMmg1xKTjXa0UtTF7+jCH2EiaGLQ7AsqjwWPG7nN4waB1/3WNucEK/4GPk1laURAfACYfSpmCE5qBUSlh5DZtr5gYcu+mqSTPXxGNftKYYz7wNc1HFO2juk8rFW2jNSmqSlsOvGB2AGUxGgvYWiyO0I3OpSHxPeTnJyDEvQpjHfnIK57eCze/wAu5wT2d3wJ52VS0ow5e98GdtkavGDd8dU3tIPztXIcWCmFZwYCIzn2KRcBN2TzuZAOoZO3o6NczSyR0F3B3Q3bK383EY/kXVJc1FuhuT4wKgWqsaQgD2bollKa8oMoL7YsTnoNvhS8/wZwJx0CrEAvjEV1bODn7iAdJtwCpFSlBzpv7NwlBeoTcN450P/61IBZsWYIGJMvShlG3RdMUcco2PZafuee758ilMIaWvAkas1HDXIV","layer_level":3},{"id":"c9fc6984-6a2e-409b-94fd-559d9f7bf4a0","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"安装指南","description":"installation-guide","prompt":"开发详细的安装指导内容,聚焦于如何在不同环境中成功部署python-office库。基于README.md中的pip安装命令,提供完整的安装指令,包括使用阿里云镜像加速下载的推荐方案(`pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U`),并解释每个参数的作用。说明setup.py文件的角色,即作为setuptools配置文件如何定义包元数据和依赖关系,支持pip安装机制。涵盖安装前的环境准备(如Python版本要求)、安装过程中的常见问题(如权限错误、网络问题)及其解决方案。介绍如何验证安装成功,例如通过Python解释器导入office模块。此外,提及项目在GitHub、Gitee和atomgit上的多平台托管情况,以及如何从源码安装。确保内容对新手友好,同时为系统管理员提供必要的技术细节。","order":1,"progress_status":"completed","dependent_files":"README.md,setup.py","gmt_create":"2025-11-26T20:50:26.6657176+08:00","gmt_modified":"2025-11-26T20:55:08.3737138+08:00","raw_data":"WikiEncrypted:6nDTd1wU0hYJuRoAJhne4fiW1+A9k9ICuDHtRF13pCGqmePKzDATTc2HxkCI5JsAj8ZcaKIqH4sG3ObbMtsLNZApF6d5RikgRdLIYiAkKClexI9FHHBObnD7Ta6pevHeUcY/5ValaM4O6I0oFvg8cI8K6z+Mdq1r5GX4HJFKXpGNI+/FMtOCuA9fzJQplzSawH2f/7tokWHZUqBRQQ9DuufkRujy2wMRvTS8TLylyxaQ+VNfvsSObCHwghLlf4jzIWA3ikOvvHvIXBhoFDzkSGgiKNiN8xgOQOQ/OlZIDueF3L4GChyHidi0Gva5X+7zHSZzkroLQ8mWQby9yGi+4Bmir1MlDLupSgk4KKJ3TJzXnVu0BaFavHk452/KtGkt9PtuzBhmQPozB1Kk1oixDUSD9W5c5M8NzgAn+U+Ym6pYdT8cM1MQZHRX4MhgMaF/1hVJQ2tMuGvUR/0D7LfCPm2xyRcFiW1eUkRN9IjmJhq9RrHZfks797J8VcaeCeP5BXYF3PvMenmPjTiELNaANOgi6BN20qwp8ds/YoX3KCTMqGHcNx/JOPr0Nj2UZSo40Kcjv+65Q6t8DtbR7qGgSPiSn0wOH5S+EcyW8h8F6EKa2m3zROmVGmyhB6iXNUrCppzNde6TFz1MjsQ1tRki5CCDUl4/9a7s8w43AxjiER9mIMQ8ougl6mDOVxEI11btBFPB2TFPUUzFp4pCP0sXJ1S167mX9N8uaV5n6t0Q8H+EJ3FMRW3/3ECzVFm/o/6VfqN4xZQygX5Jwo+NkP0tqTz2eupGbM5L2vNRAMMjSll6nDu/O0FqXdZY25aCry4Oufvy0lj79yQDqjwkUmOq6ixfDTAsbO2mNQVV7hP335mX6VZ822znWOVjBh7HcVMXTyW0SH8m3tfEGZKNFFsu2ePDbvkx1U8Zz7T7FU/MVDJRBNc3GDufdCUE1XPYlKGv9UZC7kqOmOgfvuFAtfx2sGDeCX5EvrUcEOB+zeoaQ2I6v6tMP1KDA5AJ3poowhFFpyRIy7gOdChjP+9y9LSJ6zyCXi4SNEMT36Sc4PPzcNCnJVaeA+qQFjYR5Idex3wVYscrzl6D7WHJgMUdq9M/OPejyXh5vozshbU9byLI579wpeNzXwpL9L7sdIHa+CCJuSvd1VvN0OpdDe3GFK23+sQLl7b6eXggjWU4ts0KGyHzJ9D4jxcHK/CooY5iyeVoSdxyaTvIxOwvUXP9csKPktzdcpC+vEMW1tZWSyYU7y+oA+MNiSrjYEkSlceUWzaeK8Lw3OCA0Xom3VO4aIWpiR+vzP/cY6NkoNw7rLP1Hmhyhcclh7V6DcYjdHHXrjSVZ+cvNxAizjD+gHundT/6FG+Z8XelzgDmZwI4nTuux1wppqt/ZevuQ1xrVO1kCvpawmMFTq9OAsr0IOFoXBPKmC9gC029401CIhP0mZ0S7WlTMArWeWyC3ePXNkv4fx1rzIYUT8UuKyFLMujZdTLUqWPMjiwUb/t5AHDrHfirjcz4TcGUDksDh1IVI7hGkGWe"},{"id":"efdcccf6-6375-4180-abf1-f90510945ed1","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"核心组件架构","description":"gui-core-components","prompt":"深入解析GUI的核心组件架构,重点围绕MainWindow类、信号总线(signal_bus)、配置管理(config.py)和UI组件(如link_card.py、sample_card.py)展开。说明main_window.py如何作为主窗口容器协调各个功能界面,common目录下的工具模块如何支撑全局功能(如国际化、样式表),以及components中自定义控件的实现机制。结合代码示例解释组件间的通信方式(如通过signal_bus传递事件)和状态管理逻辑,阐述其如何封装底层API调用。","parent_id":"bf12cfdb-30f2-4b0d-bc87-c1bd097570ef","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/main_window.py,gui/qtpy/version2/gallery/app/common/,gui/qtpy/version2/gallery/app/components/","gmt_create":"2025-11-26T20:50:50.32501+08:00","gmt_modified":"2025-11-26T21:00:46.8352221+08:00","raw_data":"WikiEncrypted:5do7z9I56YIENhLqOIMjAXI0ZJxRRqDv0sybN8mGlEpJ8MJDzvBN6DBSrDRC+PnPSvYFOmumM6bRtfvn1fmkghRolkcUxB0g58xgOUV3aaDTgHhauBbkquwG8aS5evxIkRCwuVTj8b/ZPNEtTJ7tzPaf+n7w1sZ5EgdRcw2XRf5+QrKoWsEY1d5O071ERhjKyrVAJVFuEprQbE1YpnSU2uu/GuTKxQjMEmq4clN91IBu74aXQFoWFCIRYs9ZX/ptipPckxQrKobPW8+KGAxOhO2zA6oisAIb/pAbHJ5aYEBiA3uFKedcYhXPxhs4r+pjPOd871mj1z0szm3szjzluQfcM/BOQTbmGjSOXlWTeySbMUwKG0+Y6ldrcL/3eDOhhtpqzUbDURJ8NMzHVxEi1dze28ZUHg5hBC1pawVB8k5T89pqU/0hzUZAcl2gEENwg9IEdi1aUoJ3oWwIgMFJZKpqjrhCJ55UV/kGrBjeVGaucG2/2XvTg4DS1DNBYoRVLY9DY//wUEJh/dzjd9XMDOYPoogjcO1N9/vzkvE7ikNiwyGa22PZ+2KB/h4lHV5PIUpgZ74zNs4EdW/bPcoFDTOVX2v2vLdM+mFFMY8xJ5iRPa9VoN7Bpn0RbCne+6OM4bCN3iUYQ50NVSxsNjaSx12jcylF8tI4ipF/MeSqqqxA7RvFJvdtGe/FJ/SWg9zck7y6dJJAI66Ai1aE7oEob5aCV+1L2BFFt0ht/4ljjfBJZMbaERA080NZYlGLL9FK9bOUVxOFjAC4PzFwFNuq1m2km4S1bvGLcSPinxandFUBfacTmLN6j3g5c16IQAQHSxTMxzOchY++cq3fXllt9s0wLMpkGPxfkL8hiRZvLVu9kYEAZr18yDhxMNbWnAp/VH75r6PZUL0x3+U+60Qf9z1nqJ+K87B1iFcFHVQ9b+k4X5NlU6EguqeZy7o8msnSx1ZDIm8I0bEdQ1jsuXcq3qlha/67QwKKgHjNjmfTkh9lvgRNWJzyEGWuR7Hmp0+RntoyjUDXzLrQSAQhGpehAfrPuCOlssNoWcjdPKkVtw/2Kgb2HSl3wUXTWeBVZZFgXWJZf66uQV+Brp7qSlSIW98OnVnfPer5BrU+35mbP/I3bs+iaXnIOJxMUYXRAwU2AYxoh1DrORZWaft+YtCijgA2xuo8MlDbm2g2d9GMNuA2X9nHX7vaiXzV0CguTOvFIXSMdTGqBwcTf9ULX5NM57RprgOxqivrN+H7MLOHaoA=","layer_level":1},{"id":"cc0f1364-c170-4040-8c52-4b79072b64f1","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文件管理","description":"file-management","prompt":"开发文件管理功能的完整文档,聚焦于批量文件操作能力,包括文件搜索、重命名、分类整理、列表导出等。基于file.py中的API函数,详细说明每个方法的用途、参数含义及返回值。引用pofile/下的示例脚本(如批量重命名.py、自动整理文件夹.py)作为实践案例。介绍该模块如何支持基于内容或后缀名的文件查找,并与Excel模块联动生成文件清单报表。提供常见问题解决方案,如处理权限错误、跳过占用文件等。内容应覆盖从基础操作到复杂自动化流程的设计思路。","parent_id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","order":1,"progress_status":"completed","dependent_files":"office/api/file.py,examples/pofile/,contributors/yinzeyuan/SearchSpecifyTypeFile.py,contributors/yinzeyuan/output_file_list_to_excel.py","gmt_create":"2025-11-26T20:50:56.4183222+08:00","gmt_modified":"2025-11-26T21:01:01.304732+08:00","raw_data":"WikiEncrypted:PS6QJlpgHxZyZMwNYt1TRIloRD5fhXuA3TjWW/zG+yEBfw455kj5VhGSTNiybiZ/m+py7Usdy4nWTAcvwlf3/fQgCa0WXYWGyMCWEgun1DtEc8tuYjftH9JMXHp54oXmn+oW/aoSCA4/M4BCzgAZPatj37M73N5oeSMQEE1X87JETUQUfsY0fpz2Wq+WsH94qk4NGIL1TE6IvdxWEdlpvGvSV+Ih+5LTGG3nvnQuDqnTZt21ODvymbzfLSasyMQtdqKrJYoOkWW/TCpRdpFag+23OAb0OQyvIIa+D/21U9dDXphE9OPNpZ/qKCqzXCi1v2LwifQNAc5zo+Q+aGSD6KrdfNUgyvohBl/WLJd/LFowK0xTT792G2ETTN6IEWaachfyIoihBuJpPbwKN5qmQN7r9ZXCG9IlpSESf7mU7984iccryvVWUFrljO17aXn3/2JtDRrvhczByY3dkhQoUHIjYvdiBKnlJ002Q2fRw7YfYV1A0haY7eqioLsq4NybzUKpu8PXfejjq3DqBOGu/GU1ptz4sWgGD1c6wuRRcgs9UKqciaLXzx1KuxA7szz8gFh3AdWd3mmaQZ6iMJBdVQxi953HwKnSnLadYQLBnL9S7O+7duBOpwnWR1Ky37yBqil26I/NbjdInHy+rvXOvqiqgzRo6WCwbGb0P3cI5LuRRQ/4lKeqHo4AQOSE+/6/nExw+WwMGPdABCnuqy8/JnrNQOlKK03oDLprVkPAF2jnMOecA2gTubu5+dHKzA7PYQGv39vRR+7bxwiNP42Paoh6rBdSHWWCfENnRvin4t9jrGC7V7NrDXgvz6y9MBuYz50cBJrGcKEaAcn2ZulBaM0uHK3mKvYBxp03/VKWCNuvC6u678OYoSQdbvwbodqQbgnTCXAJkHC8nzf2gQWBo60bmRgNT+PE2RhGSLKFYpM1PE/BKSzUomynw/z+Mvn7D8jhvFMTb2R9iKF47M7ymFDizDBKVElTKi7AT08DhbLMYGC9kUX40cs4NUVZKszeu2WcaStYuPBhN49jF4xAOx2TDA4oxU0fYYaRWhX7d11PUZNYPWGC+03i7HAJoQRPlKz+5F6RfhqhbW0GbM7ObvXc3f7xcPe7ot+K5Vet2hX296mBl3u+yOJygiAeM1ri5j2FffA+yGd1wFqFHuesyL3ZwuTDjIO2yIHv40AT27tEt/duUSh7e6nwWkYhfUqMclbEKJhLyC+ZObWjaE4IJhBFg/1/mcf8LUJqEun9W+g/Loq6KvJK2xLVLqy8IfeuM1tuXGvXdNGfIM6zNCmCVMrH/62Lnv2ncD+xXN/uO2TuxkOIhf001bDRz/ZDUQGNDcdmRr1JqzYIoMv2+JxAKie3LfQ1vFtU74P8Z7QSIgg=","layer_level":1},{"id":"fb4b14d8-a3c9-4f17-8f24-10e8bfdb747b","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Version2 概述","description":"gui-version2-overview","prompt":"编写关于python-office GUI Version2的全面技术文档,详细阐述其采用QFluentWidgets组件库实现的现代化Fluent Design设计语言。说明main_window.py作为主窗口容器的结构,home_interface.py和setting_interface.py等视图模块的组织方式,config.py中的配置管理机制,以及style_sheet.py定义的主题样式。重点描述多语言支持通过.ts翻译文件的实现机制,signal_bus.py在组件间通信的作用,以及link_card.py等可复用UI组件的设计模式。提供完整的运行指南、依赖安装说明和界面功能导航,突出其在用户体验、可维护性和国际化方面的显著提升。","parent_id":"b38da97e-0ae0-4dc5-8bdd-d53a1218c22a","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/main_window.py,gui/qtpy/version2/gallery/app/common/config.py,gui/qtpy/version2/gallery/app/common/style_sheet.py,gui/qtpy/version2/gallery/app/components/link_card.py,gui/qtpy/version2/gallery/app/view/home_interface.py,gui/qtpy/version2/gallery/app/view/setting_interface.py,gui/qtpy/version2/gallery/demo.py,gui/qtpy/version2/requirements.txt,gui/qtpy/version2/gallery/app/resource/i18n/gallery_zh.ts","gmt_create":"2025-11-26T20:51:13.5134368+08:00","gmt_modified":"2025-11-26T21:18:21.4938714+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwPeOtCOgu45W8uAbBgOfkvoYO3OzM+anuVlhx+5Y8MwA/VRlIUnOTvdqhNWoe91nhNgkdPj3FGTEcVoHd8zEQdBzZ0fyWs/YJzuAdIh3KyzKrWuF43620DTeWab56D3yo1ICo4eHcBkfwLhY+IU5QYh7RTPGc0eUPklokDsDC8jqbZWaufEBgIu0/++O1vsyozoNVwRm5nE6oOwJGKZoPVLarv8oKZ4RobYw/Z2sxhAXKA6iq/ES/BFryp+KVK9fm4IMGGfIKwkVS1hvr8OoJ+w36gMkmNu07diDHwe6LkU1ro/I5z2zldFBJhuEYRuE2dEPXXt/TxlAY3HSt84zfaG9xmaTnc02CC+Z0gvxoc3Ux/+3fWKHZJO6popN2+8peh+bUDwiITkIajCAvIkqxfh36QUhcPN4M4K90ghnHGgaOoetaWhBHu39IjKDGiGssudZicYwnxj9/HoP7tIMjr19kOdhV6bGPE8kceV6V2NEH25npSLsiB/mz6b0lJe11kLVsnM5sjqxc5bc9UEhwGZzTLPTbPyp3siQ15H3wZSl9HJfj8FhzYXGR+N5GEcsmGch3rZLdI26fLd3SylACOLpNX6FREE6I2wOOwcZNXDDY4WAGO3iTjpz+UUkBb1hkyCI48kgm2pkGFvge1NCqBDrzegv2M+l/jvIaxsW+aZtdfl0m43y8QX+CH9jjaxFiyb02NwMuh8HEsgSGRD1WNjB5iKvijRczY8IRcpnRiFNsArz2EpbaUTfY+9tH+fXwYKq74QeXgcdnSmKOMIvRXi3LwBsa1ULgF1Cj//f6VZq3HKKMs1ZNuInXIJCTiitmDVqeAS6jMasCip2u+ZrKfFiv3eCcZ8jwa2zOrApW4ABcCtFMFyyo7D0+WEfEdUX9Ruolvnqp/hXda4q1VCGLYHOaz3tJeo/bVCxfUzcBG5osX2nDv9sVfRDaDdRG35VcHCHlhoebgFbxQrPd3D3AJzfhIh07IxtC5r5z0gNNelI8/OM4URSt9p7JfaDaRjVeuujXiJyV90KMo3NN2FXZUUjTDXSzXlpgFbc3v60nHl9e+SjiUIjCDZtEmWDwLLvHDL8JFBP3NX0qZt4kxquKbDBOXgjKCJOzEFqzQPMwYwEqZ/vULpSod4RbqPZpf09DRW52cINRebMmBmdMbgYOIXOSyywMrWecmG5wsrUo00a2F2eS+X/gylkCHs5lnvVDDZijxyK0aB2S8dkN278QxKC10SUGhoOkLc1GVXnPGNutqIP10SodX5ZnQy014YU9Kji+uSn4BGbvG4xY8U6LNR/qiWSNCvxftrHYsGGqn65axjgHfYq18PaHrm5mi8p4yx2s+JHGiYQbnIuvzG9CRrKDiSahd0i6w0/K54MDucAkMBSmlheGLdB+B+d70Lh+oc/ogZRcoOG3zdM5TbIsInOgaeltkUfAcWLyxrIaEOBuUmUZ9+2p3BRKdNGae60uMs38xu29wAmnpQJOudp2BMyN0xqIOLWr+GCfF9D41AtExI/hsYJyR9xJb6nT93bo5nFZA57U7GdW+fAqnVnHUr1qA+3nLFl3pCW4A5PjFZq6WkXFbffFQvpa7gl8tqWsmc71ZV57jRNADjrrxGjA9LLLE3wPa0PUab5JadqpBcbEi+F2ikj7DuJwcwcK5/PsFRN8JQqqOjjjioOOsduAXUwP8f0zqpT2EBLna6mEaqZg5HlBdMKyTU5N9j7QSb8cTwX7oPF+DFFr80bm9zvhghXHUm8X/hWIrFkYWqBuVzw/uOMOhXa89jsAdkFDhRnmOvxfP14ii+dDtLDvPAcwdv9siHufBRcFhfeMFLNnt5AXocoKyC93WOyrvxizd/qiA8NUgibFmZ3EkOxZwjej1vbnvHbycmJdPrPGWRcRHdodLaDphg7K3LNM3tuEhIu8oO39cDEXs3WyJQgAMt+oQY=","layer_level":2},{"id":"77600606-641d-45ee-b403-76dc1f223258","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Excel API","description":"api-reference-excel","prompt":"开发详细的Excel API文档,涵盖office.api.excel模块提供的所有功能。详细记录create_table、write、read、merge、split、search、get_cell_value、set_cell_value等函数的接口定义。解释每个参数的用途,如file、sheet、data、header、start_row、start_col等。提供创建新Excel、读取数据、追加写入、合并多个文件、按条件拆分工作表以及数据查询的实用代码示例。说明内部如何使用openpyxl和pandas进行数据处理,并提及性能优化建议(如处理大文件时的内存管理)。解释该API如何通过`office/__init__.py`暴露为`office.excel`,并确保文档与源码中的实现保持一致。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":1,"progress_status":"completed","dependent_files":"office/api/excel.py","gmt_create":"2025-11-26T20:51:18.1844023+08:00","gmt_modified":"2025-11-26T21:01:52.4546856+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg2MOFE6WEkKfXkaaaS8f9cjV55aojpDUxiqg8Th94qFBnOGDUHUTsnTgx4X6RhpNVHBkJXyifD59aCHZLOk7nY1N+IQtqnYlxAcanRSSCKtVikUIwHDeKsstg0WrbS/4J4x+MZSGx5oCi2/yNRoYyPdMGlu7z+7LJdyPMGQPocA0qUirLpiGk1Kv7L2+PzC348UxLYg6uLUt2JqS0AjfdSvKpdFZPFPgPIyhiej1sJOKPihshMV89A6LP0K5Xz2hJhIh//+rvNyGqdjbkY9ZIaxRlmMqhz+y5UZIVyI3CqKxUZtj/sKHFiq3Q7B/zFEaBolahWNw+Fa6uTeZqRRs0YWYLJCDr1AyAqbxUj/7aanZ9Uiy1YexVoDRNVc3FKj+1cXcuHgstWdXlpVP3XgpIXMIfD1D5YukvrtO1IcCNxGEnDU/A4RgfwaYqZIVyHkOVkVn105zSP8y20a2AX4asGwgbdgReKlOt7koekNKuRRZ6soxWC8csFRH67Z6zMW9IGdVSKOTxtU8yLi5E92i4QQ1s1yKPBz9FgPvLP8388Qrt1U08/Us+xR2GrQpO3V6YlObHcddD6S7ao4qshlKfYqCB0iBcZ4Z3g/0Ui0z4TWFeJkNHpalYP7pCyvR7WhFydYC3+dXxxHSriU8kQccq+O6Sldx4tn5MKD/lujInXD9VImo8S4yDxwpLZU+IUCCv2V8ZnIH+DVjGcAoeaJq7SuIwhvk4Zlo/3oGYW1KqKiYPGVyeLKygBpWz6g7NLXL/bbIOxXwM1mXvKx8APWmZnernEPiqPT6RB4Ayi+2knXLqoiSa/ltxk0SolggVsDMlCO5ZBoSZXfn0vXWgMCN/pZF46Bg5EB+iZ+S255QAF1jK3jmAQXPZBdpowCYK0+ZzkNEm0KR9fWQ2CRtfCInuLKzzYUI3b1dBPloTtX7UzLIc1JEiCDCTo+t40kU96wq/ne3V7qIErxgNhChqve8BmNkxApr97IsM2hgmk8kLNKpPBHKZ8xQvpdOeLQI9jQEmYauec523lTqWRlX77p2rcYgllz0YiYW+VBgzAHf7agCtIzWCP0fCwdEpuagJH82aWHtKDnjKjl7EcSvGQHOV/LzZ3eBTOelCapOFOG3OVhP3dE6Y0kxyfoYz7dfeNPHcadylfm6aHckMA7jzaIvmvCDmxJKmxIWI/meUEGu6PMHBgAGhj+q8VmJv1y0x8RmVSmyDCxcR0ks3z/ooSn5+8epjz2Gr56Oq5+EfBEfo1wPQjclIUOg+8+6Kwtd7SCVOrLlGOYVM4tjFgbYTxTSpa4=","layer_level":1},{"id":"3aff6fd1-b9c7-4eff-b8f5-26462a3f14a1","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Excel处理示例","description":"excel-processing-examples","prompt":"系统化整理所有Excel处理示例,涵盖文件创建、数据合并、条件查询、批量生成、结构拆分与汇总等高频办公任务。为每个示例提供清晰的业务场景说明,如‘根据指定列拆分excel’适用于部门数据分发,‘汇总100个Excel’适用于财务报表整合。详细解释pandas与openpyxl在不同操作中的应用差异,提供性能优化建议(如大文件处理)。包含错误处理机制和数据验证的最佳实践。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","order":1,"progress_status":"completed","dependent_files":"examples/poexcel/创建Excel文件.py,examples/poexcel/合并2个Excel的内容到一个sheet中.py,examples/poexcel/合并多个Excel到一个Excel的不同sheet中.py,examples/poexcel/同一个excel里的不同sheet,拆分为不同的excel文件.py,examples/poexcel/批量模拟数据.py,examples/poexcel/把100个Excel中符合条件的数据,汇总到1个Excel里.py,examples/poexcel/根据内容,查询Excel.py,examples/poexcel/根据指定的列,拆分excel.py,examples/poexcel/统计Excel打印出来有多少页.py,examples/poexcel/Excel转PDF.py","gmt_create":"2025-11-26T20:51:26.2347666+08:00","gmt_modified":"2025-11-26T21:02:04.29043+08:00","raw_data":"WikiEncrypted:8x3JSVErdDUDs2nXur+vXXDHNzie9c7oAZuL8yvsXqf2580QgWFV/ytD1WJs2ztly8HvjUln22bpHK4oI8CB+AcWLpLUZzpQVQaA+6Sz43siv5vKQDMQ/H73nd3yuDc3KMeGIhUJRFHLLzZMiVOxSqfbm3/GywR2PNuKpP/eguzDNMnCyBv/2qAwg1sN2Wkh3KKG1onqWwuFVRyE46GLFcCTQux5DqesirXKQIASU8ocBjRd58JnGqICMYHp7vQI7zouuazoRTjvGYq0RSm6ArPU+Ih8J7xUCMRB7rpIjX0eVGATMRQJhngIcx92uw40PKEpnaZIeol8YMF1Sd8GlV0qnF1wD6F/97s362wteIqXnXRdYxtVd3pSRVIRT7ETpFcxwxrMU4EdA0eAoBdtRPa2kdzfzVVeSzoHOcHXPQ3+/nSr1QqvUcGgF3ycxVvfCN0DDSg7UR0Htd4yA8ps7l1HxFQo7fvqIOCTnVO3z3q7cnMjK/oNYpOTE64AS2GjbtwBeRHjvVgl0Ga8Q5nS5kirb03rXDYdtxhail2jIBnHK8UR2t+uvLxjrk8KooZz/eDuBu0Csa6+rrgHZwJ7VgJLndZsvxEmroBWJkD5g9o6wG2qM+10AofEJ3zhgIQq0TqYLkymUMZwNdlaR8yWEDMXAeseLY7GA+hvigPhsVvHbQAdk2b3KspKBc3UDs2n4i/euAR7RiVgPXKSyLXumVZ7gmCJ44hVOpWkbUlXC5i0ERbEcQ36XoU+pcI5PbEIAUchWiSPt2imDftSMy1cmwqvUjSr+CosA8rXHkZS/5RIgtk7LtWK4vEeserJQgXfr4Qm1+whYecUxt7Ej7qbULCciIFUbsTppV7Nc79tCaK8EFz0ySzfG3vR+n1uMnsKkl12yOWuEPkzD9XAtyj6a3rS5zbNRVIfgxeuYleuumaZ0hiR8doy+IJjmE38zlhwlAil0RcS2FJZszROsi6P6fQ2uj5QLRVgh9WQGRKL77IY5KZ01vagAAg4TBjX8ziHFirl3sY4obbUCXFawxcxwV64dXRyGNFFZHc3YWdFIDK2N5+G6lqY6PzYAOu6pEpQBbnHGtRJivPbgr7LgejUQ86S940Rup8xLqgAPce/xzqeUnk3GIdYxKYqjfhPJz7oEcGTLpkwUQoKP4oCK4odtGAz4hVEojxMampsrbK2nAbEBelofKC/1jZGHMgzERYZcMv1vb4Z53gXa0T2LoqiTj57NX9XVgPE+Ff2vkML/SdoIB7dsDcG+Msj960ff9s6hRgPGRduXBe9jWNl90e8GCPkUoE/tvhr+1t2LMNtCMffhDETGzVqHOJJtxuV/ZvDQE4V/uf6bU7Tfo+V4f/Iuqe9LZRcGJ9lRhQc2RLA3KE3Hwpf3pdwffPYbH25pjns2NrpYVgnKHSvl7MBeWlHRtdhvI/tacjql5lFakMB6tqsNWWjwKtihJdwZ9H0gKpstXbJWKPW4d4f5sVZ1G1JG950X4es6wnw/8gqjt6FmgICUj3tyPdUVFRXaK4CfP3kxBHzFqsQusBkwRZZ0/VDyOwrYTc2pRUDVoVrkKEhuCXDeYs+5A/yKik5Yd7DNB/OofbirL36dqQMprm3eSyoSIEqBmIqNBN8OHmvKBmkE0Ob4eZMCuIfMhj+HGbV8s4fp7Y7BBDDH3mY9NnRFb1vVY4QJn0idCzdud21Hbcg1mowFSY3w02VulRCyhRKVuIed+YFC5aaX+FES+hNU6pBL5izmtkSwcAN57HmhfL5WoWpnU8f76xz8ptvaFGfby8EuBntw0lZStV0/mSFTmRkpONWpuYRCaB+x3UiNIyvSEQ=","layer_level":1},{"id":"297b3b64-8aab-4cbd-86d3-cdd99356c838","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"公共模块详解","description":"gui-common-modules","prompt":"深入分析common目录下各公共模块的作用:config.py如何管理应用配置与持久化设置;signal_bus.py实现的全局信号通信机制及其在组件解耦中的应用;style_sheet.py如何统一管理UI样式主题;translator.py支持的多语言切换功能。结合实际调用场景说明这些模块如何被主窗口和UI组件复用,提升代码可维护性与扩展性。","parent_id":"efdcccf6-6375-4180-abf1-f90510945ed1","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/common/config.py,gui/qtpy/version2/gallery/app/common/signal_bus.py,gui/qtpy/version2/gallery/app/common/style_sheet.py,gui/qtpy/version2/gallery/app/common/translater.py","gmt_create":"2025-11-26T20:51:30.2186242+08:00","gmt_modified":"2025-11-26T21:18:13.4546536+08:00","raw_data":"WikiEncrypted:5do7z9I56YIENhLqOIMjARxbxob41zrdqvKhKuZ1Z1AX1hKOySwqpUTj2M9clsL7bDCndtRI46lMiFgA18FgUSXf/Nc4YB4JHFNqfSEIrZQuXqSyqrJQpSdWc29Ei2nJEbz/jjSrJi6qGY6joR/b9vKLMCEf9kFozvapXDGJgLoLDafF0IMGlJV8/afwbMEAQ2vs1acwpQb7MOMlBzhDa+GnJHN2WNabrZWRRB6g3spYTgtrWNRakvBL+rgR64g6vRZ/4FOVrOJ8z/swmWiLBeIRtiSgqSZuAmlbEzYmg9pYbflgeTwkJZpswjxmKLhFICkZBmDa1eKzai0gCMNYOKMqLYPcoRyVij52wK1b1SodGpI0W3GayZ6uR6ioAjBiDQi5P0qVm4eES9oAa61TTv/12Lx7AVjo+8T7VislMXcu0KHY/dvi9MzMu3U0+DIZkz3+4JKt+gUWoFrj3RB1RUr3zO9u+CO3OFMbuAqqeWoBQcTFhCm/Pij6Cxn0QIzhthY/Bg51g7iQgwFg1ZYZH1U8W/e94aAcRuXaaS8C5rHM1GKRzj/FaqNVYX5xmSuZz4GYj/T5iPXgeEwuZbFx61HQY3saPkhsBKABrp9mgJKBDbAVuMzelpcxu+QuTsO159YKmkxn5UnH8csEevCpS6CFSUJit07HnVxsznWRguZV4x3FqbhL8pKWb1tLirSAPoBIhX5zuoOO/xNLQN/O9SsHl5QQ36rbSEu1bnvV++OQ+8Acgx8bPUXLFbSWbqBMteoHWrockiHViEgps1wl/bAA3qG1FeICbye/ZVg4BQb7vlZRd13xijcdK25z7SrE10ybYhvZxWUy7uJ8QfrJ7N427tbSATjIfS3+FII13Bn6pcsfG+63PGU2SlqPkP8RZgpacvU3g9TNyDcFRLMtwChr2rgEwDzjQzIqfKE6Hop1O+oxHLEkSe4bpqD3fDnAsDpm00cF/4cggZwZNGFPSwBfiQgttOjS+cirSgMB/CBxsShLOCcyhkkj8RgMg92rgq2j08QTOckalblccAH9bSGuFp6+kpyuaYek385coXagFJH5q/8HXNLHbH6HTuBCkkcuq2LVOU90a3ZyujblXdHpChUZtnJgMViSd5i8kp9Gs5IeHgkfojKs2ZJCYs1v","layer_level":2},{"id":"1be2325d-d01c-45e1-9320-c2bf7aead663","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"通信自动化功能集成","description":"gui-communication-automation","prompt":"深入分析GUI如何实现通信自动化功能(邮件发送、微信机器人)。解释dialog_interface.py中对话框组件与office/api/email.py和wechat.py的集成方式,包括配置参数传递、消息内容处理、发送状态反馈等机制。提供实际调用示例,展示用户操作如何触发后端API执行。说明异步任务处理和进度反馈的实现方案,并提供常见问题的解决方案。","parent_id":"e2f3c078-2962-4624-ac55-a7ae4ab1ba48","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/dialog_interface.py,office/api/email.py,office/api/wechat.py","gmt_create":"2025-11-26T20:51:43.5367179+08:00","gmt_modified":"2025-11-26T21:19:11.1371068+08:00","raw_data":"WikiEncrypted:5do7z9I56YIENhLqOIMjAb/o9NOH4MfDxpVq6fG9hJYIf5a5/UtFF3XJF4iHummldqR9hEUBVE0PMpYTGjDVZz8N4XDmqNasG/rJsgVwPbJSPNjJcKMdZwCnER3rKvwR5zT7FT6DNC0MmfLmvj/NLx9eajo8aBCziq0Z1WhdkHoPg63I65ataXgi9c6xv9iecKpCAcEdl4cDj+wKjr5F9OmjAfX5miwmiFVf7hQJGdxylYwBh5mj74rg5UKH1Oq3QkJ89xQsfy8yOyTnl+FTy0R6X2y+2/Q1WxHehGfqx9c3n2iima3qzY3iKvo5EddZICubVBerxDTM8PeSGVQ4koiuL7G/Ot5ILfY7sJ8cSe0EPx5m96++SKJaQlaUxYODI+k/rasX075Ult1un7WZc/ScRGIBoA/+BVcug5V4/42frdMHoxdPwVl0gcwSV/0Y+x1ob1KUGYYugM/Z4bAqsimw2X9nsYkEabw0Y8XYcRB2nEIjk3nt2wQpTeHLOhXHRg2S/gtRrV3ApARsiMG9/HSas1QKAOrVhPRw03mc2IT5Px3xhzO1BlNLcB9DTDi1u7rKxb8XhLb3z1CXzuQz6GK3DbF3wwUTIJs+bzGPczkVDNbzRkxBc42vuxPjGw6tRXX3qZI/cXYQEnzKxgZcBFD59mDI4QTBgNXTgivvAlELztFrFDQwcOkUzWfk0R0HsXyZDaulspl/Twf3MV9YvqPexO0xooUmqe+GurB8s1jmEoKtriizmyjkm3iELMXZkAQDcoqHOVC7KMtVyHGNqSZxHmASlwTgY2fDFNjG3Y69D14d6/pq1C+oFLT3Fi8+w6HcCZCQSAL2Ja56b0hDnCvXw6yIzjg4/HBGdxlq/PP42bWup+Q4x12uSFvwBLBl1sU3VPlSFz8xjSBnu2yvKEYO/1+OGK45Ik+yBMB6XrLIsefYSQi0EEUIDMSk157/ENz7WUzoGyULGM1tWIMb40J/umID4za6EThYn1SKTyK8KLuCsU6vRfsc3gZ/WTiAg6hAx71yDxeULO2aEYwRLMl489kw3j89PXs8T9NwHRM=","layer_level":2},{"id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"微信自动化","description":"wechat-automation","prompt":"全面阐述微信自动化能力的技术实现与应用模式,基于wechat.py封装的PyOfficeRobot接口。详细说明send_message、send_message_by_time、chat_by_keywords、send_file、group_send、receive_message和chat_robot七个函数的参数含义与调用逻辑。结合PyOfficeRobot目录下的多个示例脚本(如发一条信息.py、定时群发.py、根据关键词回复.py),解析消息收发、定时任务、关键词响应、文件传输、群组消息收集及智能对话等场景的代码实现。重点描述二维码登录机制、会话持久化原理及微信协议合规性注意事项。提供故障排查指南,涵盖登录超时、消息发送频率限制、联系人名称匹配失败等问题的应对措施,并建议在生产环境中设置合理的调用间隔。","parent_id":"d2ac020f-81e6-411f-a866-ab1d3e411da2","order":1,"progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/","gmt_create":"2025-11-26T20:51:49.3463705+08:00","gmt_modified":"2025-11-26T21:19:07.2856881+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tHC+mPjhK/AXjHb2lSnWNBtJRuAU2VFK7/NcHUsOb1h+JvaflSPMurK+491+hVVZbwd3EVhO6CYXJIRx51tjpo7lMk5FNqatbP0wUZopiMN5nU0LK6L6doPp0TfHgxgw3vLtV6Z4T7DmyDTT/zqWvnMnxg2FHNrLDSCUSI400SyZzQk8UYBublM896uZJE8ROOOfuELz5SR8tuQhVsSHwHpg8shUqW2zMOGcP+klNjaeOUel8rsBOYDyCJVP08OaoM05sMvEM0zfer4NqkbMAGPmKv30arJmQbozhW/jmXldfJ56PShkkZUsYTuswzrAMLAfUKmXWRQBvPVXNtixfeYefUeW5hBPFmHq0zigE6dXXUKHImbaJa58wcVD48rFNn5+T1ZKHwQDwJXXEmVpgkokG6M3y4QZYJWB9AVUDRnDh6C+9z/1XJdAMNSb5Fv8yjW9qb43XnlIpgE0qN1osCf+qJo0cbWeAhnOLr5LAlK52fljwzJRBbUUStrg3TBdZO75G4s2w8mI1Vk5ZWC1Tg4nvnniZlkSLG8mvw/UApwEi2m/+2xGKHVHtLdBc+T1lZai0CVoS+1hzGhdQYdjAZc9qo3QR7Z/VlIZ3y1CUzE5l2pCywQ4dgNZ5YKWCJkSRzBSpQIDoQnNHgDheoLA+N1ggIEO83ZWwNGeAPEQjJ5w2VMtJstUx1YmFcSTeA7RGDDylbgCJn48sQoH4Sx19MAIMmxft+uPZXPOjHOysopS5+ahmHGvOrP+WiQi30UNsJ0VLp+FrFF9TJyf9EQBtSmwKkfxHX4xZ8Yk0vXeqZBKki5HK+wWiEXMqSeyevT9P8xu2CjIGPuciZrbusLVz8Ria0MCZAVnqTAJVMl6iiGRKlUusmUqq8lrTqQ45J6nm69cBk7s5749Y3HHLpn3NUkeP+y0SXUKh2E66HceOGRBPGi2Q+Kg9jkvHCDLa2dIC0BiiKOhvmFlIPtyCihjUhuEwWJlExiQFggl2fkY9LAe7nnB+WSQKN2vMQWlaJW0kfcYhPwl8fwh3kMM4TyZRcMbEgG0nXEqrVRGfm6DnUi+WY+uPQb/DZEFzFvXmsvjocomLyQ1VTzaxtQ9a205I44Cbp5SDIAaYw322TMnSWlrDUePF2NBmQ3BgwgnEkSNcIjZR2+5Cqmumj9ubJubY9EJwDej8Pq43ENy1L2fisoeZNWBaayyhkm+PLWVlphLk9/pXtoAUG/yERZVhuUarlj2IZjybtgjDp9CUeBz667ZCMkhggX2Mx/Ff3pug2ovwhXcDnx07jqU5pkY80YngS6r15H8F7JgVj1Jz8TK1FFico62nGecXnJbK/2WBrzr1gsX5fTnkMNxOpCWXvSMchS58EdE5LJO6IXchj7dNz+kGugJ9Zkk3Ktr7YU/Au7Ao9dFB0rOJhIsQpjGoXiV8gQe00EHtMV79YmGviWwMUdf7M7CRVFODd/NKeomavZSLASOadw/alNwru4mR/zqozQyB9Ay4t5+43xA1NtF2UFUifb2R3tK6iSX7D75cokDQ9fPMwrhLTgz7rJEZiq50sifiY6C2Mn1b4fiboJOIYxI","layer_level":2},{"id":"857acbc8-0151-46af-89f8-37b311535d41","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Word处理","description":"word-processing","prompt":"详细阐述Word处理模块的功能实现,基于word.py提供的接口,涵盖doc与docx格式互转、Word转PDF、合并多个Word文档等核心功能。结合examples/poword/中的示例脚本,演示如何使用office.word.convert、office.word.merge等方法完成日常办公自动化任务。解释底层依赖(如python-docx)的工作机制,说明文件兼容性处理策略。提供实际调用代码片段,指导用户正确设置输入输出路径及格式参数。针对常见问题如格式丢失、图片嵌入异常等提供排查建议,并给出批量处理大量文档时的资源管理最佳实践。","parent_id":"f7bcfd40-cf6d-413a-b3fa-59f8cc0f5a06","order":1,"progress_status":"completed","dependent_files":"office/api/word.py,examples/poword/doc和docx互转.py,examples/poword/word转PDF.py,examples/poword/合并word.py","gmt_create":"2025-11-26T20:51:54.8831598+08:00","gmt_modified":"2025-11-26T21:19:36.3257366+08:00","raw_data":"WikiEncrypted:Wdc9SuVVrlBg9wenEHQVknV4hNwblSXOG2vz91HrtHjoHwl4bUu6KE48UCsQYNSpiBEVYaL2tHF+4Hbeb51Al49KiOuB72meJa9Fg6GrPaClvH/KKtd0OZ8oyh52Er2QEwhhffzYJqMaM8gZv0UDn/BKqnfTzAjhs2N2CimYon5zw8Nr0gfpmEm9Fm8FNKllYQu7K2hjQKrp1qCUiUTki5ypldP8ZaY/888eAIysna5kfugR70DwM5hUgOfdMdzrVT8ZUywVsrN3xZbrJk3M98PUDbHL9qg++kifQmb+Lclj0QygER9f2omkVnWsVMrOJ5ksHGlaaFlxeOIB2RTTlqr76wXcw80B52zZPNpWAZ1kqTZGFS0pBd9Fb3hJ4qiC++8y7cVSTTIu/BzCXhVgHjQdJF+qFSDAdnl/XjU5/4w61xpAgClZivYoE5BlBU4m+Sclls5PtUVexrEz3vYKawnTSvSlPJUEESDapaW9SoiCLWmy0g+nvUPVyHmWUqX/GEURUxzlMepfcSJfWu0nBF9gg3V6UEfB+eWCxJNXfewxjXOUISoeXQpbGFi39KTcj5siSZi1/IESloRzw7sxIqxU2xi0PfqKtm8bv4sIiK65LFXEtxO5DuJqwtU29oGaHPxbY0OlKy+88rc5i/oWyB+QsmuU4rczw4FRi2Z3dtpNCkht5+eomY1DhJ3Ta019/RHmULVajIk9r3AoFdVOMY62FOgnNZTAOgkGm+XvWSvZzUaDnSLk5ygvFnrblH5Nr8xk5v+4aV0kKqXGkNvcDmoUhOMV7FvduY812e5LtKRR/Vec7t2gQhmPAcp2BuMm5CpM8zjAPHfrEt7A3rvURYxOGFotfAlrZyLRi6fsNMct2eFV3/0QV3aapWani+Tr+XTOwzGI/j8Jm6DL9aU1bBfmBVElB9AolBz46rUchuruDxt/wpPWoUxKTqQ/+621D6VGuSR01kbFT5SpCh5Oh6/o5vxYPuULIMAke5pb5wkzQuOiUKbvHm0nSO1yxY1rpxqxhBOzmJ8Ip0Mpv0lOBN92J16lP0lvwQbYaF3dlksUJM16AEJ2RO5oyz93urRYDKjjHrM1A1t1wbL9V2rqAsCDCsNswXzFeWYgyepI1XdJVOgjifZvl2fCuJoXcmDBjrXLi8l9mbD146AuwBXS4ZzqAC/POVdVYjaKSLkyaZiGFuOCTw8iDphstIA+HF5a4IMhfzwhSJNoM9Vw+15pcqBO7txtw8dGPdRn+sIFprbTvVKKbahnrznBY14qKZJhXqQp5DzWKUX0ZToRvfkS3Jc1c9K3CVyqHVMRD/4YUn7z7QxkKBQuHMcTAmxhN9Cm","layer_level":2},{"id":"f29fecfb-0072-4d50-bdc8-ecac5b1e0631","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"视频处理","description":"video-processing","prompt":"创建视频处理功能的专项文档,聚焦mark2video视频标注自动化能力。基于povideo/mark2video.py示例,详细说明video_path输入源配置与output_path输出目录管理,解释时间轴同步机制与帧级水印嵌入原理。阐述底层moviepy库的视频编解码依赖,提供H.264、MP4、AVI等主流格式的兼容性矩阵。分析批量视频处理时的内存占用模式,给出大文件分片处理的最佳实践。说明GPU加速支持现状与ffmpeg配置优化建议。结合GUI演示入口,介绍图形界面中视频模块的操作流程。包含常见故障如音频丢失、帧率异常、编码失败的诊断步骤与解决方案,确保用户能够稳定执行视频自动化任务。","parent_id":"f14f8d32-b1d1-4726-84ea-35edbe9520a3","order":1,"progress_status":"completed","dependent_files":"office/api/video.py,examples/povideo/mark2video.py,gui/qtpy/version2/gallery/demo.py","gmt_create":"2025-11-26T20:52:02.813009+08:00","gmt_modified":"2025-11-26T21:20:41.2282376+08:00","raw_data":"WikiEncrypted:/pvGPLaEVo9VWauq2W2LemwF3P2K2kTobTBUiXcvlej/Ni0oH2rOdIA8n+O31rpeubnWq293rcvnQX65ElUcOZzct+YW3yuOR9L5rllXYKNNkcuQz1UUhbH7fbIGx+JRmV/qiUkcb2bF4ifwRtBj9gxV7MtrG+BA2+8h80TSKO8JmcLvvBSpfTLPaaIyh8tsFoBe3+V6kcoqnD8NRXovkGgzvCdMOPHTMQXpL8ejU1M7cfTcWewfdKQwlfmYYBXyAREvUeULfRqcVZTjnkQMH3nqo3ggKi+7XmiiZ6bga0zi7hcFWBLb+sy4ifPuteI5jz6coqocZJBF2btyYA9kcIFsdGPbmse8UPsC+7d5jZJgHFCYSZDLpG5CT9qNuYfbVC+SQDbIjY249ahlUgNcuAovSfZ9Kx9rrdzGjeyIZ3gD2xlto05sFCJF1mDr7dvhl+Jnk5ibKS2fDEME9fdhCh2XMboC2/OMpcGfsYzUj/GT7wneeGGKc3ss1x9UNrdaV/2tEmvQ1MYu6h1vXHGywRUXs7/K0U91PViG/Z9fKaY5bAN4yvUmQ+A9+ax+RMOsCPmzsUX/4GwQPfq0wDBb/xJpD3UI/++L8sTuNmgtWyyEgpIUdx0y9wcZrlgX9YxsdSTlld849U1FTAoigJMhPR3JF5hupiri/BTg4ZRZpIN15HtEluqn9xFL/GFCiyBpajMkHrgehNXgHQ4VjVEI5RWFzzTuSTFE/1rPhLdQ0Tfqi9rPapUBuL/RrdDm5qzOutu/QQvC4/G4ohkL6prXJ5WFjn3oXyN2Q5R5ImS0Ee+lPvKRMotTbdaKvCtAcca6SnyMVz0S0HDorDBPqQuRJQeyjVIkUWJkphqv3G6QzYOHzxk3nHPpPLdY/iebP4uMPOTvfC7jQyFxH5dg6bP8NW7/ujbYkqS5WvOk2kOfRi6W/lOyk5zDHUrt2jXi1vtwojgZIFxuiRD2SG6INXqvADEQ1r1aKCUlyQyAan6evhYPfFnMHIvSkcL7gzYxYMPwan8B+QtBfu3ouKI2bGHjSIVPQMPbchojQSlPJs6Cb1aXgJ4X7hjCpcsMnyVxMWQ8VDLa3XyCVXQ3TKLwfMOI5ZWCgvv2rnqX+TfPbUEAh00lCVyptZHZNFZCTrX6owPyUkaj6U63Bv+8vzf+P0wr8X7Y7DqDI8HfdZ6g5DlXeG/RDqdl26F0u8QBXoPQwzd0uZrCFaeAy0YswI/fkYvfdYH3oNp4cq4mj45d1mQDuGBqQLLeZrHSzMNLbJuAGfMqucX6qZMtWB4Ebu8ToVad4kLk+OhFvBG1Bv6vqqY3VQojZ2vDjJ/DY2ZVRxndREzTQqLBcGuuMyrAT0aSfj5w4N/AZya5HtxC7q/S+udZyrtX0L6xO1Kky/72UllF+6EdOf4JUmR4ECOSAx+CSnJ7Erdp5cZHMmUrOCXzc1yvx5Zrn6IjAVMb7NAMaM5p+XzMApafveJnk5iMNcO0RXCplDxp0z9rw1Pg9PRXJl3bc/c=","layer_level":2},{"id":"ef89d5c6-745f-4ddd-80f8-d518915fd224","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"核心UI组件详解","description":"gui-version2-core-components","prompt":"深入开发python-office GUI Version2核心UI组件的技术文档,详细解析link_card.py实现的功能入口卡片、avatar_widget.py中的用户头像控件及sample_card.py示例卡片的设计与复用机制。说明这些组件在home_interface.py中的集成方式和布局策略。文档需包含每个组件的属性、事件、样式定制方法和响应式行为。提供实际使用代码片段,展示如何在不同界面中复用这些组件,并解释其在提升开发效率和界面一致性方面的优势。","parent_id":"fb4b14d8-a3c9-4f17-8f24-10e8bfdb747b","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/components/link_card.py,gui/qtpy/version2/gallery/app/components/avatar_widget.py,gui/qtpy/version2/gallery/app/components/sample_card.py,gui/qtpy/version2/gallery/app/view/home_interface.py","gmt_create":"2025-11-26T20:52:14.1919105+08:00","gmt_modified":"2025-11-26T21:35:09.9552382+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwOvtW1X8B5AVsoQioggciTEhU8QnNQXroAPZzseMgwQWIclHszl6vUB6Ww0k+MZemDn7o7DwkoMDLHid0ESQNHjDmZclGtBlIhMhxcmFLM+1nXSAxh1Fhg1f+ihGBRwJpzsI/VkcZGzvRliZdKogJLfXGKI3OArC0FQDaFyoG54ik4Y9t1RF9YKDWuLRm017954gdzSkLWY+k8bGurOKjHwOEeOZbhFwC4+b05R3V8IfmxuNtdV2P7dqXg/jgf/W+PBq4RrNbaDehv09LWbeqcuFpNE1Sg+Ow7J+J+aC2UAoJjh0SUQF6Ur0VEQfgGBYFPMfmFq30VtcQkdyTaRtaGl8jK63JxUCxdGUwPrHx7++BE3ZT/5L5I5Oa3CZGfuzwgA2pVqjYs98EXFCQjwktTFOCKKMgC3hw1fcWRcLcR2EkYA8gTqaSNG8p/IXW+4rcqvNoznS3WF8n7tb2iuQEDbRSeVdwDD0syLSTIObzw0WErKqCkJnfGEB3ecBGpwiQP+xx0npZrkmkoJS1LeNBNW3pvYDdswxJiKlWcxai0GF/M/FNe3ui0QaEMyar+RALKskP8VfkWnNFBODrinA0raCxPP2f8yfdBZTmlUxRnZk47imtPvh2O4kV4UWJZL75JlgevLPXbkKfpBxyFQAQeQXZSqmiLdsnFe2kEk5kgPN3HGbDUF65Yc/R1GQN+Sv+tBv3MYT5z+lhXUsQpD5iJd2v0dkzIDcrkb7vP5VAoQKP8Z2n9WibO3DTREh6SSn+lJ0g25G2m8eHtIWsk9GP85ZbKmBURv0+mxcBHzpG6yNwcaRQezld1ooCmGIot5LBfw0DAXjYOmcZqQie3CuY460MurvfdK6MgzAEz5pSB8EslaFHs3TH0FqLjvL++sp78vhNR9rvQXALaQ9aSCIGUeo6uZSL3kpfQcsAjzmMrdeAaAit7Q4ItYmJxapZMQSMHOpAJtkyBrdFmBRnZ1m1/RgEOq72JQG6LvfhHURXPBwIeFzzYeDxTlE0p6jHv4nEAvuib4AMiVTOlezxb4yIGvbXoFi/p+w77AV0t80n8LCaYZCIJeg6x0GnOBBl4rLFwjv7Z1Ldo+xj73kyiqrxhCwNB0zJN/GEN8/EZzCOXtbY7uQ78U02g4Fw7P39QlJS6E4fCBl2QEKf8Cimi/Y8o5aswdoDhxWmge6lRkfmnfJKin5JOmnMSCRbgbkSrpU2kUhRRc574gsknzYUFUsZTs1lMkvgY6cxLJmVcim96S3jWfF2zMj5nH8IhrGnuVOPKz4eZPg6xv3wjvVUzBMCU8tX6idTdy/XirBP1qqUIr6","layer_level":3},{"id":"0d3591e6-05eb-4c99-8c4b-77afedac49ea","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"消息处理与自动化响应","description":"wechat-message-processing","prompt":"开发详细文档,介绍微信自动化中的消息处理与高级交互功能。重点说明根据关键词自动回复的实现机制(chat_by_keywords),包括正则匹配与响应模板配置;讲解定时发送(send_message_by_time)和定时群发(send)的功能实现,支持cron表达式或具体时间点设定;描述批量加好友(add)的流程及当前存在的控件兼容性问题;介绍收集群消息(get_group_list)的用途与当前BUG状态。提供各功能的实际代码示例,分析其在客服系统、营销推广、团队管理中的应用模式,并给出异常处理建议和性能优化提示。","parent_id":"25cbcf29-42d4-410d-b72e-2c345cf71be5","order":1,"progress_status":"completed","dependent_files":"examples/PyOfficeRobot/003-根据关键词回复.py,examples/PyOfficeRobot/004-定时发送.py,examples/PyOfficeRobot/007-收集群消息.py,examples/PyOfficeRobot/009-批量加好友.py,examples/PyOfficeRobot/010-定时群发.py","gmt_create":"2025-11-26T20:52:21.1777906+08:00","gmt_modified":"2025-11-26T21:20:34.7590699+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tEewfBghfsS3/3zi6W71iCDyW0huK0IdFvPzdtiUIogVB0Ig+pSac2/SvTApXfXX385KilBiu8o1igRqQQPzlHNZotBUKF1983/9WONY61XH7nU6rJXnU4o3mEbn8O/lEsrx0dtEOmFoaCeBPrp9bNBfUQjHEFYqn/sL22Lis1lZdHcwN/Guo2iGRZoDBbiLs9/tTxEyRQOezWK41u6ghg8KPBBrm4mB6vXacHzIqb5fVqEExaF56K4+2ujYkFZhb4+hGWpW56qg21bxN4Xh92qp8LYcW4lk+0pBk5mAv1Hgfxmc0RqkJE0iqaFZgAbxQo4GQUPp8KHiQ6k7qQ1QOIdnTe5QrB/NSvvEgXE6blW7Yxl36TXkgAwY/knHpsjOGw64HPWYfQBkv3cNF3raH9hDxf11RzN7qPt4cd26eJYcSrZQsoMp9sxKFXqgh0TzBEh/fdqyvZM22U5bg5fEEj+TLCRjFMfw5W4IxJaTCiTDvjQM6qrH4ji6p1UyIArMaEAtlgPb6pSz4ReAuHSmZFz1uQvIku/861taLE47sYR4cvT/hnUfW08wtuss073voX9cnhE6wNJNER7WhSPTPmF6QYxbb4PXolBmLztjJGH17455/c76Zai+L6nIbrC+HeJcxjI7SItcosemBvQEBoCC1z/GixDIssAVO+fNLqnMPfzyKtzTUngwv73FCXqpJKIPiNYtVTqQxuel+rKK/17QjwkvAeYclrcSNpTC4jZbXevoOWxnig3qlisC6G0cEmKGoI5yc+4/mYkh38lvXgZXZBnNiIAw4OpqhJ0o9YdezfKU//gO+c0xsPfgIgCvkiTX12Nko6z947bJKxDt4yEpcyF1TOAR2TePhJHvrvvAI76KJCQgMiN2cZub9aKRUEkigbzqmq19BXxHMMqWdp4eKcCuXpPTtcg42gphoHDVNwk9E+Yl4sdsPdxWfXby/AB2nKo7D/95+BtG3RqOOR2HZsW77KL+V9KpC60mh3kLNuBSL7vlK67OB7B2pXDVebyhY1dYuuLCNN/aAu3ItuMT3bybrwizLsRZ7bVjP1U4Yq6BJXLuI+xCC/EEidfK9PU55XJETWJENNIBlQ+tcghDyUQXrMvwpjRp4wnJSuoGqIwrElDO9G/UubMYgHjwc7YXXKbuYV8/ytsH8qvESRhl9ployRAthwTUBIwOkTBSGmbQlz+onPUdoaS9dXflNedteNZ3G3waDNisQyVnU0GxyuOTmQ+K9HKnLPBc/Q6n22sTUXOwPAhuOkrSzPADuHJUMf0D/6rWTjsXvry10wKloGQu2UDXVHPRSMmZIaXX8Rdqsew5n3C7o4R5imSBv14M6pGJ68fq3zdeFWGN7zVCWjIs01uAih+GrQ8FMuLIJYyHZO58TYJoYD6hKsl1Edq5VsYa7raUQglFJNv0kCoE0TQ5JpCFjcBk0Ntfv7e8JEl164ixWp2qTWI1Qtkd6kjXeQy3V7JZXWP4PDm13v3YwMEjJMgftKnbx4MBQ6Rlg+duei438G2Nj7rtSzEoKABiPGqjvqqlD6b6s3sXtuDvJYLB39BJBFjs9u5Y4ZLtDqVv66HBD6j5V7gr8gMsRfPX09DR48e2N4waB6gqc+Y=","layer_level":2},{"id":"2bea2dfa-9a57-4c02-9f82-5f8267fb5caf","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"合并Excel文件","description":"excel-merge","prompt":"系统化介绍merge2excel和merge2sheet两个核心合并功能的区别与适用场景。merge2excel用于将多个Excel文件分别放入目标文件的不同sheet中,适合部门报表整合;merge2sheet则将所有数据追加至同一sheet,适用于数据汇总分析。提供基于真实路径的调用示例,解释dir_path目录下文件扫描逻辑及输出命名策略。深入探讨openpyxl与pandas在大数据量合并时的内存消耗差异,并给出分批处理建议。","parent_id":"3aff6fd1-b9c7-4eff-b8f5-26462a3f14a1","order":1,"progress_status":"completed","dependent_files":"examples/poexcel/合并2个Excel的内容到一个sheet中.py,examples/poexcel/合并多个Excel到一个Excel的不同sheet中.py,office/api/excel.py","gmt_create":"2025-11-26T20:52:27.498085+08:00","gmt_modified":"2025-11-26T21:20:45.6895809+08:00","raw_data":"WikiEncrypted:8x3JSVErdDUDs2nXur+vXQL7sAMDx/YixMbfQAL+xUDDAt9sq6dHGQvgx6Emyiose8PgRIr3SmBh21OEPGbTTKAyma7/w1wNxleCk8Riy0H6PEukE+vudVHimToTy+cYUHaP077Ud9FzYVYFM37URIsb6Adh98RPi8xT/PwJE5VKVBObXPzUHSubT6DA5A+jaCDg0sY+eYRbie9O17FEN600eN9vCSvebr4ce7OGcxXXVtHYrg/iaf+04PUjFX4XSkRRSu41pCThfqb+tpnIgCkOqTGWOfSLg/kYO7F1TwsjqiWE7V7bB45UuwuNO/kJvs0ZZc2t1KE8zqPZh5p4+sEsF993b/gYxyhq+pdZPKoy+OIWwZlCc/BAX5R3ECur/MFE5VnPp/py6UdcACRSyVJ8m+Qj8RK8UjlxQrGkE12QizBh7yl1qwYwRLIRr/jy2UAZLXGRAT1s/Nu1XmlzOQpNeWcMP0sN0/IuB/5Xtuq6t16raG2fQNWfeZaoajSIqBCyKn5gL6wQjfd2LMxu8J0t32op2cwLzBJqC27yybwCaaccmY51UO0XhV/TcPrKNVpUc4Q3NVAsumN6suOwaKwgXbg24TZroz02QhX239P/hJYw7sWJvdUBeGIfEY4pjEdN+XqmTD27W6FncNXs6VGg6W5wU0b+rd0MElEOoRnioyQLRTvCK4vAcMgqdsLUPXV3PxRvXgtIQcMce+45Bc9z3z9iwDnsaWRsLY8TeU+nT6Oj7etylXJlakN63M8inE1Omr4tjPVgCBh4uiEuaCO7ysvuRO0Q+C7m3h57akkVHe1hAVgEY6siZrmg+Lt7Xs9br2pPSOYiiZA1LRPII9vHECYU/vTgR03isx/sJuNi2d+WHYSBkBT4uQAU1I36HeA8VCI6NPUAD78BgHDtM0r+9fP83hsd6j8HDeaFiGKd3oqpMvKEZV+XeHlKaqyXaywSxAD3SsJhZqi3pMTrCAgPngd+j/vpqV4fl3HmsL+Y7P+bfaC6fs9MScoxltQOGVMKWn0+SwquTBNtkEojlyE3Nb7GK7FkxS2y5XzIE0GN/gQYo6kVCzKZA8+2ixuHWwlCwRbnQHY/ZUMi0t/l5aHGo0N+9brugatA4naOW1lI0VBTcanJaa91I8PMswEp","layer_level":2},{"id":"be0c69a6-6c67-4442-958b-7c6fb66891ca","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF格式转换","description":"pdf-format-conversion","prompt":"系统介绍PDF与其他格式之间的转换能力,包括TXT转PDF、PDF转Word、PDF转图片三大功能。深入分析`office.pdf.txt2pdf`、`pdf2docx`和`pdf2imgs`接口的参数配置、输出质量控制及性能表现。说明文本编码处理、字体嵌入、图像分辨率设置等关键细节。针对Windows与Mac/Linux平台差异,解释不同依赖库(如python-office与popdf)的适配方案。提供处理复杂版式PDF转换时的布局保持技巧,并给出大文件转换过程中的内存管理建议。","parent_id":"5235253b-7037-4298-b76a-147a71088bbf","order":1,"progress_status":"completed","dependent_files":"examples/popdf/TXT转PDF.py,examples/popdf/pdf转word.py,examples/popdf/pdf转图片.py","gmt_create":"2025-11-26T20:52:38.0458869+08:00","gmt_modified":"2025-11-26T21:21:53.1748199+08:00","raw_data":"WikiEncrypted:haTv6sJEHWCwMTjBAXr0wMd2dj5b6WsPW5qSTrZKr9FgrwP1lWGq5jXtrBEHFSq8y0/8P+teSAsIRfjXna6xLJAFqi/fRj1eXgNk8fpbS6BhnAAbOnewshOOvdYFkRS2svYuxePzZs2U8EgFSpBDiia1gZdzmuDS/gRy1TxxnWzBgOUPU/4LK2x0JLUM/r7f+VXlFjUWB/svPAlDpyNxLO3io3bU+pdJWpXT/O6sABT+x6K//DxgGRQ1nkWi2S0qx20uoJ9ag0z3SH9GZVhue3Wp3GjYC5jJWBIVn5O54J+N0mv/ULDb0tePaOchATr1zJS34JfetY1AM4+sVtzs2eljt9WyArh5l0MHVzQF0RqdC5sYwXECjWDRnoMwxim8SDtgziJzegDmSDCh6qdvXA5vUiO5UxVOU30Mhf3lu0DWAp9yXCJuHc4LBJ69ogao2wGqiKwBlCBkX7uCqc+j36xtJmTt9h0qruin2GJmNlgIuDFlqPV/jKLjXwExUY7yoD5UsQlltxRyeVFulrIw9tButNTF8gzVYspBZefuf0kaWwp3NBSOmSB7/SuCuHLklNaqMFFIjJ8xY51XWMOcCFcloMaTGr+k5EBHtx0i5y0dIeBIodbuZltQHhG0SG7NPZe30DC1Z4WmvUf+XTVJ8YXPObZGE7Cqck4hAvYglSS/atvr1bmbQ0FjXBLVrtE4gbYPg1qbRTILGxkfmVVURaflDPD5GQrruEY4GCcNbaqqEzp2eShhh4FbIAuHJK4bYKq1+OEHrpZKkOZAzupaKftqhLgVPAU/8apv7Sy46/bz/L+3uVFljpCxGNAZRAo6eCfVXVBIJetUDOh5Fv4j/WY/o5eIoP6sbQ0ZiuaIjdMaarrcXUzsQbuwJrkyVYoT1YDyzFwZKjUzBFtuNDKupyyiRPoV/gJwJa11WmX9OC6txTv3YlwHMcOq00ElIlCjztb8dEbCChFmcjPBwqJuHMgWAzXlUaRj52Qy0rS8PJUupjZp6okvTFB275EoB2BObFPYs9z2ol4xvBvrtJbaIhdvvwDtHyy27yauKcUMKl0ev/tPw2nyvIjjbDYrta+yVzD1xiGOSEAjyPV4gRypPt3d3k36k73GRo+y2RMCnDru3cxTpVBbOhbcIs4RjOAlREqtvDI6MwgzpYvmTF4Wmz+dn09iKluWpLZyZdwMd/OszqnpPavbgNmb0yjoqmMgyeOEu0G/Dy2BVC/v58JKnA==","layer_level":2},{"id":"8be26775-97fe-4545-a6c0-9c0f979e08ac","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图片加水印","description":"image-watermark","prompt":"深入讲解office.image.add_watermark接口的使用方法,包括输入文件路径、水印文本内容和输出路径的配置。说明水印字体、大小、颜色、透明度和位置的默认设置及可扩展性。基于Pillow库的图像绘制机制,解释文本叠加的技术实现原理。提供调整水印倾斜角度、批量添加水印的进阶示例,并指出中文乱码的常见解决方案(如指定字体文件)。强调该功能在版权保护、品牌标识中的实际价值。","parent_id":"e11e3a92-fe01-4716-8371-3f718d2870ee","order":1,"progress_status":"completed","dependent_files":"examples/poimage/图片加水印.py","gmt_create":"2025-11-26T20:52:46.6705974+08:00","gmt_modified":"2025-11-26T21:22:02.7695784+08:00","raw_data":"WikiEncrypted:vw8SwXDMWAcq3MVrbhINPCEOGMBmYTr+4avn5AbnYFpZGJlZQfquIX+bOshfNe2sOH3ebNp64KjijpDLKF0rkLWNZ9OWhr/gyZpzmP2dEAsGLdKGm2hiRyhKE+hDvit0PinGccT8UPlWOFEhA5SXIGZSTPSzOuPD8NjhjcBbRP2yx8i9oTbQ5n0h4xEfhZYP9DpAuH7KxJ4nxeXQv8EzPqKEIywnP4X6OIned2OLW0SuwL+gFNakMvebW+umuj5d6o8PBXZbiFX/BSP5KAKl+QCMlxaWUYiFt8iM7aKKkq1bE0CR11hvzvtkfa7t50dcURnGf2pdFJJj5lqK2UBhcAHzitBplZiI/XU9a5TD8oi+Z1VYzXxDPIWcoCDmYz6jz8v5/h/L54eq21KPfv2E9I6fuHrrlBnAsSSbli+DZSd5xclE6nb1IYwFUTzrkTouGFPyswlplzeeRfFm4WpHqiaQdzZiMWpkISL1ePjk8d1Xph/ogXEdJXmLHL7nrvX1PBjplaRluGOEu/nbD0txGqjKnoujJDY38yD6E9pivVUWpsMfQRJN5aqs0ePJAXnYOv3rgW7L8gegzsss+zMlV6XCCIKnHobbObm7nZ8DIgi/srSGp06QQE4t+l2VShIFmEX3qp0UKz0L22ZCOh2XeThKN338iVu7n3qiO/0cptA2gZDrM5oh8buaH/UR5B6/pIiW7I3DCRthEevhEo8jkqoPuUOZs1eyKCksgX9B9ktVaQmpodY/aWxA/fUA49fxefcA+uZb7R6GmaEPs33UD29oL4l6T3zWKy614zh2eJA8EstUV9AoTWkfynvkqDgrOXc0TRlQp9evtchhtdHHv0uhXIFTaVDZxAcvl1+Uan2/X1E8TqarX71a/H8IZTvt8GKvJj6E/miUtEMl5mJztgBVdhZIyfbDc8VmOuRMJbx1uU1vvyEic5XZ6QPZfGqAqK8cqBu3XdRTs7MPt7ED+shEUp7o7YsJWvO/fu/mQOI=","layer_level":2},{"id":"e07dcb60-1d19-472e-a815-14f3bb5ab9ad","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文本智能处理示例","description":"text-processing-ai-examples","prompt":"详细阐述利用AI模型为中文文本(如古诗)自动标注拼音的实现方法。说明如何加载语言模型或调用拼音转换库,处理多音字、声调标注及格式排版问题。通过具体代码演示输入文本解析、拼音映射、输出格式化等流程,并展示如何将此功能集成到文档生成系统中,辅助教育类文档的自动化制作。提供扩展思路,如支持注释生成、朗读音频链接等。","parent_id":"9f1b3695-d545-4923-baac-47827243ec01","order":1,"progress_status":"completed","dependent_files":"examples/pohang/1、给古诗配拼音.py","gmt_create":"2025-11-26T20:52:49.0241847+08:00","gmt_modified":"2025-11-26T21:21:59.374329+08:00","raw_data":"WikiEncrypted:OaKalwwf1v+r15RVxX4Da8m999lVJfkRDjgDNPv0KGgpgLoLOljCTG+h8ORbzG3fhDntUyHVPNpYzwnEgH8P3NmQoHC3SXR0IA+dp1WsaGM5RAyc1DjseHdcFjrW+Dl9+5ez+ig5gjciDlW0oPmka+7g9Ru54XKR21PFbDeqS2MfYswLdzTgTy/VSuFHWVx/Yr2w3NVx1Z2mtSmQU5lp59/sU8L5zRv6trw8n40a8ojvHRNuDr5TdeYmdIALQrTPe2IEGTPgORrqL7pjvwQmgVg0koDFRfRK+rxacrqqZsYmW38A5R5F3pxF4cV4LV48A27M9CTP3W5g3rRPR2EaROMKkRfeM771z80k0pcbAFPD4PzFSCVZarPTmtpuN13rsSIZvQnB8GdCH/z8oin++jsCXbO1e1YWyvb5pxU6ma8iBBUNGdez1LDb1dOoWlFN2xLtOWGImYr6BKKHuFB+2v0SlGeqOABBcJYc1QkyXINwXOpOAvihCs1bF2KuG3dUeOJxRRkifBWy9n+V5t8vxQtVNyJdsCm1n2yrZTCK2chiB7HPHbGYGYGmRmsxVIUgmyK2vl5iY27P8hRw1CAM7DqsZPP/CjoQx1d0nBhtB00SZZJ54ND2OuTXTIZKSo4n18BBAxyBbP5P4+ARzEJaueZdfLGiE6Uf3Y0wXadQeZ0reYjidINucIWlyCag1JMyDf3BBgk5FPCexU4Dxa59iwcNS5ShsZkyLYxb4vM86MKgXFbxQu0jgeAhd02CGikgfW8pt1rE8PEm4pFJKK79BCOrAOKbBv34kCengDTClxmxJoAGkZ20igwyRd/6GAudLU+iMOHWlk349WZ0vSGDXX/oa5FDuJd8PWEm/0d6bQWruhSM32LvLudowN1ccNm9aGpeulC7FxUuF6FgFP4dNHczWIgC7+l4AZQP4SSF+CpvEk+fP6OWgF4xK6DjpmTrBZFG4KHuVMITtOMqmXJqDea6i8KpvanbiKGY7D8ucVn8TOLsKxP/ocp/FmpHEJFB","layer_level":2},{"id":"236bd51a-06c1-4890-9a45-b5805fcbb5df","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Word功能集成","description":"gui-word-integration","prompt":"阐述GUI如何集成Word文档处理功能,包括doc与docx互转、Word转PDF、合并Word文件等操作。分析basic_input_interface.py中的控件配置如何触发office/api/word.py中的对应方法,说明文件路径选择、转换参数设置及执行反馈机制。提供具体调用链路示例,展示用户操作如何转化为API调用。包含常见问题如格式丢失的应对策略及用户体验优化建议。","parent_id":"a4bd1c46-ef48-4bbc-80c4-8708947bde3f","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/basic_input_interface.py,office/api/word.py","gmt_create":"2025-11-26T20:52:54.8022841+08:00","gmt_modified":"2025-11-26T21:36:00.7404615+08:00","raw_data":"WikiEncrypted:zm+x+5Q8wiyI4ncmNZ+8OLD2cueHiz4qVKT4+Mne3kXi3J6kA3jCRBe+s66ArlyitU3022l0C6+h76f+epTGHCFnsZiA+1Rgu7J/A6PFrca8oXDW2Vngx4ceaOx3BzAJp0d05RGeh3Ux22MPbp5Qi6NEaJ/6eB/LYvI6x+Y7K+7U5Zv031HJS+7d/ffLmS4+ml8eRls1eii16GLhc23w7FJD6vfQrlP3UDA5NRl1Zc7K6xT9GHw3mKZaAN3/lUBRaIbYgnnsdHjyXh0+aUtofQwNYw9ovCDxi66zwTYMBUuSqOxwKoPFjaqVnoH/B+0lkEpHIcr4C/7uZBwjZ/fu6HZVFY5v3TmJF4QVMK4qgO/yKHU9bLsZ9oCh7Y5t1iUH9Q4jdMFDgkM/bTQupSDXeYhz9b8DjKyFdP/2Y3Otb+mkXOQtY26TfCCpAk8yMJQGT9j+Nf37xYTAoUTl4IHjNn1aHHtfkqEpu5FoeQcim5tLMkQxJ0XZTAEUcmxululQtVyWSMWzgh16RfCMWINK989nN9Th7z0U40IUv1gyAnVixULkZrLZQgcXm7vb/SZcMoaI1kWlRIsXREbBDW1TuckTyS478kLvZ3sPU+ZL8p4z84fc20lTGaIzXY7qh6OpuzhCDg9IDqWRXi61CWKcRHGq5sQYs8rGqiRdABgwQ+GO4S/F5KDnHDjhS/17v31DrpPaN+lUmkx493GH2i1BGCY1QyIL3kFWI433hVw9KNbGuvsH2Qu8XVU2gM3fZyBlFy0MIDaMYQYkJSOyxycp3Vvj/YsN6Pw6aSsjgixGzW7HIhOgnnP1Yv0jmaI8X0keWUg/DloGL1O0cCeitEzAp5BGCdx1m33OHmja+7pSh2wwRd21Pv9jGwCLNfIk62NVslKHulwul5ZUqm26LFjhAOPWd1Q6Xkq7kfryV/G9rEvZomSFXe3I6e68lrbnL4g19AOjCZagG6/Rv7EHrpLoggaiEYQAPeuReJNMkKNnye4=","layer_level":3},{"id":"aaa92e67-19fb-4b7e-a758-85749ac94e68","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"微信机器人功能集成","description":"gui-wechat-integration","prompt":"详细阐述GUI界面与微信自动化功能的集成方式。解析dialog_interface.py中用户操作如何调用office/api/wechat.py提供的各类函数,包括发送消息、定时发送、关键词回复、文件发送、群发消息及智能聊天等核心功能。说明微信客户端连接状态的管理机制、消息内容的序列化传递过程以及发送结果的反馈显示逻辑。重点描述chat_robot和receive_message函数在GUI环境下的异步执行模型和日志输出处理。提供典型使用场景的交互流程图,并列出微信登录失效、消息发送频率限制等常见问题的应对策略。","parent_id":"1be2325d-d01c-45e1-9320-c2bf7aead663","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/dialog_interface.py,office/api/wechat.py","gmt_create":"2025-11-26T20:53:00.2751225+08:00","gmt_modified":"2025-11-26T21:36:21.3326072+08:00","raw_data":"WikiEncrypted:qEx00KNDeShN5h3zyB0L2AxsefcRgKsfWl8+XO6xs6pKyu//Vaefg7MP7y1hn2dPpgBKqQd+ayuAdXygUjT6//3cj6NjSudadc0ilFIXJVGLQ7b8EbOaEb5LD0TlrqKAR2JNAUt7rwKfVTOTSOolSn8ABLRtdbD8tPX+x5Yx1pW69OPgxmyDZU/vf1VWzawZHRiBdnWdOxf4SwMdkijeEUe3TtgIAYCaQnTMQpPpWoULZImWH+ZrAhfZTHCxxfYmlY8wiU04NlPsocj3orm2x4bNq/Agm6dt3YUXd0owjnfZin0RVI0n0tvj+sJCPr95p0lhi0Y4BGEcRvE43Mq8v7Q2kLy9qNlqLC20pmF4ItMJ1UxANqcc4qut1ARGjjRzEl/yXSSktHA6hxyUOqVPt6LZFMM9hmRcuEwdFwxJivHel0pHcLkcx9fgCsuF89RULl2ieZ9ovIvR4o7ryDm3BQJUNrLZpRvl68aHDhVR0603/S5vbFZUFxFkPwH7iMql4OKxBol/fVwf16fHjQX6rOUnpOsVZPgKcSlsfM/hHloiXkGBb3jPoPKuD911566QlYJDR32DF9YE5sJLMrct/7An60q5gYhNIqX2nJ6TTcW09fxt4bm1s2znp0Ahe/EErN/omnjqMImH2j5qxezVAncScXBgw7I3NplDotn4iLuNQtE1ylzwmJPnF+hQe2oMb1AVYb5ViQuyR8cBgQEj9GVOycBoHuSQeCebOlO5uzB8e73oqkKlVTP0CFBjUqX1dgioa+9RKjX5AHHbP3sV6G4YFzBM4eMkrHQvpEJrs5ke+De5bqKwpAbR7rvjUAbc7ac6fH+PLzn+nR9ncvU932ual6v7jr0YRrV3pkKzU65xUnf6JlcAdm8UFEyk+W0REQQhJBacX74TWiqHDZa4/wqzz7KBy18hx7ajrHHEbZpXnxenmzSv84+wga/CgAkN0sXJyjfJmJml8rCCltiQA35aqywlOGAK/V1CGF7+RHAjihti9IehUVLxEwCDu4fbVDi/6wzoOf5jBf+igOxSvPuPUVWgJPz70jE+E3LKqXQVeKePigZLNw3F1y17QX/OSKs5//SSUULD2LYWFRajcWXlOEpkLUpdhM6+aa2QxlhyhoJ7uZGPBa2XRetHZvhwzIweUgCRIQReUmemHJ7koMPUg5nRShWeCSsSjTYDxU/CBuqcZ64pTxrMYP5PtBmcRYkASm3Y7WbwSsN+7Qv9LXthG9rH2jlaOROmwAKzdOLSbeYrp4O/KsjyZQZ8APKOyca/ssKhCMNd/t6NbhcrRIs+CY/gj+seCQ55dTzM/J4=","layer_level":3},{"id":"eb7f762e-5efe-48cc-b280-f68e363cbcc8","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"视频处理功能集成","description":"gui-video-processing","prompt":"全面阐述GUI与视频处理功能的集成方法。分析text_interface.py中的文本输入控件如何配置video.py中提供的视频转音频、音频转文字、视频加水印等功能。具体说明mark2video函数的参数(如水印文字、字体、颜色)如何通过GUI界面进行设置,并描述video2mp3和audio2txt等函数在GUI中的调用流程和结果展示方式。提供一个用户通过界面操作完成视频水印添加的完整代码示例,包括事件绑定和异步处理机制。","parent_id":"c8b75962-2412-4786-a59b-a3d2969e09c0","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/text_interface.py,office/api/video.py","gmt_create":"2025-11-26T20:53:07.159151+08:00","gmt_modified":"2025-11-26T21:36:22.4705784+08:00","raw_data":"WikiEncrypted:PQ+uVW02d44FbNYIrdsdIRzTQbAX05V9G918J+O0rDgNMy4HNbRvwoYslFp1Jpy05/TO5gh2GwQAOoPRXQ1+ZKepSJFLjdz+AJFnby6TxzJXd76SblNmo2379u4SUh70GodL63BfHd0rnr6Zi2OPjSS2om646WHOHbpMuFxLIq2HCUmpj0dMuGJIizptJT7kZAjWrcnpP/vOq41+wyEg6OLBh7Kc3VctQoJezvGCYgAprSMABkg0Ha6Rr1jmUUcLuYIpLkpYXhQlegDNUChNqZNCpPTu68yfkT5UKUHBCB/XnzsBZkJ90EkwpvZtxh9YY9q6LPTUuX7fwjOHVYt5mRDkf/oM4Kc7PPuXQroLcyWt0RYZX7AiDrL7MfNsvxxLjuqJaCeJYxCQb/iT/AzzOdBVmdL1nJvp3AYoaNjiQj6/RM8MESgXckoMoyMYoYErvqbYBwp4BjYt+42qrCi/9Dt1lGD71ywfcSvnoVfWX0OvrNOPfOuV0eSTAvgh96+S2V6ZhBAcUL8iADVvT1lcXuK+I7KFFUlneRfj/mnGLhZGqLoe4EVegGw/ymJG7TBNauxAtoSGcgXhXHZG4ZjuIbGXMKDuLvW1OYE4fZF4+8MlEJlp4ObRcjd/H5YlMx1A6NB3M/tyHQoWDhfzbRpSEJSR99pxqlqdcewLCYG2tTr1RZycMI+329+2jBA8kidn/TRZWmV4GtRdOj3Qb6WaepqaZn8gcPzP00eLzm47ViXeTzviQ5WsnMHJ99qicp/puFp14gbneBkc852C8/3mG9zSVhTTvcIFkmg7Qkjbs3dvZH81174ciD+GPeDr80aeJyP7bgY9RCbTiketmLlWnZH0nsykdfc+DO8SllXH5fvVgfsPhMnULBoB3uarhJh/IWmpGZlUTOCt3HDXW0xM/lDbd/xUBV85buTWk9bi7jiCE/3Ms6F/2u41+0jQUuyhVqLD5gWz42YDD0C78Dd8Gkhg8UbDcFUVj7lGh5jh4/e7RQtfjWun4PLNKqmV91n//NOlz4xz7SeU4Kg3A04e6gnleOTplZQqnBrWyU55+DArJpVTcATqfMUepKIEg3fe0ryDbam2zYYI7tS2s0wJ0RBTfStQeWqOY7GbGR1sx15hmRH0wL/e/z+cVEdFgy4Jn4PYWvHP5DHkNnIBlUnBhBgLQSlENRL7LfbJ5eZu5lX+BR8rVIacKmCter//j8HZ","layer_level":3},{"id":"84bb86a4-20ca-408e-bb74-69510b09619c","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"工具集功能集成","description":"gui-utility-tools","prompt":"系统说明GUI如何集成office/api/tools.py提供的多样化工具功能,包括密码生成、二维码生成、翻译、天气查询、IP解析、网速测试等。描述status_info_interface.py中不同状态提示组件(InfoBar、StateToolTip)如何根据具体工具的执行状态(成功、警告、错误)进行动态反馈。提供典型工具(如qrcodetools、passwordtools)的调用流程图,涵盖用户操作、后台处理与界面响应的完整闭环,并分析多工具功能统一管理的设计模式。","parent_id":"ca6067ef-5206-4e99-9e65-628a084a2c9b","order":1,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/status_info_interface.py,office/api/tools.py","gmt_create":"2025-11-26T20:53:11.3268122+08:00","gmt_modified":"2025-11-26T21:37:37.8188005+08:00","raw_data":"WikiEncrypted:Ncj79hKsAuofnQITIf9/4UZ224axeowhRs669AyrN+PW6OYdZK+AW6y1YtQ4k0WdZJEhRMXvU0JHBY3u+Xm7213NtuXnuJsVQFsViak3XHvgxoI7potetNejzfv9EozTkLcC6UagReAiDDbyHi51ZbMzflv3NfbdqYPv6H7KYCCSIsqa4pRramBgRiN7BIaHcmSRNd+5xDVwrgNGv3wXATp/F5w/tpxeEa5DKXRjZtZb+nE4xQjm+ml/Y4tddMdt5qng2rk9gJXb+G5Q8hAZgRn3ED4yvBywsDmFs+xUJXXtRR/I4xkEjlziE9dOEGkqRh3tC3G4XnsgU6SjXL69socnv3W97NA7AqjIsollwuVKPv/zQhiw9wNmUL7rS4QddiOAhcIANFHMguTOdW1b9/aQHg4MNalbH+kPtkMfLQAEr+U8XUD13PG8319xv1n5UVT+sDDn1uN3gLlUJ5rCWGU1+BmvDglCnXDXfTAwMUAATaIQ0osFFwt/4oJVba9RfgsKMtf0NxQB5w+TLdz7LPDcvcUKS1brNFu6MIx43XxctZHBdL9UZxdTphqPfEPczeHledSLtdOFOn3+r36MyNYQX9/OIdSGZtqkyT7mXP8iR09fgSQipxCl7+aoJd4Wk3Twt9ZnWoqXjMgm3YDJ1UTFuLcJH2yobx3X3wpxZRwToPaN7e6DF4wVJWWsHpn7ffTy/nmcvpPf7yGaeIc+BRuw6AmOelUj7D+iCeH12uvNWrJomPxTTpsciOf5MXkSID3p7s/fYmRoPlyGSEILnenqlbNj5bs8h2MXdvvb7wyNpLN/JBnBrVqwiDDnRI8+qHbpbL8sKD+dua2Vh4IGaFmSMjfQFNk2pd2IGPeKi8S0MXBmrEZczrQYGu+V0r7G3aGLYuSK1aOEeiLdaxOG+g7HdjxHO3PhW+v4jlYDlqYIjevLHEJaR1BlHB4ay0XwwvcAwubf1u8lcY96THLgwXLPWlawzNa2/TXw5CrfZKubbl5sfs+GhfqSKmNYStuFgdFn44/2t1XqRw8PsabQifSuIo9TrWWUS0gBKa8cNr+UEre242LIcvUyzQ3zgGtQr95ONPKjEPjaoahZgJ7nTLs0vi8vob56CaxETY5mJ5eqhS8q9L95+JTgFevkYD97unYZ3Q/SudI6LkqtiAAhn/a0k0HxtophZ/pyKNN/TndJFUDAMAUSF51roOy0CUcGgciEwHpy9Hfxy6S/TAIkMg==","layer_level":3},{"id":"19390422-54c4-43e3-9595-68c4d6b0bb5b","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"定时发送消息","description":"wechat-scheduled-send","prompt":"深入解析send_message_by_time函数的定时任务实现机制,包括时间参数的格式要求(如'YYYY-MM-DD HH:MM:SS')和内部调度逻辑。结合'定时发送.py'和'定时群发.py'两个示例,演示单次定时消息与周期性群发任务的配置方法。说明该功能如何通过后台线程或定时器实现非阻塞执行。指导用户正确设置系统时间与网络同步,避免因时区差异导致发送异常。提供任务取消、异常重试等高级用法建议。","parent_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","order":1,"progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/004-定时发送.py,examples/PyOfficeRobot/010-定时群发.py","gmt_create":"2025-11-26T20:53:29.3883993+08:00","gmt_modified":"2025-11-26T21:37:23.025712+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tJbchqvlriYxAFkixG8bdg3AldDfpN8Ve4ToRhWYs77X6gaECd3dVu78gEoLLWtkkJOFSx3hK3CojL3ohzUAdmQdCtTUgHOq9v4vOwBzvnxjZq1QXLYctJyHJF54XcQ3VWDvw/EmTbpmpROr5fCDbaiU8ODsrfp239nr6/XJOSl6EO23bqcA8Y9357baqV7PAe9CbwoZ5PrJ1CrZRO3aDjLzrrSdLiWtPLBRBzNCF76T7YhnQdApC3cVIIaT/xInV4m2QMaXtJ5fL/c6+hWyVYhsYkminHIs6IE0mPROWFQYU7hDcwqZPQeTr7eFIQ3SsmLAGkhCqtvn9eV4UElLIfxp3od6FdqGSD9RfkoBZAf1DT6SSc6tviBIPLHLNVjYc4Ps2SHbvTAlGJRugUaxlt9BKsi0/+DBToy2PpQNYE9ukhT/4VTrIaF7TjrV0iUDQvQm3TU646pvp10lDzxANAAw1v9gt3YYq4L3hbHHWpPuBhbNhaA/fQU7/lwchyoxz8O2WVwDD4j5X7nuU3/GOySHPpIen2gZIchDegnFKkT7S1/gvOnSgjPSOb7+wgR5UlG9D5bbqavTQb+6Ent9RPMVACVKjrkcNVACNth+4jnTQwh8RnRVSVlk6EAiMwa+SoeV7w38KpZcaRrTgIR8OzRmIZLHuqw67ZC76wh+PvBXT10PHZfwiZLrCRzeA7uFTuLAbHdhObXUOCO38m3j9sWH6hD77paQv80Scz490bFmJxjaPjp06DhCTNNMfpfrsViY+x0fuJmcrV0Hi3Z6ajZXQAtGnvjXfIFpOEw+5zyHhpP4E5IXtpuT60588nVjdmgg2f78T5gXYj4bRdRyYwiEXdlFxiXpzWUR6xzCPaG1nGlyxsphkbF+pvZfEGYsD8NDeHAliM1ULbgqwTxWcOmV0GNj15cvRMgOK9jxT2Z1y1BpPXz+BlS7se2KbprBRBs7cCtxAiIkcZhLCoSUP8Wcyr32udFN0WDN+PsdkVx4VjxfIfSg9u039p9ngJ+BObS/Nh7lLEsbHzkKbErKQY/uOa1wkYCzYMVlUPoG5TgCTzhGeFVUZxJoUOJDaRgJYFUvk03Uz1Pg7RQtYfKotvU=","layer_level":3},{"id":"ede0e1ab-84de-4436-9bd3-7fbc92a72f78","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"高级图像处理","description":"advanced-image-processing","prompt":"创建高级图像处理功能的全面文档,涵盖txt2wordcloud、img2Cartoon、pencil4img和eliminate_background等高级功能。深入解析txt2wordcloud词云生成流程,包括文本预处理、字体选择、色彩映射机制及mask图像应用技巧,结合示例展示自定义样式配置。说明img2Cartoon卡通化处理的百度AI API集成方式、调用配额管理与client_api/client_secret参数配置。阐述pencil4img铅笔画风格转换的算法原理与图像边缘检测技术。详细解释eliminate_background消除背景功能的实现机制,包括背景色自动识别(左上角像素采样)、RGB容差(margin参数)控制与透明度处理,提供处理纯色背景图片的最佳实践。涵盖opencv-python、baidu-aip等AI相关依赖库的安装与配置指南。","parent_id":"2add2cae-512d-4dec-acf0-6cd787932142","order":1,"progress_status":"completed","dependent_files":"office/api/image.py,examples/poimage/文本转词云.py,examples/poimage/图片去水印.py,office/lib/image/eliminate_background.py","gmt_create":"2025-11-26T20:53:30.6725436+08:00","gmt_modified":"2025-11-26T21:37:14.5733167+08:00","raw_data":"WikiEncrypted:qSUmbhu+RuqdVWUcJ+wGd3Nu9ZpM6rxZmv5Rsc49UWAhJYORsuaRyhKxtklKA0mz5HQ/hmtGOnFYA9SZQ+TQtlcMHQD37ZPVI8p5qfgtB2/Qp56TQ2E9PHSiwyfzSkSBZ1D6+GSbgeztCkuD39IoXvHBPu3lpBs/WH+DdbsbXxSG+IVlcvtW/Oopjsot0EC3EfZdF6KVDbwI8aQKwBPI1S+JIFgStjNZREsd/2vwj3A8KItHOTL+WFbD5tdhWk3/K7TjD3lZC9wMDVAF7q3z0kjHtSd1YD4PkbUs2uTnf0ZslddQprkOuCT7zGp7cPNzA+qIsTfrIyZpV2x3nqo6IzeihS7r7lt/b48VOvjV/Qry3tcXDECldd96zrU6+St8C9hAQTxqlV2734yIHOJuBC7dtd0YqhSnY6cO0WZDNAXVTahNsNq4a3lyio4ge6FbqV0RiwBaIjx4TVI80gkuu7v8H35hbNbxdDEcG7SoUqf6w4qeU10SDg8ii6bgjGz/1yASYfbjoOMJsWXz7ElqQSc7BXI84SvNlTv8uS8GCtMTTklerlzxpIR2SZNSEsFcfp7pdcLA4/O7FcJLD6J+p53llusyBA94cQw6Jywfst8ogHmV6y+u/2ZbLpdSvMvKemmVJXo4NiMg09jKAbiqz9zUcbpOGXSB46QCCEnyQTkQ3avo1VN9DUzefXcGCpultiM14VmZXe5a4p2m7tFi1aEkzkFQOnGTy5+1ZomBxvibtXtDUNtqsik1KZXKKmpaK5Rp0/4om8eavGpKbMOvgreLj4Ff+am77J1noA7Ry2qOBNx5iNxZlBG+p2UqWI23IB1iL6WhAqIxSQV/cP48CLzhDXyDgZ6G+k52R5VFo0XLRMUizqMCm7pSQXx6fabVKB57wDIbOzf6mmyaGuWXiEanwuLMa183qZtR5zuLv0K+L4vizxh3T0msXJpdRHp8HRBXHnidXaSo7M8jb1d3x3k0iVZcAxwT/YtWTEF8T/mrNKVjdn26ZBYxvE9WP8EUghINE8ecYrtiIt7xW7UOIVLRdgBfTw/2jRfZeAl0jDhDkHJFcXPXbIBP9IWKrfNhIwKGCQo37IYFa9qjKqbsp62hX6ZE5qkPzooa6k5id+6ylOPFphvsdxbVU1C0I96LOjRbaJEA6SlMdP2cU/1jadfbxl1nSN5/1L8GDyfjUC8weNLWzeP+LoJ/bbaj3/dH7jinhsbIrEOvt0Sk/FNGCK5kKfuoOOAORm7N3398X+eJyDB0o5yby//aB8oNa1GdsHgUD2GtZxozjGLB+yTlTj7Kxr9i5prStccEjB7DB2c6mGOEXuoY5i8FHEO5ng4Z0Lc8EBcT0QnuwQLvW2Qp/BrebomN9BCF2jBdBon8A+s/rSDDM8PGlKoDdx3988JvEFkKUmkLT1iWte0+3II52hEuhbYv/L3O8hBb2b6oaD1tsQnDB+FW/0irPUj7vJnFz0vxuLsphjM1yzD97WDpx+kPSdT0O5OzaaEEyKtXSRQujzeQGgukYN/XjWfzcHIujdPB98AXhqYBClK4vFjHbZRwQ5fnQ3/+y3a9oG7t+Oo77/OTRxTDgo34dI4zLJgWYX423+WiHmvm+AswFzum2P/duVAfaFAwK0Kja4/7kEUBdJmqJTC9jZuGBmaFtt6EQtAwwei1GC0YjwtVTKotZzSrNTILVLfqZL/DYJCokbNoBsmX3DZQxD6udbS1Au2eRUypTvPwxm8GMBezld6mjg==","layer_level":3},{"id":"f02f61d4-07cd-4a91-9a71-b0578eb120e8","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"定时消息发送","description":"scheduled-messaging","prompt":"详细说明定时发送消息功能(send_message_by_time)与定时群发功能(send)的技术实现。解释参数who(接收者)、message(消息内容)和time(发送时间)的使用方式,支持24小时制时间点设定。提供实际代码示例,展示如何用于每日提醒、营销推送等场景。分析定时群发的内部逻辑,包括群组遍历与消息广播机制。指出当前定时功能依赖系统时间轮询,建议结合cron或APScheduler进行更复杂调度。讨论可能的时间同步问题及容错机制,确保消息准时送达。","parent_id":"0d3591e6-05eb-4c99-8c4b-77afedac49ea","order":1,"progress_status":"completed","dependent_files":"examples/PyOfficeRobot/004-定时发送.py,examples/PyOfficeRobot/010-定时群发.py,office/api/wechat.py","gmt_create":"2025-11-26T20:53:36.3500974+08:00","gmt_modified":"2025-11-26T21:38:28.1139593+08:00","raw_data":"WikiEncrypted:Ixm4kI/Z7v0V3JxitGlz9foJw6/n3qn/p5XLPHuarGKcy1ahbaqhsmY83vSxlJIHyI3b8TPXPt8GJdqnEHl84wRyxrDlwIMnFvWkA7jw3hJz50GsO1Tr54QPlaFTKWE7fDrzMfJ11FGuzKFos6vYERD6ZyUD1DAosD3lvE1gYp+qPYopywPb0T3UL1YetUI3fputEPZX0mE534GDaZIjY83m7Tf+6s2YgPVFcYqaaZLyl+WJ3v942JtOsEthjtOP+yOnaDnu+izzMtBckn7i+8nnp5Mvek879Cmv0p2zwVz9yO4vTCSXgtbKvPoUS8ftmNAO3egHJoUF1MLsBWzgug44wQf67l4pORaMoVa6zxb/EIgNHZaX4GqIf6+ueC0Os/DEKXCkZNvlgorRWH7VVM13ftRztqCkXxwZg+dCjapT/w3BN4xlgmD1autdYYxeCh3SqfBCWZ7racH/BNRbTnIuS1NvPeM3VXSRb0o8xl8k/B2zgAj+YLPfh061wABOba16ebhvyXwOWy0EssLF+5t6V9mFJ98pHB6FUih3whLN6IzHMaPrxUYDUovDzqcWDYHlLkpCunt7GbF1Rlex3xFx9aIgFsGTnOSp9EmN7Q9gKUHTX+c7pl4SrFqimBGP3cSvGunGavFGkRJnAZFFnN6isbSpxTnu33VO2n1lQ0+XkGMeIAtSCMLx/oIucWy5o24pSNOqj2G6KKORKMLngZaIHdYsf622vIt7t8zVbJ3ejboI18OMJWl2W889PdCT9LkXLchO4IYVz6TVgqoY0WZHxsddSbtuCtLUiRGaVeM6UaJ01iiWSNkqVqO6S5Ktz8pYRQ7NLzH9VSjH8Qb7IjqtCeozaCyNT5m7BuoOqZgeNRmvzfTqmMkCZHaRhFIYxjk1cPOn2MvLKRgibTB+HpgJr9S6XegJQDYHYYCHvmHZAHYK4kDs3KdJCLYuxsK4c+xSh3O7KGEg3AkoAz6KtIkHIVAyYTbi+YpRU1TWswhijm4XazQLTR0EsJ8Ena+FdsXzb9YHm5MdHAuDSZedEge0Q/mvMguJLLl94/pGVCZYAxR6sROQnpQA5ks7jLLrGpbLCzcP10EudPkzjPAH/RVa80J/+YFnxictGXOuiVBVGmRwtu2ylaSFlD62rkl+GRi7cfJtPeLAiDlVo4GA/WR08DGYmV+TUn9Rtb66F9gXegyB6b2u8tGUeDPNl5PsyEqP7VwQGnpSG0sF7czozKPoQtyF8bVzvyUZqJnUhFGqUUOb31og3r3z8j0v6p3FFC2m1tG7DhebPNun8HjaXA==","layer_level":3},{"id":"5da29eb1-dd1f-48a6-94c8-1f2ad1420f35","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"合并到同一Sheet","description":"merge2sheet-function","prompt":"深入讲解merge2sheet函数如何将多个Excel文件的数据追加至同一工作表中。阐述output_sheet_name参数对目标sheet的命名控制,output_excel_name参数对输出文件的路径与名称定义。结合真实示例说明数据追加时的行列对齐逻辑与标题行处理机制。探讨在大数据量场景下openpyxl与pandas的性能对比,提供分批读取与写入的优化方案,并给出避免内存溢出的最佳实践。","parent_id":"2bea2dfa-9a57-4c02-9f82-5f8267fb5caf","order":1,"progress_status":"completed","dependent_files":"examples/poexcel/合并2个Excel的内容到一个sheet中.py,office/api/excel.py","gmt_create":"2025-11-26T20:53:43.266618+08:00","gmt_modified":"2025-11-26T21:38:30.195149+08:00","raw_data":"WikiEncrypted:S7kEndY/dAdtskAMee7DvmSamA6BIg9TwE+6t2/LWNxX01kDeVF3nS/OMw2aUo4IuQGl8t/ktUO9zZaDDBVapuaEYsyQInK+Teb3kyL2LjrVYOkaXBK+udO6SH7RBxqhj4Lz61B723ypyxWDWpjT2lZVThhX0hkyExj5gSU02dqwqnl/0lDS2pft8Yu2+MNsZh0e/+syJnukxFJELYIS7rEA68DXNuFLnyy0xX/JZtq0WEKPqw+yukek9XSX+1ZyY6MQBL9rZ86dbLOxVkoMhAzZa/47gwEG2wH21CJiEdEjsiwN0Wockv+Y0OkK8+krqXk/Ym6jNBahItdPMwUSf/M6OvYwq8gtWJ53gVnKMgkCzhQ5ZzEqdsuCdwSMhOP0gOjQxdknAKcWDZIDF1DGtmUqPw7L5NiYF+T6iN+sojgTb7jHBoKoapVLpg0jtCWVqE8XjgWKD9Z2KudhAbWfhF18kPiC/ZDsdqyuY/qenHh2+Qlie9znB5ZbVjBP9iU3szxIK1YaelirL0K3EIDwPl+jK29BlAC5IvHsINEfvEnkTUC9rC+b1tJvsRtKk8TNAUWM9ybE+LxW16bZlGfG2EVNZcLqQJSZb409uccYfKbnFwVA12B4lTJmUVCietQ7hfMSc4kro+v/oLRrM4sbTw7cYvUN8mJvlvp76fv0Y5uDQSSU4Gc5jwlNGb+BT09lC8Y60cXNDmWy18r//u1Jg/RymdtCMhzZuFd37ruNPjh+7w4p7yOjRjfVcjB9/kqnyU2n+HMd6ZINY2N91oyFEs+egKUyRhyqkcEs+DHkFSrpEcqY3PlCffRQDAF5sOPtQ01lW0hXn70TDgFVPgR3N0kHwYn8t+UXm0nXnL4CZHIAdGQcvJyN7RwQ8WmQl8CYtcDlKiV4RkKMJ2gB5Oh3hUKPVD1bPkwBBSkrywFEM8ZyBaY3yHnXuhuT92N9d5cStP3x8kaFcLFolhWmT/6yyKCMwTaJsg0BcYdAKoPY0/+KkRAe4AV3ifJ/R+oF+GkG","layer_level":3},{"id":"d5efff4b-8c76-47e0-acf0-ac47de7204bb","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"按列值拆分","description":"split-by-column","prompt":"深入解析基于列数据内容的智能拆分功能,重点讲解split_excel_by_column函数的实现原理。说明column参数从1开始计数的设计原因及其与Python索引习惯的差异。剖析process_xls与process_xlsx对不同格式的兼容处理机制,揭示xlrd与openpyxl库在只读模式下的性能优势。通过代码片段展示如何根据地区、部门等分类字段自动分组生成独立文件,并讨论当指定列超出范围时的错误处理逻辑。提供大文件拆分时的进度条集成(tqdm)和内存占用优化建议。","parent_id":"faeb2733-9b92-4fc8-83ad-70bb5688ee30","order":1,"progress_status":"completed","dependent_files":"examples/poexcel/根据指定的列,拆分excel.py,office/lib/excel/SplitExcel.py,contributors/bulabean/SplitExcel.py","gmt_create":"2025-11-26T20:53:44.1034871+08:00","gmt_modified":"2025-11-26T21:38:40.5036367+08:00","raw_data":"WikiEncrypted:6Cd3HTNJl6XP3zH7snBMpTfbBEFbVjwJdOV4Y4crOoM3WOXvH8S8Evnm0Ec4q/vbZAHP6RhclwGdgOZ0ADcdaX7sFkR3Bu+m/hO5FBgcj6sMt1vmoIxRYpfPemz1XRkTSyx+X9mfI/lE/CcU2Rh4hn5uOEzmNyNTUB+KPfFCenA18NcE1gkfVQmIsIt3AV/JGnR8+jvJxD3K3l+NOePCJdYETUSO8xyoiwKXqi88KEgZYIlbYy7fBDiYLLj89Ge6tUbQAhgC/pWuSeuQraqoIm0cS6nMXwkzIo3/kug/K34s8/kmv1JyeG2nIXufcwM9hePZRE7ophU6ZtSDkt+PRT6ZYtYsoMFB67C2Uf8ET6Wv6L5N7X1iVRMGs4tELrPk9/yYyGqvhMsSCL1G1UQnBjprcppBlQvNBIwP/+YeciZWlcygy9TpxKBmoBc+Y/+ayFfPn6porFVSE8YZ7376BtdfEqtcLQBnfC1qHnuBUHKdfMsgUhITyn8Y2Bz6e6Z9IFaHq1Z3QG1ZMp1pWk2BopKLJHm8e5+hPjHI39Fy0GekW/XIFNkf2cNNUJhjyeribGPJLkBENNc1+h7Vh+wHeOSt+ISIN4xaZiOISN/9aTsZXO4AIsTPszZFWxHAvIbRRUgS9wbMK4aAKczrGnsxYcar4gNfrtWEZMNO7CJ+vcgGRyNpzqCbOHdr3FgmUJJPb2i4y+Wpv0XsvNLSNhmuxuvp8M5yaVL2R3K94CNyrHC4/TKfJRuCUNwXq64B8aWE8etb+wKgRz4MzXY1g0HtSGdzoaRviUWjw6f1fOdOtiduGnlQOWnlvT1W/3uOVcRRDTq9xL4y3t9o6MkEXcQiXZ/gIu1WSOl2JC8pG/B8t/31qbj8UTcu6NmmS34wcI8MEZspyAIKFSpEU/uIMX8hdCCV5CeKQAxi1xa2Ou4EumqtNeKkStfUB4PNvcz2wz2qKIjs9+DZSLtZ7UvbyQ0EMTBZJknMqk8PnbcpHwCIfNCzOd3AxETEFDdcsVDH/qQ4rkikYLJFRJJBfT5PRjDuJv+byJ6cfDngK3q//frqWdulNUs6ZX2R/AaAQqiXmsF4yV80chpeRm95NXnRmBnY2oUN6UKBGFAI0xiVvSo8c2F988sFbv4WU9ECaLeAs4uFqGYlNHfR1aA1hwB7KBS9e6Ax6h5SdQ6huK4V7a9ElrgfUlcXy4VmzJyIvS1fZrRR0ccAWxDhz+3hiVV7P1mvTK66FLbuqp68jW4mdi/ccP1hbGOlWMbRJ1tQ6xbxA6MCmI+enjhaolTzFBOTIZKSA8/TW+a+wrdwlIzGj8eORzbfXfPRKKlrGyCNgAytbLd9","layer_level":3},{"id":"ff7a478b-63bc-4b53-a079-cfc3326c82fe","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF转Word","description":"pdf-to-word","prompt":"深入讲解`office.pdf.pdf2docx`功能的技术实现和使用场景,重点描述如何将PDF文档转换为可编辑的.docx格式。解析`file_path`和`output_path`参数的具体含义与使用规范,说明转换过程中对文本、表格、图像元素的保留机制。针对不同操作系统(Windows使用python-office,Mac/Linux使用popdf)提供适配方案和安装指引。通过示例展示复杂版式(如多栏排版、公式、图表)PDF的转换效果与局限性。提供性能优化建议,包括大文件分块处理、内存占用监控及失败重试机制。","parent_id":"be0c69a6-6c67-4442-958b-7c6fb66891ca","order":1,"progress_status":"completed","dependent_files":"examples/popdf/pdf转word.py,office/api/pdf.py","gmt_create":"2025-11-26T20:53:55.877152+08:00","gmt_modified":"2025-11-26T21:39:45.776285+08:00","raw_data":"WikiEncrypted:Pydghlf5Vo0qa17BK+8s8zSgZC1vuzHrre74IhgG14+f0txbxmZVcy3nPdhTbHtaI12URaQORemtF2ZW/4ESC63+r0TjyxZwdBknvxC5SNcfJ3asYuWreXxmcPGN+oRCrj2AHuY0rm5ACV1CVIvSvaRunuIx8rHyYqgmg3dyPfoB/7sEK7Wi1+mTCzFiN74r9+FTg0VLMVXaWGytj/e3qXQXZXjHNQDtb9adJbY/AppEFMl1t+Edqzyzs6wu1VZ5MPDPJ4K+aRRi/93OFNIKjqpeCaTfgUVE46FjvKbk9dIHAF0VucCBdRg1wh/lOBO/H1HfjQ2ltb1fQIm+lMRcP5UKEfSzW4sf18eq4iIRciWGdokNqRbeoGn7Mj+eQH3O1NALaiiQ1hqRDo8E8GYhZlsNIBhvoaqn9GTLX9ZcnwKQOvySFnO1dpfoO8rQ6rjUo3cGYqMjCbS0EuZownVElgrkiKc77wwb1jhkuTqGXpphxLEf663nWBpKejepiyC2MFs5QvFJpGjY1suOmQouwfraTQJ3MWEu9t14IuEjwGBSsNWYRZvCK6/VkngCeHpCkoTwgZ7+cTH60gQcUGCdb8xpWRLuybhcQmsGTvwMC4Llfz46hI2klrZJwBfsuDzt12GdzhxIn8eRZ+y/WEKOcZzFWNUXyBJ0ndKdqH3ImR68ftorLJwF+e1QDYD8CIn34D4oN2J59hbVxvhDoS2s9St1j6Dfig2ONltztEw94ts+EnA+A6hQLzKRzKv+b36r/LMXjDrOsyJTQhuen+SAEfL/4MC/3gWlQrbMajRJ3k5lLgMPmHgskJRM7uGXyhqkhodReZHGNqWqn9N/PlxjYlWfO2T1wUvObxJZt//mR0XYs7VxKpOT82J3CIeK52y4jtan3qYKz8Lm735tyACPqH69m6B9kcXjUwjodE/30EeWdEVKkyO2y795dUiNxs+EO8smm2eL6VXaWuy6IgE0PwnBwSfLWUS7MMIiL6YDwyEHReZWeVuN7S8QaSFCKTqvSnZChGsiuZBksJURg+h2z5E2rw9/0RhEc3BaI3FhcnFFy+ahCV8qZSBB1FwSeEIFGTTnFuAy1mWDgIty0s2X619yvLLeZ9NbQIQhXNpC/TdB23AEBUPDxY9Fnp9rxMPh","layer_level":3},{"id":"75cd0a91-bb97-4811-9083-3684c7ae4636","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"快速开始","description":"getting-started","prompt":"创建快速入门教程,帮助新用户在几分钟内运行第一个自动化任务。利用examples/目录下的丰富示例脚本(如PyOfficeRobot/001-发一条信息.py、poexcel/创建Excel文件.py)作为教学素材,选取2-3个最具代表性的简单用例(如发送微信消息、创建Excel文件、转换PDF)进行演示。提供完整的代码片段和预期输出说明,强调‘一行代码’的使用范式。指导用户如何下载或定位examples文件夹,修改示例中的参数(如文件路径、接收人)以适应本地环境,并成功执行脚本。解释这些示例如何映射到核心API模块(如wechat、excel、pdf)。包含从安装后到执行第一个脚本的完整工作流,解决可能遇到的路径或依赖问题,确保零基础用户也能顺利完成。","order":2,"progress_status":"completed","dependent_files":"examples/,README.md","gmt_create":"2025-11-26T20:50:26.6662352+08:00","gmt_modified":"2025-11-26T20:55:17.1180252+08:00","raw_data":"WikiEncrypted:qfgbutC7oyxR6nMxrwk1ODnNMBEQ3/sG78fQT1yXWju83LC7H/jAM8CEAvWT8huE5OClmQiIfNYNxHQ9s7RRS6MrB0bpNwXYWPyFXl2OlUtEjx552X3UwBOXUlbIT01OWRQvoTlZCwkjhbcLXpbQRFMw1JBXjGNbNLWCKkxvX4UjsSmJAEHSR26pYfYXy1K4O5xpLa6hpk9/tfXSbDC8SlIMtNero8o8HwZsoPppIAa0zp5J8WaMrBG20U4Mpq/fBzzLWa9PNcJ1jVBqkT2CiDr9JJBo0U1W6JtPcmSc2CUN8ZCMdZjA1LDsEruJ0dOgK79JbeiERrrM+/lzvqFOCteERVVMnKZvXz3q1sxIb2GnGYdzQZtsw+gzwks+v5gVV+hYyOTUcrfVr/ZQ4LmIv2A3LkwiM3r5lIVG8eRlCW6o/m8qmSCbxgGnHQutST/POmGjToskp4sV8Bcq3xUYA+uml8EdoA/HJ3Q9Mly+PT1xM+EBuv4wOc1eABuzSZC4FX6sv+Dox8UlTNtmQ5/bRInjctHC6bJdVcr9Y7EslYMW6toLOe03hapK3aT1emeCpW54qiYmGsx4IOrpncMCnRoH/eXpVywbZoX6JVS6oJblct++2HOXtGvpD6olf+PzgmKNrTDydljsB2P81O+i7vLa7IrgxAA27eF+Qic4TJGriJowQxGLUtTGVYjkXD1UQB4lKNJX7/NlrMjbVmdtgJuRGybW/lCCkDZakKA+g800uyLJUy8dP1umTEihKFsIq1jnvMjDN9utH1k+SzCke/pzY2bzfjVQCJSM6tcikRf/jcGNHdgtm/CpyFMcwEd9zL033XGoC+x7MVhdm3h6mPOtffrSnJzLqEVCUllFF2bW++P6OQNHZ1OBCHg7j6D07JOt9EMD4+GYT9R2QvqaDjsh05m5/6Hcv4/9d/viWMuDqTnI6Axw9pgOH5eon9V1Kjzu3T64q8WzxKtZk5RMSJhyDCCGvKHH3NA1eQRmy6QzE8qe+fwu93z3haM8X7dhr2Zk8EHrl3+3pL7X6aaYiXWHbns1B+bPR4Nt26P1TpXcO+q3kXvlakDsgaTrI6k6DG+vNeDTtQuyO6MMUm/AuUc7D/Oy5yG4rBNV109a16AjZLBGdlgy6e9F93HVKkKvWjYDhGyW0pTMIr9FG1fQZXBTg6PVZzZU1Ahau9BDjhtSeZYsJJ1BJ39P8NKf2K6Uqk7ccv+xI/2P/LfBltPGqL93vPymX0V6PZ321jHg9yrDBT17K3ov6RxwjPLIZfIT7/nhfcR/vc/u5Rg78L29ZP4lMqEWQk0NQv2Piw+Se+XwDfoTX65RznSbqpn6DBuoB+cnv0Gfd8cVIrg940pysgSFGdQXaUqyD1z6IMjmITlE0anAJlK+V7X8Mnl8XJs+LlgOIcNzHPnqKnWJMhWq5lIrui03heLyhk+5Rn6o8V6tlaGEEbxswIKcqbJ8e0Hoyed1zaUAqQvoPddeoa/25Q=="},{"id":"3babe136-8c6b-43de-8ea6-36bf688cc629","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"国际化支持","description":"gui-internationalization","prompt":"详细说明GUI的国际化实现机制,基于translator.py和.ts/.qm语言资源文件。解释如何通过QLocale和QTranslator实现中英文(及繁体)切换,描述语言配置项在cfg中的定义方式,以及应用启动时的语言加载流程(参考demo.py中的初始化逻辑)。提供新增语言支持的操作指南,包括.ts文件生成、翻译流程和编译为.qm文件的方法。结合实际代码展示多语言文本在界面中的动态加载效果。","parent_id":"bf12cfdb-30f2-4b0d-bc87-c1bd097570ef","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/common/translator.py,gui/qtpy/version2/gallery/resource/i18n/","gmt_create":"2025-11-26T20:50:50.3261172+08:00","gmt_modified":"2025-11-26T21:02:30.9603456+08:00","raw_data":"WikiEncrypted:7L7SSUtpALuJ1PGG1aUhF97EDljUDGxMMvl0Echz8kwEuOr5bCGISvgQoHaXLrzAL8EdcgTibN5CTHhdPw9EmT6QrHjXRcZP3ORw8mVv9jYW+30O1/fpOdD1iV3Hi4ESIP9qjUgb6Ukdj3rYxyy8XzoTWk1+8whA6aUdbbRuF4OTQtCmiXWIvkfWSA28ly6xvDWHb4aMU/Qn5ZfX509uWxJj9ks3Mh78j7ojTPdiGPqSl2xaIOPfy5RJSVG5nwyZQwSIUkE7STuVyV/7s2sv94kbr2fvolxQP7/vY1z1t7dJcGlGTP8XSL+o8POC9SFnNKRpXFtpjIFBNNe+ZSUhmt0qlW9ss7QcgU4/z54eHUzRsPsJhXpG8XDyhci7M9yf93oLZrKiejDq07yEZbrUe18nwwoC/ln0UwZWJTjGC4XOnK+CRqKovaXmA5wcAtYXXYb+9encahWiypPeoWOuf538NJq4ffRd4oaePl8gINFnwXvNcjV+JEnO3CsJrwfakrEFB8MWDd7O5h8JQcO5U2awYeXhJ16dhiZgB56csDtxgkIOD0O+Zo8L1Or5N/0aixyNEVmL7rX/wKENkcpUjDEEPLlN0lIUGJaGXLiMiHzU7SBK/FVCvggXVz/veLL1ylI/fNFu4AUIEg3aCeMJfTFQO5TgowXov7GrG9vyS1iCpxRHJYBy48+Z+kdTBNJ4bGgUDXZJb5ouy6/dd7bLZHP0yM1Zkp0EZJ9r1pPPpmQQFNSBHur/ChR3NrP+RBRS0Ew9Q9t/xIHB3goGB4E0WuOy3rzq9rMFJVdFvacnvN75IMbwh3VJi8oeWw3HOTTbhL15/+3QJKBN9wu6OZX5/e+uHXtrOmoNXzA0uE/aocqHHSVWEscbNHkxs6x9kp2YKi+Oz7fhWZOdKJTdcXlCibv8LBSZTW6yaIAL4BM+SxfZzsWC/33w4bqYm8Zo2NAyq/lGYJkjcfwbj2Qoz5+cKuoYbZI1PlFD78kcNW4FmXGGeJ83HNxhQ+Rv3PYFRvcghLgvUR3cR4UZVDJLA+hg7SVaOMpgtIEiY9g52ynRb9LWDFAokKH1Uuk36jDI3wL1xEK+KQnKmMSCCg2vEBr2068oytwo0FJGJm3nBz+TV0c=","layer_level":1},{"id":"d2ac020f-81e6-411f-a866-ab1d3e411da2","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"自动化通信","description":"automation-communication","prompt":"构建自动化通信功能的全面文档,涵盖邮件发送与微信机器人两大核心能力。详细描述email.py中SMTP配置、附件添加、HTML邮件构建等接口的使用方式,并结合poemail/中的发送邮件.py示例进行说明。深入解析wechat.py提供的微信自动化功能,包括消息收发、群组管理、定时任务等,引用PyOfficeRobot/系列脚本(如发一条信息.py、定时群发.py)作为应用实例。解释会话保持机制、二维码登录流程及安全性注意事项。提供故障排查指南,如网络超时、账号限制等问题的应对策略。","parent_id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","order":2,"progress_status":"completed","dependent_files":"office/api/email.py,office/api/wechat.py,examples/PyOfficeRobot/,examples/poemail/","gmt_create":"2025-11-26T20:50:56.4189082+08:00","gmt_modified":"2025-11-26T21:02:40.5175772+08:00","raw_data":"WikiEncrypted:ZCORAne7l5wn5JMRd1ey/jam7fnExtbyyQF/5tXRL3W84jRzb3I0SbBs/u4msLh1grhLrNVykNQzohFxAhmAQ8saJQtrNCaahFDNA1xLEVFaJztwDq6ARTbaDbnhS/DbrZ2CT5Da+8Vk9KBjznqM09PojMjmy4V/XjF6pk1pkcDmaG+NPmPQSL+0/xIQ7myQwOAAgUXzj0hB/v53tpbKreMfvUnKaXoVSxTbPenFoxSFYBqokEOrM/wHmnkSpYyUxvY8Qdt3lCoD3aMh8RFMxk8EaB2DRNQTomSlgyzvobC3LpJgDCsh5xZrSCifgWtx22vVfq1shgxsdxnfZJ05Le3ugn5SluB2k0TkpbokTPy5T+BJTfMjy79/z8VifgaA8GrFTVKwi3rwuLWxMajzvvf/K7wKx8gebNbwbKicSAHXnNo/IG2jerGE9oz4hW5f3IBdaM3XnHi0BIeCQfKZCT9+iA6+GDqSPP5f9L6zS21ePNr9Qz+w84ltMbO9nexluabP7R5K+lbQjbMbgcLYhL3B2V6ytLRmzAqYy7a7eHOmCAn6eMhtvaT+3LA6fQHB8vDOZuXxQvtsO2ZzQ53FYsr/S8IUX7MHFogQNNrFgM/fG7u+8foFPVXd4qhJw9TZzSSgGfn4MWIG5DyqGXJ0A9/RpSFXoPpY9pEg8YxNzK31uKn0mhbmdUQvH16hUH8dYkVQwqGHLIC8xt3jpgtS+0bSOs3m+EDfj6sK91XuqSxISkqoA0d1pe2WKF+xn8jf4C8lBZ8Bw0RHbrM+jEjhgU45ZRd2GA+/3zYdT7PaJQbCpfYx1Z8MY6E965ZU8oMPhyrwXEpHytY0elzxstR1pyyAREMDnCOQSJyIN2p863kUJvXMroBChlfxjKNang5o3CeI3bgYKZIKsQmwATRsS2isgrrj4KvjtDY7nhdz/Ig/j3r8KbXuME7ftoy4XxDIzrMyT1ACkDcxl/4i9jBnS+wcKYevczuJEc+c8iM9F6D36KcRL8gWy3uuTlRH+Y29tIJcHB0OlJnHvEZFAocdY/OMhueDf7FzcbACN7RKifuWk8pUmDLMEysjM3h45XgdBkCDMWk4zFYVbOF8Y6+MWEOmqkB9FdxW7nyMdZNkMdgYzpH9lCcOP1vaWJ2/nJhF9dJ1LYqeX9Qgm271LZYRvzAiAa9iPTfhjHBIXz/DOPo6pH+KnbtCUoQd0nQ75EfiemcL5NnSvVCZUKqcF1NDTb0elJUORgfJBHDH0MjcUdreaNqSYygDVRWIO7WQ+r5TfR59ixC+EIXOHWmxAgg05Q5Zi42+DAjKAiQ6ZUA99TujkHoAha7i/U2k0s7tBGGDZt6GAzSWb+9nFtabUzG1S1jnaz/t2bYuOTYBH/go1Tg=","layer_level":1},{"id":"ad656284-e5b6-4784-af1d-b7c75a25975f","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Version3 概述","description":"gui-version3-overview","prompt":"编写关于python-office GUI Version3的初步架构文档,分析其作为新一代GUI版本的技术起点。基于main.py文件内容,说明当前版本处于早期开发阶段,仅包含项目入口点和基础初始化逻辑。探讨可能的技术演进方向,如是否延续QFluentWidgets框架或尝试其他前端技术栈。指出当前功能缺失现状,明确开发路线图中待实现的核心模块,包括功能面板集成、模块化插件架构和状态管理机制。为贡献者提供参与开发的指引,说明如何基于此基础进行功能扩展。","parent_id":"b38da97e-0ae0-4dc5-8bdd-d53a1218c22a","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version3/main.py","gmt_create":"2025-11-26T20:51:13.5139753+08:00","gmt_modified":"2025-11-26T21:22:51.0957713+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwAktLnwOxABuDBdYzRkturpCjg/qPdUhHrxSzsYr+AgyUMFwKp8cTFacVqhbWpNYx6ysNE28BKbXtJ7aFzMRNa4qh1/9PvzYEbJ2MED2zcVDk/MDwJUfuacXDCTVrqVhmpt30NjybrppQDDGROmzbCPqWwvL12tB2rXf6c6bo1uHaAtcHrFhROhBGNJ8dpHfWcSMXSS9v76zdnQvcVyu70f1VQotAzH+xq4YDwoh3guR2iRS61loC6zlO2G8sa+wS+1SDGoRu9yIrdF4MBxtics7uhj6bi3Rx0DeNcIJ4K8Uq4O6quNsKmRWoM3MmvLZ+Hfm4Pj0pN9TMvAhjIGhVIDqUJpczQIdIKnAF17dpiSwU5mGKaTXOFsMqsidn+50cRcqyHA3q2m+HMaMNQR7lGFh1FeyU3FulXDoKVxbY2M6EBYhWbVEuROQ6nGmDusFRGzQEguABeyc2APSgPBEMNTUyJeaLT9helpuam9uLhA0wJMWbopQz1WTy0+JeE0+/PAyjMNaNQlyjtkW+kpmSGrz9oIVNNztoY21dTeEjwujIqJhhrvXVtG8F4eG6yv2iDdw0mSF6dML6P/fAjp2jR81emrqbDIFtkCEgKysakfXD/sMT1Q7wEyR+xDEGIVI1F3ObGfoPEH8EUSSsokpLD/urg+PoGP5mcMXPZ0wSzAxlxUnI7HV0DnrGQhNjvgD/XIlnrA9hf+ZuwfPk35zP9o1bVuNKTeKysR5VjCZ3F6Jxi9nks68kDVCXKAn6mG+N93C8r5+iqihiIA9gaCaOW0la0N8S+1F/tQdeemhx9SYeuPe0HwZHGOwKraHklrSVZmgd1vfDjcPS/w+hsGgeWFtste2EoZLfe7LjQ4cGLbGz47icqPy8rcXPFJfBp8qT79cIk2ZgGuUESOEHzufSn+eaEnSMvMrkdz/5EUdvRQ5jVtNhZj7YJ6NKix2cJZLTTh5x9mgg2Wsk94gwLJ0w6PPOA8JmKq1PqcmpGbcd7lMHL5P9waxcDHG9VxZMNNZ9wo3E0k1yvKKkqsdUdDVhnowudG+nITBbT7QmslkkTT3CQg4Dwpbf3dFqLwU5uchX27f44VCLOCKM4SNscFrop4X8djl+c51xQ9Ezh0cuCIVvdc74zNEUcmAEXpprBUcCw==","layer_level":2},{"id":"64c00342-40b1-4002-a280-6393d621ab4d","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文件管理API","description":"api-reference-file","prompt":"编写文件管理API的详细文档,针对office.api.file模块。详述get_file_list、batch_rename、organize_files、search_by_content、check_suffix等函数的功能。解释参数如path、old_name、new_name、rules、keyword、target_type等的含义。提供批量获取指定类型文件列表、根据规则重命名文件、按类型自动整理文件夹以及基于文件内容搜索的完整示例。说明函数内部的文件系统操作逻辑和潜在的IO异常。指导用户如何构建有效的重命名和整理规则。明确该模块如何被集成到主包中,使`office.file`成为可用的命名空间。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":2,"progress_status":"completed","dependent_files":"office/api/file.py","gmt_create":"2025-11-26T20:51:18.1844023+08:00","gmt_modified":"2025-11-26T21:03:27.8570005+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg5wWUCPD7zMUbUPrACqcr1fTu3IvhLqteUaV4ZJT+GQTYDCpIR19+bKP8O2ZySVAX8iIBTcJ0b0oYK6AclGFVupFhBWikx9LiIitRbJ3fvzTVR9CrHc4sT/ACHyylBS9YxFeYJkA/e5pGpKuZZdX3N9lpGT3RJpxbfSScH/3LuNxGtnzVxyWdUlahM5vyHomfN2daWz06P1DOYuR91pvjP3v9KQcmf9YJSP31BN/1E3sXlFoKKHYSDwXL4zH18u13wffEHseEFC0MyNoHjrUuJg8VzPs8IbEZADZHsVdrh6OOJheY8mKmwUC//+R54CDmSWo0kiIrjIMe2B59nmB00jPxukOjaeeroyMj7RldhMkSaWFjZXzYw2ManxkrkkZ+4cMF6dtn+Gqj129qsr5PiPrkni2w7ytEOgjeQaAwGCrQZWXl2zqEgFaxUZStcCDlyksRfeUM2Hp6gpAxcEBhbrvC2Fu1Ham3S6O8og/2+X+3YdlMKktRWSCkMssk/bTawSNa3KkDS1J0IEAuINwDn2//944p5zwoO9sLJwmPE2r0jeNegt5s58yzhNVa1W67Uo+3gqYQljfcSwjz3gfzmjkR0qfWrCfx0WeUW+gLM3mC30ql02cHfF0ARaItFDeShVa/VvxwG2FpNge0GzjyKyQWVdRms+CdTaTiBTX+ldgnEc79e/SdOUH4Fpq78Frhf6rtXVbAKeQ82sJOs2Gvp4JzoXx0ZZW0enyNUu0QSIMy8FgOfN81s+5ioNqa+EPpuZmmtaq8tMJ0FC9bcCxPPPuzUwt60cdPTJksrpI3ADE/DPvspSAiAAs0AEpjMUMKF44sizXsz3d/yvyhQLBYMrUZEU2mxZXpBaCeBx1g8qS18fCBWC12+YK7DSqMcSp0LkF4iBn8DS5Sg/+NGI8KYe+4kDb1OIyIbqxmr+Hw4O/dmIXiG0C0mkVntQFOcCUnRNFYikH61wfOre7X7WwNqqrtmB0YaHlTETRLiC6v5gbV1PmG50SqCaZC1MVr8MQl8QSZEOWDMMWSzrCXqKzs3IIJMR8ihPG6XL4r6JZrs7l12185ZvCsblazm4QtAzTWndSlQ3/LmI154Aa3P4cyzRZEF3NlIfQ5ugT8eSoIkjMjP8czrrxV1QJwt3ixN3glEPdKs/zJuCfUvBslH4AOl/RcW8Que6LYi4+ic8gRSXa","layer_level":1},{"id":"5235253b-7037-4298-b76a-147a71088bbf","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF操作示例","description":"pdf-operations-examples","prompt":"全面介绍PDF相关自动化示例,包括加密解密、加水印、格式转换(TXT转PDF、PDF转Word/图片)、文件合并等核心功能。解释PyPDF2、pdfplumber等底层库的封装方式,说明如何设置密码权限、添加文本/图片水印、控制转换精度。提供处理大型PDF文件的内存优化技巧,并演示如何批量处理PDF文档。包含常见问题如字体丢失、格式错乱的应对策略。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","order":2,"progress_status":"completed","dependent_files":"examples/popdf/PDF加密.py,examples/popdf/PDF加水印.py,examples/popdf/PDF解密.py,examples/popdf/TXT转PDF.py,examples/popdf/pdf_demo.py,examples/popdf/pdf转word.py,examples/popdf/pdf转图片.py,examples/popdf/合并PDF.py","gmt_create":"2025-11-26T20:51:26.2352755+08:00","gmt_modified":"2025-11-26T21:04:20.6399176+08:00","raw_data":"WikiEncrypted:VwE3l+CgQ9gmKE/XMR9eLc6Tt5tN6m674Da7qmo7w4Hk1KQxu6wOED1zAUY4VYjWAbf3ehqKJq9++QAQA4XXY/OqUI5leaL8PjRspS147UqBkmuP40tRtloDNqQUHOHNVvVJKNveihRnLZSPgjDp/t/zJZgodHsgy9FNGQo0Nn5yidxS8q7L2DMYHJti9qD4NWbXU7z5ZxfCkufSqCcLvKa+Jzf/doKeTsL0e/mI0r9lXwYuNaVmZHNZTGKMEEbvDH2OBGReZpBWvfiSqPaceIJMnV4/c9Rcs/b5LCMM+Rfy+3if5YlPQETB1vmDqYqEAJNQSV4TiZB9nYdbCm5WTAk1IDOco/KFbYcON2KO2fKjB+SZAq6ZEr8JgYhxiUkz1b3LHtgF0JiMTGJub47k9WaeSZZMcZv0VW8tMWirZ0btKG76c9BPJerRIl7rIgv/bx4HMHwzxjAcnRegYYve2WFkZPJd4s+pkAgIjBpLksLOe5BwZi17qKJA5njpSJYEacchKZubAL7myIfjflCOrftJlSekU10foxtjOBPkIbfGBKLLHVci/kKQlJK63KiMBqmRDIRsI4qZZdkaOVLQdgAj/uQKUUWWsJjuhVvajpYyopNrj5x+WpnchZ9dmhsyvnEekUZmy7X6zAF8kMSEyUy4dPruvxp0KNhd1OF4SgiXorv2rH+hV/AOP9hZJFBRHe4voNpo6mX2OmbaNSm7xv9b3n+wfTJC9DQAWBUNq2gZdCGovS+3kEyDjyuDAvnDElMzED/AEEWmmkgfVzRnmV6DXKhkPnY1edmQrIu9/bwXdOK2OXJR3aa6+M9DBCLVg0ls5cB/cjMC0jKuaagW8GJ0IyYoNsw0Yz3ZH4IyHIvBN/9NV+uHToWGHDdert9+nLkT/BNxOHEzbL5o8EScSqWzjKkbU2dPZe68fpLZI3wVYUT/OwkSME10kOTS8obTxSOe+ePgqutSjcGj5Igq++E0kjj7XpTy5xsEoNgubiuqB2fhsRmAtGWpzp7k88D9i9vWBCShmpnBnMPo70g3enEwb+PLEkDKi+DdQC+2vxTElzVefTKBqQtJA70qYKuLe5T3Qh2aN4p7yGpE8cEskDjgi+Q/7xYMcJ8ADcCxpE3V8d0Jf1LEbfYNDcfWcjxJB2b9FLkdf6AUNeLZOmJ7VI19Os60R87wUpqaefT2oF+ffVbVRWIRaceWH5qnF2l+d1Ab+E8Qa3TyV/tvzqU4i+mJo8vxX8TW9fz926X1frFske7/c9/tV1Eit2lmxGvYopVXORXb51mlm9us9hyZvQ==","layer_level":1},{"id":"fe6367d1-81a3-4b95-a92e-cf12e5d7db5a","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"自定义UI组件","description":"gui-ui-components","prompt":"详细描述link_card.py、sample_card.py和avatar_widget.py中自定义控件的实现原理与使用方式。说明LinkCard用于导航跳转、SampleCard展示功能示例、AvatarWidget显示用户头像的具体UI设计与交互逻辑。结合代码示例解释这些组件如何通过继承Fluent Design控件进行样式定制,并通过信号槽机制与主窗口通信,实现高内聚低耦合的界面构建模式。","parent_id":"efdcccf6-6375-4180-abf1-f90510945ed1","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/components/link_card.py,gui/qtpy/version2/gallery/app/components/sample_card.py,gui/qtpy/version2/gallery/app/components/avatar_widget.py","gmt_create":"2025-11-26T20:51:30.2186242+08:00","gmt_modified":"2025-11-26T21:22:54.5360428+08:00","raw_data":"WikiEncrypted:bkaT8KPdtNh6SUBPSvMyLuGFNDZuWAfq/nRAXShIKZce3mB5Gzy9KTj9szZ0+l0MFfiCgDhe0L58H2bTjpNGkGZQtXH1FpNQG+Q5fMpyYIDWrULnW5HCf5oywOEbq5uwsYSpRL53HxGnz4CCA5p/7reRzYVcm7lKiB5mazZkcRgdNWe5os7iZ7b7HlKqTFKx3qCvIOEsuJiJqmX/RODSIfM3LvxIVtXvS5UPM/d+hHCjAA6Laxaa1z1R6O8Us/ypEhpZzw+yvBb8O4QY+4QcFhzXyDr5jZLo9C7uCfrjYOiB118/pNS7SAW8zOYNRi4uM8FzK6JZpn2A3GFGwPQcJ/gTod+2fTPeMY0aZ1kp4+nfTJ18TAV5LD+672C0genktlJT17rfOH/khUq8JjXQ/i9x+mx4D2suLNN4z3VnqpBsFRQ2Zxbjvfa7Ke/tvQmDQ/RPLSCZZy5QumJWccC7qj8nclykc1jhkUa7ec+T8wHSVVPRNfAfsuy/o8olVj6SucEwDN/OIWOpAzCynBicg2jgq//+kdWwx/HiDi1g5AV41EXM2XvpQ874AfRKSyPncnNMRJJYadif71Vs7w0EQZd5/5w4S65E81U+KZsTTPiTdXdmOUD2uX/LUqsLlCjKDP8U46/PFhRWIk6UIjSGJpIkQtm4p0mngfFYK0jzQGlvKuZ9uocOC7+aqMsobfC+fXl+Y1f0sFSvELyd/BJVakPr6aS9k4u9T4rNzfEVi2ZCxKGCQ0E/V8KI1FDA7rjL7aqnfXu0iDWMD5B6Re+HEfE/EbrmRpREXJDrRK/9LGlIF7cC170qgkLBbELLDiM2N1mN2WYznFN0wyIT77F3EPAST+fRGSThLKBw9vVezM/TPwGG3PTx2qa8H4bt3cKYbYuAO0ArefJZ1B2T6W/E4BwqxWgSd86gLYZ+YaP/ukIvrnws7RoUYJoshcQv3dndIc8klASkp51AG47vfE/wfE/QEsbbXy50T7mNAeeVwPh6H/EFlw93VLdalbpABdAzLWj43PkZs0KcRbIpR4oP+ipvgxaNf9UZ4TiMsiyLBaByE4qSi7FGVJGkbdsgLTJJrwOcLDhY/IAbUWU3pvbmZg==","layer_level":2},{"id":"c8b75962-2412-4786-a59b-a3d2969e09c0","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"多媒体处理功能集成","description":"gui-multimedia-processing","prompt":"全面说明GUI界面与多媒体处理功能(图片处理、视频标注、OCR识别)的集成方案。分析text_interface.py中输入组件如何与office/api/image.py、video.py和ocr.py进行交互,包括文件选择、参数配置、处理结果展示等流程。提供具体代码示例展示从界面操作到API调用的数据流。讨论性能优化策略和大文件处理的最佳实践。","parent_id":"e2f3c078-2962-4624-ac55-a7ae4ab1ba48","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/text_interface.py,office/api/image.py,office/api/video.py,office/api/ocr.py","gmt_create":"2025-11-26T20:51:43.5367179+08:00","gmt_modified":"2025-11-26T21:22:58.3232991+08:00","raw_data":"WikiEncrypted:WkAYmkPHKf+tzKJYBi4fksqdZjvq6c706eReDciOLw7YHQfAPsrLozFYXfON3n4JOA0XotbopkQo5ioGfE2El6VChYs7m6CpaxRk7NZvadFzxxm9D3jSnBdDzk9K4h51ab18mOBKedm27va8KbcQVvI+LynnR0PlO7H02SMqL86PgyeZOqMuSbueCvNBb6GBqLStUVfKtBbttKExHa9NIYtjZDbRWYNmqLOfilHivGR8Gb29mUWHiSfEi4ufdYozhNGVlYcCMGRRGg83PT/9jgomoKVCLEiBTwi5RhDwmPgp6y7aTsWTFwlpNl/AvwLFQccKZnvzKDITBOi+YoOWp+J2wRHz2TTTdNae0JOAA/MnSDP6gY6VPThKfvZybqochTuZ4OD06zxByd/6cToFbEcTxepVfVYGYDATcVL0rCwjQnFy9/BDJSZzDgJJu7KrTedOJ669fn3a4QrDdBNwPmGDupGiZZpJXKzR7DhczVhpZ8lDKfdD9h4q2cVGzySdYLQ0OxCgnfuotYEINUvJe+u82Ga9ajh5MmSHXUpgSoEJ+SJgB7vJhoTG0R+jcCYqaE4HBH7oN2I3mxNVrhOBPBHrznU7MW+Ed7/4SAYHhJnE4cl4FJrQ5unQQ4/q1SHZW9vlbTB9+cLYGzJLQwtR7BPgrEHRj8ByxpwnKKZxhf2SpqYzwh8dPCFc36Z6qTgKYGS8I69USYFiA06582y/D/yCqVV/FtNpF3owEDjwZLTPTZR7yZbSYfcPLiO59xwm2u5xDlvgKLVtcuj9iT7WNKTp0kzQcPAPivyeE9qx+gp1sol4mF6llDD5pZi3cfcb1qgudJQMbyd8flfXzkYpOK3//XtmBTLvmG7+Qh+wI/+yIk8VbFmbRqUX0rmcICnVKdVzSAaJBDpngjfZCMYzCjwyU5AuGP0wURj5Qb2O+vZXFGxLOsxzgKm/IlEgNtmtGbhZWzveWCoxwl++vfBrAhSqEqc1/Z6JAz5RByEMugaxp6LtZi6OpqC2T3pqrHe57O87T1iBqeYKFoCjoXI3hzXJa20wI57Jj3Fadju+DIQ=","layer_level":2},{"id":"08b54a2f-374e-422a-a35d-6a4838aadbfa","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF处理","description":"pdf-processing","prompt":"全面记录PDF处理模块的技术细节与使用方式,聚焦pdf.py中实现的加密、解密、加水印、格式转换(TXT转PDF、PDF转Word、PDF转图片)、合并PDF等关键功能。引用examples/popdf/中的具体脚本,展示每个API调用的完整流程,例如office.pdf.encrypt、office.pdf.add_watermark、office.pdf.merge等。说明各功能所依赖的第三方库(如PyPDF2、pdfplumber)及其作用边界。提供安全建议(如密码强度)、性能提示(大文件分块处理)以及常见错误(权限不足、字体缺失)的应对方案。文档应兼顾新手快速上手与开发者深度定制需求。","parent_id":"f7bcfd40-cf6d-413a-b3fa-59f8cc0f5a06","order":2,"progress_status":"completed","dependent_files":"office/api/pdf.py,examples/popdf/PDF加密.py,examples/popdf/PDF加水印.py,examples/popdf/PDF解密.py,examples/popdf/TXT转PDF.py,examples/popdf/pdf转word.py,examples/popdf/pdf转图片.py,examples/popdf/合并PDF.py","gmt_create":"2025-11-26T20:51:54.8831598+08:00","gmt_modified":"2025-11-26T21:23:50.6952381+08:00","raw_data":"WikiEncrypted:C1NZTVz0/dP4dfe+FAqLP7aaCWuQ/xTQ6PVuiLSN+17aYglBvMfaH8Gk+noz2XK9xGY5gYDsVXX72KS75moPT0EdGmxodBrwq3MEgOyvj4OljqF8ZD6XhLDuD2swaDRonXYnmUsteC+N+wqrJi2eSEwsStlTUkFDM1n26nVS59qwEqKgUe5wpuxAvH5FWPyiicxvfai5VPjlKf3e7nIhzFejcsphJYQ5KxPzVqpESf95tJroUuJy8mzc3ZfGSOsjuXAc60cPfe90Mo4gjT9oFqrEK5kuFUTetiHWGPMZiLMAQurFrGwiN2cLTwwQE2QqIW6zzHcdDpatRKASVruS1Lk33asE6dVaar5zfXRntzuSjAife5+4M+4gUulv4hZtppMcxdRvq2M9vTECfPqDGtrJLkVRE/WM/Trhf5zgWPMP4Qi7dIXRu+dtk8b9Y72mcelqfGCx8MiHjfofO+qxrgpR2ijFdKeZmq7mf73xmxZNcvy4Aw3gSS94dKMlWVcLcyLqu2hrA55Zf7aI8Og7bVix5F4Oj6Fxzz0xS4OkV15JF/2bjXQL1GOmrFdsFCgJmk5dtr+74qNjkj07rHZT1SHTEKek/qoiKaA5XAFaPpOdsC+42R2tSM+MUbi7deyn8RU3SGScJea+xOM2RP6WU1bah/l8atvT8jDnTU0OBtKTNXFuxktGhP8h6nejGnFH5TS8KPEUec1J0LMgg6ubJkjSm4edVGqEdpExh2eXPtzAmsOmFvamzzrYgxVbnr/GTmgHQb34oYOjHWMJvNaNktfjkUpANoZhmw4pTqDyXUWHSczjfkYWBZfBY1MMQCdhzOglxcPhclhS1NlpdyAFWuSP4q0YZUeIOQWdtV430UVnw57fo1DUl9TBBWR7zdMXqkqgMTiR4WS/ese+wqzyRgaXNStNFv2u8Oa7Tf8EzT3T1j8RcB+MTlbAWQjMiutkHg9j0KVb3edUGTq83qrWAba3A8O7cPJjdqS51I9IEC4GiFr7c1g5b2wZzBGpM98V5eKQzrGEZnYKhqdaAASayUDrNTuS8rJklcf5iJCkfj+3SYgtqHVvLL9MCnFQZtlD/Z/Cnps0zYw/c+XMMKfPgDC5c9OOZO1Cot2PF/UVfSoCD7ME/X+SD0F36LHinI4SNzAgD6ebt8+DbKZKBs63PNKHzKWCawPxpkYxE0oVw0FWZSI0sm1iJSkVfjuRbz0Vur5mXQOVTlWcjf3bqB+cDr8YNZV5aH/nioQ4zs279yKgui3nVdCSpM3k3wCJBv7EMScY7SMK2X0r9opHTszz04pRvmTNN7J1XP2xuiw+HKKNhrJ8hyyguob+8mhfVJPC+FmgMaTk53VAWOqMzJNxAZBdvqd7FaFtuvcbWRcaY5ZJ6ydWVmV0av41QQed0s8FzMdIsJUe6amZwUFbR0yAGHL2MmQRYJ1VkOxl/6Fl7mAi/4Ws9YCeVo99/KZt5mfE0mbt8fHc530bU81UgpjVTQkM+3KX1eM6GHrKqgDNg0Kxwgi+ampMHNVqVb6mAfkyS43BbH8fxlv1BXln3BRtaQ==","layer_level":2},{"id":"fb2f4f78-8161-46e5-a06f-b3ac24af8bed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"主题与样式系统","description":"gui-version2-theme-style","prompt":"编写python-office GUI Version2主题与样式系统的全面文档,详细说明style_sheet.py中定义的CSS样式规则、主题切换逻辑和动态样式加载机制。描述setting_interface.py中主题设置功能如何与全局配置联动,实现亮色/暗色模式切换。解释style_sheet.py与config.json配置文件的协同工作方式,以及自定义主题的扩展方法。提供样式覆盖、优先级管理和性能优化的最佳实践指南。","parent_id":"fb4b14d8-a3c9-4f17-8f24-10e8bfdb747b","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/common/style_sheet.py,gui/qtpy/version2/gallery/app/view/setting_interface.py,gui/qtpy/version2/gallery/app/common/config.py","gmt_create":"2025-11-26T20:52:14.1919105+08:00","gmt_modified":"2025-11-26T21:40:22.3395549+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwEFEuqXiqqNI1aSGqq+T1OUio9zR6ATiO9uXCzs7nx7rmSmZZM8H2v2MFegxNT9ksNtBO1Skk1c8PRe8F5+7H0XKd1QF22GEaELWQttRNvNMawM7gWlmQ8kbPfYGIpOFrCw+pgR+rkDD2il35WtNvreuEfhR1S5LxkimllCAbP7tMZM4ys1yua7cOfPWltvAq/NPzbXb081xraLYyQ3yCkCH8vucQPKnD2NROicHxVuPEPAyCSNqU6tgYKi7Vdf5uPwjte7v6HoFcIhw3kVlhfkpJDcn4KQEvfr4Gl6N2A6mfvha895ipMVsdPGOUvf29JT9qQxS1DJEK/dHJ5z9EY3CKRzLE8je9lZdukDdU7IvNR+AYd+xqpfMTW9Rhvp04iRO69AB1xtWeql2J1I7R9JHxW13EAni9FdCin7yLsY7a+uM+wnZrTG04RXH/4C0gPXr2bjVxFiSk8EGBcUUbR1U4AaTRVfuenXn90yVz0Ei2tu7S8q1Kf1u8BEb5PUb3S/qwxS5EM70ZA3hm5zJkGqe4vnVFuZ/OWicGhYEaasM7R7eotZzg+YyV3+6j6mPjBGcLeVevl9v5C/fsX2MaG3V3kn1E6Vf91O5yADpFJ8n/icmi680Q6oWPdm0d5y6jSGniVEZWaK5ehFKWKE2NYTk1szZ8fLlXzdDir1WXjJshhmCMZCdp258lLG5lgudlbI6P37V+0Q8dStLWmGSVvvuT39WWH4Y4Uuj7QnjUAEU+ufyNS+PoBk1rLC2OmrUzFG8blBTN/iGP2Mw09AsMMBDOl6sltYTJXUy3AP14AjW6EeKmCFoNAlQ9mkSTzYCeg47FnwKFWG5wDe30adibYD4DI64Dy7ddSkIfuPR4cBljZbGltt9nWt37bYv1fGnI8Pt22X13fufPpa0dCQrtRA4fMERkMLjXXLHd8vGubHT9K697feUcz6bMyy+k7VYYSD6VoRu4PXwR2TyAa+6E6GohioV+jNeEEODMnha1qAAhAekSbIlMJ+U+IFSU4hTZN43oOSPyVw/wJLaz8gTEmZlAMwwcfP3ZqRcS3Ut9EqtKb3hZeAomcAXEzSnX4onDY0mn+0KZu+5n2u2Fl5rpWj/oDOvgoNaHZ+lncURQgS1tY0EGP2lDUJUSNAJ1zPKyA==","layer_level":3},{"id":"f766024a-5940-4054-b625-2043d2445d05","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"AI集成与智能对话","description":"wechat-ai-integration","prompt":"开发详细文档,介绍微信与AI模型的集成能力,特别是ChatGPT和智能聊天机器人的实现方式。深入解析011-chat_chatgpt.py中如何通过API密钥连接OpenAI服务,实现实时对话中转;说明012、智能聊天.py中chat_robot接口的封装逻辑,支持持续会话上下文管理。提供配置指南,包括如何获取和设置API密钥、如何指定对话对象、如何处理速率限制和鉴权失败。包含安全建议,如密钥保护、请求日志脱敏,并展示在智能客服、个人助理等场景下的应用案例。同时指出当前实现为单轮/多轮对话的限制及可能的扩展方向。","parent_id":"25cbcf29-42d4-410d-b72e-2c345cf71be5","order":2,"progress_status":"completed","dependent_files":"examples/PyOfficeRobot/011-chat_chatgpt.py,examples/PyOfficeRobot/012、智能聊天.py","gmt_create":"2025-11-26T20:52:21.1790374+08:00","gmt_modified":"2025-11-26T21:24:26.3125375+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tNzJl2pLvbiws5faG8daZ0+OoZA1fdtfYbAbhKRaTQ/TUpkBYn9ETKxkisSU6KzuyrhYaNTMUcFCtOygdaxkOaRcVqhiNmXWhcUmHY+pkxXaipGCZVq9fcLAnzQS0wsd322MB9TWyEqZxJ86u42Fc3kkpSjCn1FeOXp/YdgHPKQHo9AhyyMCpPCbtingl/uqQZmYEZNnL7gsRR4sF0dVbxfI5HOoPraoX2jv6vhtOy8S85YLz95VIZHMPAhqKaun7KCQpipF3/akUo2+E4Ad2IQgrtRGEMDlJcfSAIPM+MXN/KMNOCFDoaBskc9pdXwAAIY+QlzaX//DDQWKX52JMZI6pzakmoUD8ZCYgPm+2x1++IINGZ1WuG0ecUC7hjGAhBRFz04/4KMbuvmpRj0X3vFE2Anq50nsB/phUMMAS0gtnoqVg7XWTxUCzsx0DnRuHjZnS/UCe51tzcUXX4iTn+4cq7O5NAGSLrh5dG/oB4aXc7Sg/UCqqAFn3aksHD2toHdItaR+46W5KlgQ9J1vohCL48mQ2Wkq2MZADi/9SPL/EAuV6RXZeJ86JARiJxkbxbEHfqpFkBSWmo1Y0FFa8YM3uboQcAYDBh4zZyymlqsTsoniXY0pM1ZBMUs1E6K3cNWd6ALmTeuEi0uB1LSvdqVZdW2QcUvStVwr/l3th00Zzxv0uYd3l3n/paj7KtfiCqpXUa9ka4t/VnNlYj+nH3QCL5D0IMy9Cf5HNPyVo2kf2ooo4F0eeCWytfqXTiPO3XojqbNtvr7qo+gL8xcSgBCVmUhk3CvKNhSze/zeIqc7BWRwMqRCrZF4KUDw0cIJfzQGMeREmnCx+4j0isjlg+8yij3EedVqBN0ezEYDOgVMjLmBwUCbzJkSo/YC95q84mEMV1Azz78pMsJwK9+kgJVYdOu0Pug6mfIvLey2UjjhkkrqBHsR8Wj7MCEzifA1PvocbhpriHnfB8o9ZtFbowtmTjAx1IxhsJmygkwnaE7NB+clBSdrWNQFEZsqydJibVOQOnjnWBeCPSMdcGM2rpI+wMk7qUeDJDAYU9/qdzg8Y1uiOasmN485ethz2V07enI6UnYq41mjbtc6HhH8IX/gfNSW+SBqNaW2U5QUs/nC3fsmcDbH4sDLAK3LF1ijG12VAQoxbAQyzc/Npjvo8cytFd64UjOzCRlqFfQdXgAHOHBTpSkXRiEdBp/4VGtdeo/cLylPX4juDjQjfiYbciUCU/r3FJ4rwqh0n+tASxJ4W9gWDQaCDlblHuLzgDxiWOvFJUDN9MTwWUYEK81M4DFcGmjFwloI9ZY3gh7nhyC9JPvrwgwNB4bPFTd5UsFyg4scXmGh+icvyrLwarDA1vPR6peweTUYsEhahpz7IgeN","layer_level":2},{"id":"faeb2733-9b92-4fc8-83ad-70bb5688ee30","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"拆分Excel文件","description":"excel-split","prompt":"全面解析两种拆分模式:按sheet拆分(sheet2excel)和按列值拆分(split_excel_by_column)。前者适用于将多表工作簿分发给不同负责人,后者常用于按地区、部门等字段进行数据分离。详细说明column参数的索引规则(从1开始),并展示worksheet_name指定特定工作表的高级用法。通过代码片段揭示openpyxl读取与xlwt写入的兼容性处理机制,讨论大文件拆分时的性能瓶颈及优化方案。","parent_id":"3aff6fd1-b9c7-4eff-b8f5-26462a3f14a1","order":2,"progress_status":"completed","dependent_files":"examples/poexcel/同一个excel里的不同sheet,拆分为不同的excel文件.py,examples/poexcel/根据指定的列,拆分excel.py,office/lib/excel/SplitExcel.py,contributors/bulabean/SplitExcel.py","gmt_create":"2025-11-26T20:52:27.498085+08:00","gmt_modified":"2025-11-26T21:24:15.9348433+08:00","raw_data":"WikiEncrypted:8x3JSVErdDUDs2nXur+vXd/DBHXjIClZ6pf/87dAsQriD55cXS+RLp3FDeCBJ06DWas2BOpNOJmvaEX+D767e/TMxfYJjYVLxk7Yu8Bz9hQNPxTVHycJRdGoykPBfSAhzagd/TA6MnmCBO1kAZtz7aF1ohySAmSAqQChYZBxzXBczlzR3vxNQEx8P/nDIyD+DgU2e7M3ne/cCz5/nnAmKyxHhTfSS+rsf8+0w3U+k8AX4tfArOGnIrCdqNcD/Xl4YAdpCpvM3kpE5m8MpZLLEa1oxav4i+8nNFIiSxdNli79jetAx2BgGfXCOSBFLicK4lyoQN7LBpw0bOlVrrAZKk0rZ+lIwohmCwhx4Ld4RAAmbmOJS8Ay13ULNeic+BbyXfD8zjEJa4Dd3l1tOQgFPpGmdP+6FwHLjAo2extnifGa+nytXhqHtUqnad1HlNIOrWN87Vs5hZZrHvopu5eoaBtcVHXVwaV+AsEXFiBKmrJpSwb3BYa4v7SsyhMICfEFJm55A8R83/j8I5E50eskUXSffDKjo04i8Hlw++wcWDSAFVTCOexNpWgJ5+OW1yx+C/lOznV7aurq97V9k8E3s6mLsI4uEgP0qgkdnpHB2N/0rfBZZizDkqhkG73oznv99cSO0tOuGy2hVoMRiv8kRxIQ/fwvSX4yigUqH8k1xiGjzP5Px0OXVie/bPKWldJxq6Q70xHk9FCcdhR8NVtLWKzx1JEVEr4MPt3v0blfA+DmYFQ1MdS9VtDHGxirHpICpf0DyUa9b+RFi2XkqWikf56DgmBREb7qhP1/PI5KkgaB5kzqOHk9J70wQcmg7WpqyL8ChglP68zGqTLSaNsgK1Khfa9G0VuwCBcRxyi42kSDFnb4Gouvrvw56SXHsxNvZTOrdA7BofHQUz4kvRE4fe0DDboYJvuGCqmDYGA5VREEq1TJG8QhUxDVgXlJJjOj1VxGMqYezmRX91ufA8f7BxJrNDLfeIRifChjyqDuhjOpqOZDZZz/6KgfWYJERqobAw5W60Si8PfUzwdC3LjqOSI91elSgHziTzQ5V6McYSUUzdNyv7AfLrrVa+w5tTVp6L4o6WZoj0DnYcY4e8OWQp7MJK+638PdIhgigAhhALD2+F0KLHuGRDqdsf6Ab0tQkCxi0Qo1djOCRXsnwx4tzasw+XVqynk2ebSqXG6OQtvdSypSvsG8mnHxV/swHj0m9fm93tXLEmC6Ngv8aovoCIUssKIUWfWHiCtjnsDJBpg=","layer_level":2},{"id":"86b479ca-7855-49ab-9a1d-8eeb9844f72b","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF内容合并","description":"pdf-content-merging","prompt":"全面阐述多个PDF文件合并为单一文档的功能实现。通过`office.pdf.merge2pdf`接口演示如何按指定顺序合并PDF文件列表,确保页面排列正确。解释合并过程中元数据(如标题、作者)的继承规则,以及如何处理不同页面尺寸、旋转角度不一致的问题。提供合并大型PDF文件时的性能优化方案,包括分块加载、临时文件管理等技术手段。展示实际应用场景,如将多个报告、合同或电子书章节合并为完整文档。","parent_id":"5235253b-7037-4298-b76a-147a71088bbf","order":2,"progress_status":"completed","dependent_files":"examples/popdf/合并PDF.py","gmt_create":"2025-11-26T20:52:38.046451+08:00","gmt_modified":"2025-11-26T21:24:57.7670313+08:00","raw_data":"WikiEncrypted:q/pojVgrR63XDdQ5hjpTx6aJ8CSbMnpj22DQMn/YOJvSLlleD052INYWpw1+qKMN85VD6iVE3GEnCE/+gr6tFOTQ54YrE2xiLx+8L+88ngSqJ5p7aDV2L4LRRlHe2hj98upsnkCS6tKGouVnqfmZerm8OzN2W6C/cVSiC7NYcYCodPM6qBSEWm00OYjB+++H6X1euTJoK5Zkoxm7VUClkU9gXp7w4mzji9cwrlK7zufgOh4b1xcqpVToAOgz/3/G5Rt7S3PxYh5F91MCxhyWTtDroydaYWbkM1Ub/e9ZRS8ck7PcY/TqFOh7mXjYiBnsu3fMwQJszMqjP+AuO7FtkZnvW5EwqioFg6s1iOpTitz5c64eB3y1Jae34F3H9IJyOaCzbtDxxgDDZA/3837lCcQVbJIuyKg3HNgSwn9OOL8kgvzeQjAjuG9ZcAsTOL6y80PMDI/wfBwHMsFkaMi4d/yrOxPgAC0JM3+LSB/2W4hbaIcspbwAMevem9ocUhYTcd2+pIMakA3ZRB35WjIKvNI/Kd/vAsFV4pIP0wHt+WkGZVB8C0yvPzYh1wEczI8wB61jjrJxBwWDjrfg/OIeGi74V+KfXuiNBxGcq6197FFhvPYXNmmAgn3McgL7C11YQcfMCNwRnB35vJqqJj5AafTI7TFb9Fi3lQSeIBNgWKBp9lTiXlau5MJKgysBYq2ZjcyG5N+zbUewGASwpA7sa1F3dSY9/9/2gIrrIb0eASyEWha5+pbCwP5oULpGPGKR0wgh+89182bnm6bPHdlcnfZt0j3da/b9NcOLASOkm4TN2u76ndY8O1ALOQb/Kg7bAiJI37Rai8KVcaXiNxy2o+neqeEN/xf9Lhh7qLT+RsPKRk5fRDX5mzFBro5PraYuyTvfqgCtCobP6emvgxa7u/0CuOTxkPC/gi757mw85zN2MTXM42mA/cMwErvEqr17PkNo4Q5xtYpQQ0RrJxOz4QWzBZybbnf5jsYRB+4BeaxD+vIcuQFiYQa9AxytiWg02JxUSzcowqqC1DEZPjeOzxRm3Hlfj8qvGbPZaeg6F44=","layer_level":2},{"id":"6a7c9b66-24cc-4cb9-b37a-80d03a83fe7d","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图片去水印","description":"image-dewatermark","prompt":"系统化介绍poimage.del_watermark函数的调用方式,涵盖输入输出图像路径的配置要求。强调路径不能包含中文字符的限制及其原因(编码兼容性问题)。解释去水印算法的基本原理(如基于OpenCV的修复技术),并说明对不同图片格式(JPG、PNG等)的支持情况。提供处理失败的排查思路,如检查依赖库安装、图像权限和磁盘空间。举例说明该功能在图像预处理、数据清洗中的应用。","parent_id":"e11e3a92-fe01-4716-8371-3f718d2870ee","order":2,"progress_status":"completed","dependent_files":"examples/poimage/图片去水印.py","gmt_create":"2025-11-26T20:52:46.6711546+08:00","gmt_modified":"2025-11-26T21:25:32.6223889+08:00","raw_data":"WikiEncrypted:vw8SwXDMWAcq3MVrbhINPKfsG/oNPJgWP2ONg9U8c+YI8Jkzy495sKBZnvlQYMAKHwoIOooa98ioZCoEDTAF+1dKUqr4UaCL3L9PuWdHPKQv2yu7PEk0nahzfX6L2qxAPA0rAx89XC7QiqsyhLYaY7yRxXSRlmo3lix+Wb+2UybfRphn8IH/b22WRfwwkThCMkK+lI0S65pBfUFtx6vy2APD1c5UPllN+Ug/juGb6eduSfWzlIBXY2veQY2rxkAj1MJrb0uxs0zBZVhwwE5NNnAY9dkC2oL72/VOPXa3HXQn7FMsBQYG19g2FS1vXQdlsAYufYrjf5xuIlGhKN+vWKJW8kAqkVm4TDrmo/mubzF9MxR8oayQCLMHesj9HYzH+j7iQCRkicmx1GX++WkTUqA9jd8ukBkFl8ELZbrZl8cgt/IPX1sqwF/NDQBTaCfjYzZp6uP6TdP8rVxFMFgMFccB861QDPdoM3Ef1YVBDm7EAjwdixgyqG2bUDuwNzZ+czMJ/sJ5EHiNL0En7C/lO4vpSLEIWWWMyA8dJwNFx5kFNSwA2ZQPliyFofljx9zexd0q3yc9DQ/UEbmcxTNkFDE9UfSqEZ1YaNo2I804/nCgjaYntuekjdkixomcEbL6fYeY93A5g5EDP73wZuiKOeUpl0PWLSruH69WclUSBl1Sj7U8qIQjbs8Jx4BlPQ8/6Lc9XxegucFgIyS+Npf2AiVaU0MAO1KhxYeAhCKYwAUsCfHVm+q+0PvI0YZgmCg4s7gbSSeSkTLhQk0UhNrqjXWXQ9sMNUtbuHMZYnLx2j1WZ/7TMbSSuQ6ai+1/2PoDEJSRPBKJwUQ3EP8Pm2EAMv2eg759RRKOOm6zzOU+DCq5VTc7DY9pcEJVkKKWiiBz1ajzDNdNrY3v1Xu65a0wHlgq3ZbhOEL/6xHJk2OuofPLfaziCF6k6LqMCiIM7S3uNQSX2Lm9wO5iTUQjvcsx2w==","layer_level":2},{"id":"2d0da31e-c761-42b0-9fb5-252a2a748db2","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"网页内容提取与电子书生成","description":"web-content-extraction-examples","prompt":"全面介绍网页内容抓取并转换为电子书(如EPUB、PDF)的技术流程。说明如何使用爬虫技术提取网页正文、去除广告和导航栏干扰,保留标题结构与图片资源。讲解内容重组逻辑、章节划分策略以及元数据(作者、标题、封面)的自动填充方式。结合实例展示如何批量处理多个网页生成可阅读的电子书文件,适用于知识归档、离线阅读等办公场景。","parent_id":"9f1b3695-d545-4923-baac-47827243ec01","order":2,"progress_status":"completed","dependent_files":"examples/pospider/网页转电子书.py","gmt_create":"2025-11-26T20:52:49.0247091+08:00","gmt_modified":"2025-11-26T21:26:00.9567093+08:00","raw_data":"WikiEncrypted:uoedhYh15E0twERiEgEQVTwRKlXaWf/gth0itP8/PGwpdfG1ZVrSr26NDe9A7AiL0ubpkmemNJjA9VzgSJI6R1vrHSRld/XIivC+R3Lh2tJzOsosm5KLacvNhzJXgsjXH7oR3zVO7GFl+ZUs1WM3a2m/fwvZQ/zERvd69tjCk28fFzZJ9SswpTdRt0sEglPjgvN06d5Sm9wDGRE1TZZ1bPBDemUosu1JUjoYCrN+s8GIpEa+7JBIINYu27HxGeZ3ZRhreekuM5R/OqGR5T9VJrsBnTRf7x0ZMlaN8/QcG3CpUcgi8jFs4Oeylq4Fxjxhz2fwHyNbeM4s5z57950ErpEFVCBw/YSCQxmjs6Dea08bT9b25sS8QR3qGiYtTHa3vqUvmS01L5j3/IfB88+wj+O6AQ8eQsC12DiWoyw0cIc18vKFkEclplIvqTmKhNj9dtiPLdLC0wuJBMSEaDy2s7S/qDUgIskQBij5XGk/r9e0v2ZnaLjk0qcBKoBj4Qw462sBMeJvSO+D2GswcogdXjsdHvCMrkuRuPtiwzM4HYWkmZUP2oV4r0VXoAamUgcl3uWB1X+QeDooAJ3Bpeul9sJnChPdr+wQD+Q5E3L7kQDfNqLD6N1x2caQFqp1ATfVJObtGwEea0EK8J6rbyI2RFGjobtpo2kB5VvTtcYHlcQix8dSllUwvAR0/+FymwBDGtsbv1W7WsIzzAqF5gjKM4JBQBTFWivoVQD1Y4VS9HnekEQ7gcJ/ePp8H8N2QCCL9W8opLD2JWxoEqKxYntjh0eKBVU10CYxlRnrxezIpc5LCmNgoNbSXX9EzXFDOzZQihhIZReQ8z8UBGg2T1v+XOhq+PrRk1nrMsDGe2NHY3pTDAnijYJ8ZLfIePK2yHA+kb6Lkd+L2t5D+wDwLzo555ff525xf0rXVyBJarpJwTEjFW1/NIoSS+MuvpsaSps4JX0SFpEPds7Mj1wGjExWiYQXMAayzx5tI005jguTU3k2yGBvjQ31pHyMWhnsMELyd44VfXFqoR9LhGd89wNmGUVvI7d7JmHEI5y2er0Ho/Q=","layer_level":2},{"id":"23418a2f-b6aa-40be-baaf-d47cf88a827f","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF功能集成","description":"gui-pdf-integration","prompt":"详细描述PDF功能在GUI中的集成方式,涵盖PDF加密、解密、加水印、转Word、转图片、合并等操作。说明basic_input_interface.py中各类输入控件如何与office/api/pdf.py的接口对接,解析参数封装、文件处理流程及异常捕获机制。提供典型使用场景的代码示例,如批量PDF处理任务的提交与状态反馈。指出当前功能边界及可能的扩展方向。","parent_id":"a4bd1c46-ef48-4bbc-80c4-8708947bde3f","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/basic_input_interface.py,office/api/pdf.py","gmt_create":"2025-11-26T20:52:54.8028023+08:00","gmt_modified":"2025-11-26T21:39:40.6772164+08:00","raw_data":"WikiEncrypted:U3q6a3ULTMgMFJU+klBM1F5CUBWKEjxZwPYGVy0Y8YXS5aZQlYopVHmVKTyHiPNIiyY3g5W4SximZGH1nHZQpmj09NrGq14dDxhPetyjCV6sOBdn7Sk3dIhRV/k2PcaVv+03Y+dv++1Mf5Tc+a/Kfz2xY9kWggmuhDQh3K3/5Po4u/Nm14pHkFBLkTXdzbuiXXA6Zs6RrreD60qzg0Kl7flAb96OPLox2ke4t+CP1dvZ/cJHmPPILHBh9x2mN51BwUnb1zCwqUgStz9brAhE3rg+9sgSo059XTpt8rLO26kVb9wBXKfgqCDPHfZxTrj8klfEdJZXUDktyUQo+/E5Qy7Cq3WLDSoqjm9uc+5J8WrSjsfI5bmXHWyLsm03S4bW8YiunRfMZUZbHw87i+EdpwO3XzMS2VFYy3yTheogE+1n5gnIoC5INYeNIr70WQCYwoYMfzbO/WLrIRfFddwgM6UV8bIQn62oGXXDvyta0njRKXsniTQHx/T5Q7h1bTRxfxXfiJdwcfm1M8x57y2Q25yphfhID3b/T3U+QxN9r60dxWox+hKawnvJO82tbBUKOIUyt6PjsFufmgy8u5Wp3jlp0UumCYUubWY04wy+mJh7pwlA3tRUsNxf2r4uU154GZAQFvgMme7UDkdFSH2+NNUrcdZahCz5TtiMvod0cTUwC/K9kCuUF+Hlg81s0shBTHKglLH5+UG0PeyZERHusQdyhBjAm3bDwZx7YVb0UtLqEXBdMeXLKygNzJbMIf8UIprAFlNjY9UwZC0baIMv4JEXbBeZkxNSULlqJyfvbQICK0WU+WOynhgNFlk7GzIpskyQhSB0YEN6wPaZKWLbX/LVKtK9rjo4cmkCqdVXyAhWHkTFMdirPPMrxLQ4KCZGhYooo68Y2pWvcPhEk1/S2F4F5ALRy5SkWy/vvob4l7h0cLlItIiQuIsod0LqgTQN833fxEblF8mKnMlr72wv9tB0BKiALQmQRung/XZsA/99fJL76KrkpDO6Mazgt+tv","layer_level":3},{"id":"1ce34ed0-d01f-48ed-b4ce-8328bad18fbf","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"OCR识别功能集成","description":"gui-ocr-integration","prompt":"深入解析GUI界面与OCR识别功能的集成技术细节。说明如何在GUI中构建表单以收集VatInvoiceOCR2Excel函数所需的参数,如发票图片路径、输出位置、API密钥等。描述text_interface.py中的输入组件如何将用户输入传递给office/api/ocr.py中的OCR接口,并处理可能的认证错误或识别失败。提供一个完整的集成示例,展示用户上传增值税发票图片后,系统自动调用百度OCR API并将结构化数据导出到Excel的全过程。","parent_id":"c8b75962-2412-4786-a59b-a3d2969e09c0","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/text_interface.py,office/api/ocr.py","gmt_create":"2025-11-26T20:53:07.1596805+08:00","gmt_modified":"2025-11-26T21:40:41.6554052+08:00","raw_data":"WikiEncrypted:qNsUVmxF7ewj155OW5SbVz5VRTToOx2fPwozMSy+j/JVWMYSNhnlsPxfsP7ulk5QkedjN9TYCC+azJTJ1kfPE3AkjV4yI0hETeVVNR3UtsUtyNQPJegzcMW1OVJwVAxd/fbp79q2/y1ajgpcLzy99l2pkinqC6f+CZF7NnKibbF+WTuBgXOOZTlza6Q7hpLrEX4pra29LGAcdwSHFszUU6oDYf9M7WSyNZn3jYcarU1Cc2P9mVYuE70l+i3P9Oy1Yi4TkxAjQtGgH7afSAd1wdJF2/mkyFPFIfCo2DfaO0Tv3of1befJXxbmjjFT5YM1UfewgPDy84LTrtxAauHrSwl+8z1INqlprN6tZYDu1u6XY09INkUgNcD0s5zRKVpYHitsbGKvgAQHQzl2NmdSOFP3odd4kC40NEUAK+CCQWCcUsnqz2+FwfZGRMfSsxNU9A7LVt6JxV6uqPokFXLUrl3jHON5D29gq1cLG+8jrWX1bjyIH97G/2Fefc+Hf4Z2tRqvgT42+Jg3R7YOs5cVfNPeZeR9mMxarrPu3zWJMCIwA2ALR7QEld9YUWZ7RRrnWG+gzglgswSjfJ0JY4/+61/m6AdX0qrt/eMhXm5UsSWX7dQJgGoqVzgvIG/t0wl7dkED4c28R9x7PjRfL2azL2TDTmHPGxRKDVEKvkkMtBtTIv87sZ/bPOVgyVXvZqsrJ8ELH5qzfFuW+4vGcyishj6sqZvZ5sEtZ04TTcDyb4VI0JKIn6b/WwCQdONUHyArKUtm4kQ/ENDgD3sB75xrfDiLAnkjtRpXuNi+NHByYFGDvgcUZ1L2NgZD2Y/vKS0mTyczAvRwYAQVFOyq1Cg0Rbz803qaAuQIpwcFdRTCFfijLIjqnZDfb9/06vCHmByYJ1sL9oUDT/OFLtRVvIRRsGHOPTXoac6zR5cLlcFm2JqyHnLFYNfPTkax96GWxig+mvlis3hwdXoy+EgbsSMIgpAUCYjHGm45890bxfmLf6bYPm7EWDa73Sa3xjjIUHJ/cj7u2Cn/x+MVA4hAh9r/jyEgLkB1aO3v/zS4DoCNBMkvHsMsAbzxlwQxOy54+rxh+ACDAxmJULuFbBbQgfLKG2hhZ1DyyvIvTX917AScXRcEf6jk2Rlv4fheJy/+X+paRFjKSHaRL61gc9KzOMqYUyBIudG72bSNsYULBJD1HXM=","layer_level":3},{"id":"d02be4f7-6a6b-469d-b867-25eca75059de","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Markdown处理功能集成","description":"gui-markdown-tools","prompt":"深入解析GUI界面与office/api/markdown.py中excel2markdown功能的集成方式。说明用户通过图形界面选择Excel文件后,系统如何调用后端API完成转换,并利用status_info_interface.py中的状态提示组件(如进度提示、成功通知)向用户反馈转换过程。提供完整的数据流图示,展示文件路径传递、转换执行与结果提示的交互逻辑,并讨论文件路径合法性校验和转换失败时的错误恢复机制。","parent_id":"ca6067ef-5206-4e99-9e65-628a084a2c9b","order":2,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/status_info_interface.py,office/api/markdown.py","gmt_create":"2025-11-26T20:53:11.3273577+08:00","gmt_modified":"2025-11-26T21:41:22.76928+08:00","raw_data":"WikiEncrypted:eNoLuopvj4dwuFHZZacGfFzqXqDMgPmd64EG0w7COnDzB0Wddma324bCX8JHKdJxP7JJn3kUjU3yqR8D52XvqHXwEFDZN252M0xD/1j1cgRzDdMEvuRbIO40cYbZw85f1lxZWhb805X1d/Dn4D24oQwxmSM7SmFI0XHK0EpfnrlkN8zt0gmsKskWO2reVLKq/E4vPWzEjHpoOfmjGL/63uhsPsEiw15PDMecapN75EPmb9xSOiDNEJoES6kuI6sSgtq7hsCH7O8cZqtD0m6qWxRZMJHsdpXJvSC3nXcGCl6DKbZN7iUdB3Ocvle31uMIOiYJgDRzaYtfXPscI8/WgnQ7A4adms+1rgcidLiK/xLivoatTy+m5NCb+fBkxsQWGSCrSWt3Ti1jo5n48TB3SG3w+DMQBCu2aAdncAH1dBiWIy/oCjiW1kNlk5MepEviNffL4c52jsI4xrjoZSSyIfVBzMA/HtTM5efZf2/H14swaeEbHhd0rTlOhV1Kf3u21trQ3Ey4ahNGbqF4ecG3ueWu0vi6xhB9DvM4dO9P95aStmqKmL12eVN8SF8zvwkV/ncXOwx5u6Fu5IbUnX5tVK+CZHnduA21ivz+ur4SVBl6eRmahn/Eec1GJZyps/BbtlkZuqhymrSPjqTuRX5IeGNtYIzTWLcZalP0TZo3Yb3QnUEiju7hfanqVkIGBL2DTfFsDB2VmL8ibsSsYlra0QQ/XGGmHUexnDsbc7Uj86VqKeHZ5pUofWOO0alGaC5vzeCEIVtJPOYhPZwOnRYh0s6z+m6U3W1ObgXWvZ5wi5qupO72ZGMDmlO/SW/pyRkljc0jpVCsegpX70ksGrT306e0n2GDDBXGUg5y5en9tYk7zGXk0cer+OdpZv/X3j//LifDwL8uqv4tV2T+n1GmFw5FcesUfqpGhr/vlp9c2I5Nw5uPfFLCsHYAaqDklj43HHL7HNlgms9VamDjDUFoulrDcvPuJUYYw/lizzNBMoxpxEZkm//O8gjY2FNySwARkB3P2qjL+CKoE/JfG+S6icUDMkp01UWIQ2VTygalM88KedxUkSoQJ7m225S1dD4L","layer_level":3},{"id":"a31786aa-e457-493f-b2c7-a9e14fc864e5","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"关键词自动回复","description":"wechat-keyword-response","prompt":"全面讲解chat_by_keywords函数的事件监听机制与匹配逻辑,说明keywords参数如何定义触发词列表及其模糊匹配规则。结合'根据关键词回复.py'示例,构建一个完整的自动客服响应系统,展示关键词-回复内容映射的实现方式。分析该功能在后台持续监听消息时的资源消耗情况,并提供性能优化建议。指导用户处理中文编码、特殊符号干扰等问题,确保关键词匹配准确率。","parent_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","order":2,"progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/003-根据关键词回复.py","gmt_create":"2025-11-26T20:53:29.3883993+08:00","gmt_modified":"2025-11-26T21:41:37.7934525+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tF/7ghvsXxkJwdNnPKWghHA122yLg1jbxeL5+Gh6r5DxQFEZYd32MIkxtxbJjCRi+1j28xdImLVEM30ulYSqP7jpNMcusHUJvJH68du7EDt0GZJHMg/BWBjlForYsSq99q8Lngb91Lw0jS4G93T9NIQXiU2uMwvHZYKKNXn5wm53eCxopsYEJkbz3gyXRmgGbQ5v6vzYRRVa0IET0pXSV8JLtcnROU0aCHFWYqb2CR9TgYjQ95vJgB2s44eoC0akCGSi+vJ3Qu0AMiKwXFRnuUDxkfFIMelZt20MZTKQivZtqeiPfEpIAKnVk/CZUUkoq1Dr+SLynfU3iU2noNhvRLZ+rUcej9gV/BXx3B2FdFjHJ+fqSC288EF0pOUIV0x90QN356Ot6pNeBaQW9mpIuMnCrowLmMkR66VE4EllZ98GY0UNT0YT7ITlCf5dPXWmWTJ7B0AQdDoOJ8PoMR1TMyEFzxxFcmCC4wvZih/O90wduOQc+mT/bqQMS3HT7vnEswCB/Pjpj4ZrUv/P7rl7dXrLfiE9wFawo3h04zQZCPjhzV25qSYBcCaFmekTTCA1AdPMKVmi3dD6DppD/kpCo1fIR9uM4TgzRvs7yGDMHASRdATGihw4x2P2+3DI7Y/FKi5XVsESwJ5Gu7NuNnEdf4EFb5gS7WEmNWxfzlDnFSlNPce/0cjH9DVqLZImAjulNvaiZ3hBftN9uRyrZ2lIvJ9Hlij2VZTuiPiCVATH57iX3yMRLsQBrfvtfg0OrqeLkGGMvSq4Okr7NdTYI5E2stv/DZcyhUX98SdAlWq6Oa0mv9h5Ru/kaNlynfR4PMueOnQq9J2cWcDdsqkjhkMbeDDvt7cBDbmQuhKBtTodZr2oIhkrRp77mY+EJKf0EXGtdxf3BZ54hThT83PhScLEb+coOaPm9J41pk58wu+K3C2q/rRmeBFLBjyN1fBPK86UduB//kGyHWTdeA228eA12RaDvdOYjhy5KNwVn641D9iuIAYPSLSxX6CftTmoqMnKk4qycHEOXkhDqZtEk7Mzq45M5bHjALO+y/E4miUAWi+x","layer_level":3},{"id":"2fbb3686-4ee9-4dae-a206-e2e93050fefa","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"群组与好友管理","description":"group-friend-management","prompt":"全面介绍群组与好友管理相关功能的使用方法与现状。详细说明批量加好友(add)功能的实现流程,包括消息模板配置和备注映射字典num_notes的格式要求,同时明确指出当前因微信客户端控件变更导致的兼容性BUG。描述收集群消息(get_group_list)功能的目的与预期输出,分析其存在的AttributeError异常原因,即无法获取群聊对象名称的问题。提供临时解决方案建议,如降级使用旧版客户端或等待API更新。探讨此类功能在社群运营与用户增长中的潜在价值,并提醒用户注意自动化操作的合规性风险。","parent_id":"0d3591e6-05eb-4c99-8c4b-77afedac49ea","order":2,"progress_status":"completed","dependent_files":"examples/PyOfficeRobot/007-收集群消息.py,examples/PyOfficeRobot/009-批量加好友.py","gmt_create":"2025-11-26T20:53:36.3500974+08:00","gmt_modified":"2025-11-26T21:41:37.6665884+08:00","raw_data":"WikiEncrypted:pTu6Knkuke/rqoFxxeyoVHD9KxQdLM+NEmVjBRp3bzVUZ5yvfe9z0oas2pY9JGRrpUwtkbfyJr6DBDN5MmPBetprVjLRKod76tViNjnL7KnRrYOuTK8dbQ3r0ufjgy59TtT18CV9G6lc/jlPO9umIUYHc1HI9TM58ni+3wdZpJQMGOdFvasON42qdsi9F+gJLU9lpuHlzIHLKQDDcwzdsdwltiveIm/nVlW3bPy/Wu35nfqucCPn2MebN3puvlzxQ1yeP7PjWGL8YCL5AiPaKgL6+MmuH8Wy3XwBBeKg55tkn716JZ+GnNjMdgo2+ZofjSxurk8j+MDEmCNESD3TSr8JETyAQ62TKEUSkq/sc6gjQRipbnxVjw3u3LnYh8nU8ghsEloPq2fVHnf8jQk/5nrv3EB0H8qH1oHJsjmqDjSMLdblklQluiWMdIG0Z4Zlm75SHh5VsUXABGZ3gvMfi3vM2lXWIg6FhvOuDdKcRWXXjN3KgYTGTQnDFbKRKHgoTF8W8XGIH2ZYjzamf5eJThGSnMW2qChv31FCjE2hAHBxA7whBh8fpwDycsfdvcfZfIW3Vf7uu07VZSo8jl5V1JmNPw7Enu23WO7rPRXqOZLnBlR048kQcASBRazbQLQyTjUOMy2Lfmcg7WkyZ4ISdq4UobTCnQlHqliN1EISXbXBjMvrEPXYsAmlv05b8kdA5Odiq61J41LqUGPPrjBG4aIi7SOGuWyIo1Woyd/nesJ28OtouPeOeGoOGcHW222H4YZyPlepo+y2CuNXlI03PnsbGs2aVgA1QcjerGOvfpQbzVHZh8WlxWoRYViTKL7KdBcLhh0S+Q4dzvtdXUUYuS9CcCFXl9gLLu+jVBXAdV0lGoigsLOWZMe5WmRbitXLF9XdCtpCIlF0eu8cc0/WvS2InlWLpim+XKPlUh6ks5K5XxqhDei97jKSLF+2c6lUP/imZy72kIjeg39wmvlK+AVvsgThhWY+20rqWRxIEZ4e4FMY8xr2tJqJvXJ8RHLkng3ha9LRO65XcjxQehfu2R+qHgbmn9kerx/SgcMcVFsZ49oaM3ieMpuddGqJR1mZbKb1fNY8Y8tlUcEuL8PHgUVfoDZ3uIrfSsMrw7PlJ4CsUJmnCQKLzJ9ZmuQzqq1IojKfPg6uAoyKyXN850HuYuKbYDMKtdbbno5aDcSw7WfN3cWrGL4bMzTIVA+aFpU8EcaSG1sFjFV1qrmClsbYB/assGRucqcaCyDuSy1UBSdrDC8YI8SSOBEMa5hQ+K6PXyw6YbcDE3BL7MZQGOF+OMLmypr0q3/P0XxICADBYKNDtmhKZp+7QeqjVGkztftFCHoBGwlnei2Lirs3E1myKufarZ0PlsrjtrybQmvbfYI6iV2QFSChd9bPof0xe7cAXVIyxmGa8oC4b/YuijKUXg==","layer_level":3},{"id":"a27305ea-b9f9-465c-9837-0a0f78f91e95","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF转图片","description":"pdf-to-images","prompt":"全面介绍`office.pdf.pdf2imgs`接口将PDF页面转换为图像文件的能力。详细说明`input_file`、`output_path`和`merge`三个参数的功能,特别是`merge=False`时每页生成独立图片,`merge=True`时合并为单张长图的使用场景。阐述图像分辨率设置、格式选择(如JPG/PNG)、色彩模式等关键配置项。结合`pdf2image`库的底层实现,解释Windows与Linux/macOS平台对Poppler依赖的不同处理方式。提供批量转换性能调优建议,包括内存缓冲区管理、临时文件清理和并发处理限制。","parent_id":"be0c69a6-6c67-4442-958b-7c6fb66891ca","order":2,"progress_status":"completed","dependent_files":"examples/popdf/pdf转图片.py,office/api/pdf.py,contributors/old_from_gitee/bob-zhao/pdf2imgs.py","gmt_create":"2025-11-26T20:53:55.8777344+08:00","gmt_modified":"2025-11-26T21:42:34.709096+08:00","raw_data":"WikiEncrypted:Pydghlf5Vo0qa17BK+8s87A1FYKiALDxE9tKIXfSfg6y5a21XQjsp2yZvyLxddkyAzaNXUP4HcMI2CroBDMPQiscG3ypfmYKmqBDwRlDP3z5l046qJN0REl+pBstN1XdimMGFNsJ6oS9ZhQwV+cuvWaAaxqTavHa6IwGe6eWT0zokXSOsukkGdaPLPv+hOeK3PeW1zoc7szndKmLFKG/+tYke7CgHRpCW098oPE8jANYefwqtOh7fau5qtW5FnH5A9XRS3rgQDy7uMFgFHqNnvVm4mQH8lJs6WKisFGR0scL+MrvaYQQLdvqELJY2HBssax9ztzEvwGXMljCPHKt8Met39vLnlRNONPXeexPCwMwt4R1sGgzb4rnqQmLIBkpoGdG+freuS5iOrqbxcVV1cQIoOcypM1KmU3hsVf58TT7HaUAkLg+/sRb4J/YLXt6LQOsVkMOFfRqToWEkdotwpTulXsD3rbEbUi+tevDamuvLg9au+GkSZf72/+TBA37hCq/ckDGfT/tvWeWeT7bS9itytjExHObhT231o65tueQCZhn0+Vkj5jRGZkKILYUTmqZkFd3ILt+ckSnflUdBR4lt299bnxTZfmQGUCawPrzNxAoyiLGpHKtE3uR9C98mWsULHNmNKcCEgZNpbw2Y3NsKFIkeZ2prV1P4AZfoD9T4H8mMvAvUY/2TLPhS9nl5U06GQJRGLdkzZahWdZ0gzRxhAgFEFlMuMRpSUgb3aXtnpFS/n4NSfxFFDZRVGTrXwl2yUasupo/Z2sMX1fPbuuXpn0FzaIb8cCE8bbgilC9VABWI484cDCpJtHP3OtXU9v9N9PqPXuOQg6L6tQbIssbIToVI0cyzSyuUTXjA7dWzsvV2OVSECx2nfXBt2wWxC5Bd1vLfTLgj7ZHiwXtEIyxj66uNL5Ny2dotflLk+u4gyVx1POSMUe5YBnO3F60RDhitfEjcrnzFNWKkKv2sNdzGSzyIjTUWqCcBI6N8lyvRYefFrYZpVZ1zLvIcchpWv/uESb0h9+ZMSzYyWDlOhFgriDZeJs86tI2lsgjW+N53OPe8dR+saLGQNuVnL5Is1Uv2avNmbHqDtyFF60Ab42Rn7FP6nu+P0dfyKUxlUIMIB4eB2DFjvQdQMENxZk1xrViTaQYTWBfMlBYcu3K3IJVtiIeOPYyUqH5A7EOSDDD0RZ9IffpxfSzCXJrDJL5","layer_level":3},{"id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"核心功能","description":"core-features","prompt":"构建核心功能的综合性文档,系统性地介绍python-office提供的所有主要办公自动化能力。根据代码库结构,将功能划分为逻辑模块:文档处理(Excel、Word、PDF、PPT)、文件管理、自动化通信(邮件、微信)、智能识别(OCR)、多媒体处理、AI集成等。对于每个功能类别,概述其解决的问题场景,并引用examples/中的具体脚本作为应用实例(如poexcel/中的Excel操作、popdf/中的PDF处理)。解释这些功能如何通过office.api下的相应Python模块(如excel.py、pdf.py、wechat.py)实现。阐述模块化设计理念,允许用户按需导入特定功能。内容需平衡广度与深度,为每个功能提供足够的上下文,使其成为用户探索具体API的导航地图。","order":3,"progress_status":"completed","dependent_files":"office/api/,examples/","gmt_create":"2025-11-26T20:50:26.667149+08:00","gmt_modified":"2025-11-26T20:56:29.7257271+08:00","raw_data":"WikiEncrypted:luoNp8LvFa7zGThvIT9T4gfD6KbzJyTAydbcRfVv0b4BXBAF9G/unmbHb0x4cm5f5JJeO16NqGe5C5EiggSB7sQb4G3hJATxiTWhFFgKpQo09N/ZeVbwi37wdbTN9wbIHG3UBywVsYF6TuuO6MFryrphGVQXngpBa1jY4amUseHI+hXIph/pgUtHgFW59uuSICLZj1tE+nNY5mswDM9URr9gkdDD3GAnNmOmi3ictetGPlB+RCWCx6veXXNvMuW2PRjhLNkcX9dDxDysq/Bi5BZKZGJOS+mq1wXhmciRHsgUMRHqOf1ErPRqZcHyfYSfhNmj76cfCGGYXi0MQqcDTFa/OE2lS2preFLGleJO8eknWk1HtAOUtmuEr/9/kOYHArV3jCbRrdoM8NBR9ul0gnpCPQJWib+qlZ807sFcDrR1Jplc1DIpK17dv5HqRvNxzAHcR6Xx35e0KlGnXu4tkPgNP9Af2110NVBt49CBrd0tMOIQAnTg6KjqQdEBpMXF+i8lJX42VaOEeIuZ4+xHiWmbTWLMepHeOmWJaooqDJhInnNpT/G+aBji+0RWLBih6xCucHJgEyzAFiWddakRKno0VSd6nY7up7xNlRXXk774cR2xmId1qaFzELReo877ODfItTmqZvExq9QuPn+/U78aegh38Jq4E/X9eZ1jDRAHC/zEAuI8uX0aJWTbQPZabZ6Vg3XzC75mSlQxGbLAToiuAuR5rj3f/8Of3YzXc4aOZbWmfamgEw7g3a8SuSSzf9i3Llx2eGOnYNAQf3MJZ4WgLIygsBaWgsyK0cFSCq6Eq6tPwIwYrcRrr9I8rWJEX5j6PPb97yILw5BV2LqlVZ0CjdjQSJBkzo3AwRIO5y5OYk5Fbh2z5XAr8EE5CVfuC2/jGN0mzO1AMchrwrP6jtuqQPo04PUB+t/pX5Fzaycw3xzuiDE56DNAb02QOMMa9yMlknMcnvcAL7z9PEIrRTTmLnBWyDQUic54qiJDtIdmIP0LwwGCPf6tPLjBQh4OiK/IVapoa6kMVYwgVa6otOdKmSJa305WFNJgv5+h1uMSCiC2tzI9CurpXVUDX1xUni41YS6/gIavALAkCj32jDgpO1nOvXcixln6ay7Zy1hnkaZz/Lppg3hCysXZSCMhGrW53KJjKTBKCcM2cWPSyBOTvBiavpPNBsE/CVNfmR9zUdL935XGaxktjfZ6XovprMUoM1chI2AXpugqhBJjShbsjRRiAC4XJ9O3/KyTrYvzBbsW/AFAMXnRy426EkuhAXkFVfTOZim9MMczhOPnaBKl5E3dKjr8SGiyGIMKBXCIwAOMCYh2k3ULjS6vs2VKTbQmI7GnPfRvAjEoPxCcNRzeuEez1oRueKK9S5VYwlJh08aPKw2z+PW3A95NlTS2i64hy1pTHHX2O0s5NStRaMun0Ro5119GeE2Qgr8EAjpAErSa8am2YocmX1+0Gw96MR3qRfsrJ8NehHI1d9rGIFAmBwiL5bn6MGdyZmZE1GREgKYawUR+fKzakcNhqamq+mFkK+n8zT768B0l0XnfNmQu2ZblyXNmb/FDBalGhUlhyD1LE3m3GDfLb1XiLgFk"},{"id":"e2f3c078-2962-4624-ac55-a7ae4ab1ba48","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"功能映射与集成","description":"gui-feature-mapping","prompt":"阐述GUI界面功能与python-office核心API的映射关系。分析home_interface.py等界面模块如何调用office/api/下的具体功能(如email.py、excel.py),说明参数传递、异步执行和结果反馈的实现机制。列举当前GUI已封装的功能范围(如文档转换、文件处理、邮件发送等),并指出尚未支持的功能模块。提供扩展新功能的开发指南,包括界面注册、API绑定和错误处理的最佳实践。","parent_id":"bf12cfdb-30f2-4b0d-bc87-c1bd097570ef","order":3,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/home_interface.py,gui/qtpy/version2/gallery/app/view/gallery_interface.py,office/api/","gmt_create":"2025-11-26T20:50:50.3267134+08:00","gmt_modified":"2025-11-26T21:04:23.2581723+08:00","raw_data":"WikiEncrypted:QkX9FMSq/8cD6wyJ/opWIxhoN6UxkMcIxumjD/78wXnHxyxyC6hkN4JvivUe1+vrsaAh7vrLVF305zX1B9CvmybVVoHqSJ6bS1zQoD8Z7g/UyTG2A32RN0hsyTxiZJ5t0RPq+AGuG0eKgGoLmtQB7MVky4yjWfipA8IhldnAuPRV3pqBEGaZ0OrTQ/bon2/gidXHraDAEpOD7WInno1AVyamLCYjfqftgfPgsm03u+ePFTIaj9Y1o3vrfiRcC78zVGICOvJ9UU6zXka0sAewgf8osjcOgNOAoWkDRB74zuEZ+UrnHxC1wRhqlMhaGnZd0C6HcdIVCwdvAtBDPjZBXH0ZAS3MVq9aURsOrv1RtnmESh+zGTUL16QsrQ/Fc9KsBitccnMOLAZhLP+B4x7rk1hOHLkur/ejPeEFfyhL0QEYUXBPcAjBKIafhk7tOhFMHRxiyiLhTi6JyWayRQ9WY59MwUbXQJEBrdpjL8O542MgXNz0vwvVEJXDHQ1+N3cG5BfKRxUqepCJhiaZs/ioDT6OrVUtExAzY8XfDgXTAzUgs0W9WGqWVKF8bW74g4KvUX2t5W4SRuZIRZJZkMfvQzmGQ4LXOREQ4cLqo792QGhkDAU/F6YnImIxg0zEoezmWw/1UPKAYv+KH8zbdsB6aANH9qCe63Suy6sWTu4K7OwgbiSRU3MXWpjWS7zhGhh2tAlbUQgQQsXbAL5cEoaHlXkkklLocy2B4ZmCwSAxBxcY5c7mJsS6JoFAvU7HbJ01NXqKB/vBVyRUyP1TRu/NLT8Na/ppHB51olok1/KQRyt6mYS9/7WNoN0w359VdDL5/2t39LWNQmdAEvGOmoPc8+pHXm2hrN2akr/nivKgSdRvEjkcH/gt3FSrN3suZarzRPOoFbfNIKE0Zx6LyZj8kFZ0Kk0nJStshE1WloEWROQk3uTtUkfnyjkSSiujNZ1zrA5PiV6yc4vQ9K3MaFwO5Qg5d537h+/CiW072jVzcC0k1xFx8lMiONKLSGzHq6LxbrBfzHX3SmX+Pp2HjW2Huq2ZFV15KZICLS8Zr89ZWgVv+0CCfN4LDGwVpAJr/niS19Qrz7yqd2M4pcN9sd/XLnsKO42J2WPqn+DkpAvMcmF+GOMq50dZfs49R015vSCeUO8fJASc0gWNbTLf+2VUUZtoIFjMfMVkwJSOEmK8gKs=","layer_level":1},{"id":"a025ee06-1178-42c6-ab66-3f654ebd24af","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"智能识别","description":"intelligent-recognition","prompt":"撰写智能识别功能的技术文档,重点介绍OCR文字识别能力及其相关预处理支持。详细说明ocr.py中通用文字识别和银行卡识别API的调用方式、认证配置及响应数据结构,结合poocr/下的识别银行卡.py和通用文字识别.py示例进行演示。阐述图像预处理的重要性,介绍eliminate_background.py在提升识别准确率方面的辅助作用。包含识别精度优化技巧、错误码解释、服务限流处理等内容,帮助开发者构建稳定可靠的识别流程。","parent_id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","order":3,"progress_status":"completed","dependent_files":"office/api/ocr.py,examples/poocr/,office/lib/image/eliminate_background.py","gmt_create":"2025-11-26T20:50:56.4194556+08:00","gmt_modified":"2025-11-26T21:04:54.2873853+08:00","raw_data":"WikiEncrypted:BdEqeBTeftqMtxtP0JJ8wgaHIKuuLYKIApHNhFXq2o9H9RbSCm4vgqN3jG+gEhIiM8JusPYFCpwj367+K2b/PH/3NKWX91iPMMYnl4JQNgYM3K7rCCKZpdnp5Y6hkSdM4K6JnPI8pmtPSEZFI0he3yueGyuQDO1muWYbM1ZPL/WFKRS6Zl17uxpksNAhIETiuzLobYuR19EL3T2SLyKOtJLGD1iCFstLjrX2XDzx9Gp2DrfzLx1lRpFusaGqCRnNyCocgFeZRwZV+9s2xCaj3Z+Kfj0J8sur1ebhS0yVjAW8gNOIgLHxsWr3Qff9OpxqEM0YvIcpypQuHPQmraVN4zmAk9CLQ9IkE1uv8IwKFlwUsZ25w/pK4h/88US/A951pOJvDfHPq7I7EjiWrtoSzPkVKtGp61GW+HHzGhXi5k7ZD0k4RZpgEilqxMGACu87SotX5ORYA+o6hVvNxmb7j1pIce64+hiPxkorYhNfz1jBbal5/fB6ITAG/K5cpZgs24eqGiFSiwNfthOqOqU9+sWIqmIrKhJ9upq0XNqImsUruDeIzwadtUEXdznd3FbIZgxnJRsWeUWUGzGQQA5qeMtAuYj2DznTVozWEzQ4b3eGkujhnJTReDj0E4uWHkv2bztlTepF9qvLfGOKEdKmwGXAaVSV9XHCly4bTA5ATeCcl0YleCPias8YlOTZk/SqDlnr7I+bsqHMSEC390BnVlowi6x0HdRwg9yM7iHJY3wAvMkXXDNmV/ISIBdJI6FHo/1Dn2LGdbNwrX+c8r58o5Kyv0unAdwlbG91KoGEQpqkySBBFl4m2IRQE/RSVYzxzMdW7XU0SLiBR4y/R5X1dOMj1ImyI21Sif9NVSau6IquZCtNFntlE7unIVsDZha6Fno9+4x1pNuTkAh0QOaSvNfZMtXeAVa7mXPvuBQAIVKgQfZeT05hxY+dlAqLI/ftsto51FpxTGAIzYxDD9B2rT5NPfp+PrdXlT1lnzG/wFN/z7LTrSmfnECJ9zswa48gu+aeS5E8VAkZMhMhuUF6GWH/JSRDOSOuOJwo09CusZjARyg+qyGo6bSyByQbK92VUaFfU2uOY0430AFV9u8F7rtpFgAW4Dq41xcvrIhg+YJK5I3rn9EEgBtj7eye8OgCoClyi29fHfTyGhgP7QLTtYHFeKGwDj608Lw/YP1ki4Y19nfClrvSOjh+X+Smb142VxHsgHboaf6KYfdC9wmjsawZKQ91R65JtEqiPvJCwnHnRDxpKC+bHGJD22V0nkRAIrSeMKWXAfWwV6mYgkm3OQ==","layer_level":1},{"id":"290a21fb-37e8-4dec-a611-cefcb38f4e22","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"金融工具API","description":"api-reference-finance","prompt":"创建金融工具API文档,详细说明office.api.finance模块的功能。重点介绍do_t(做T交易)等函数的接口,解释其参数(如stock_code、current_price、hold_cost、hold_amount)和业务逻辑。提供模拟股票交易策略的调用示例。由于金融功能可能较为专业,需清晰阐述每个参数的金融含义和使用场景。如果模块包含更多量化或财务计算函数,也应一并记录。说明该API如何通过`office/__init__.py`被引入,形成`office.finance`的访问路径,并注意其功能的实用性和局限性。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":3,"progress_status":"completed","dependent_files":"office/api/finance.py","gmt_create":"2025-11-26T20:51:18.1849227+08:00","gmt_modified":"2025-11-26T21:05:22.1046299+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg5yYJVRnFYNolh0pA1jf0Bslfpq06UEIkl6tPRpoZBuu2EFzXCIQJ0MG4Bd/g2LtmYRu9yAW1M6QBmLQPp8DblwwyiPbfUeGqhcUAyrwA7PSiyL0KDhyRrsKpm4ZfTSs581nzJy5APwLVvLqJCtskuZiEDXmtPeFDuSTiABnQt0K0FgYFfPL9q9BU0hs8fjvBuXy31RK1wUw1xfKr378WJknE/maIjm7lYSZegNVpkf3AW8OxkFXoFEje8lXIcNYsYgVhNe4ocTXOTGhYsxc4mOlFLC2XMMJIFtqZPgPIY2CtPsIk3ipQ/LND0cpLbENUOSDA4JNejdy1u2yT2IQbakt28yEnapKPfvoNQTNYiy4Kt5J9cPiYX5jb52DbzGeI0vxRLlfaKfmfwWnCjdDiFVh+g1kqozDEbiYtHafg65viSlLZM+KVXB6Lei4agaSdnkliS8THMNovmPsOEJlCv0pAkjGbRebYFTU+N6vBNGt6b9Xf787njTjDYcURsaasB+iP2SB1gltr7wGlQeFGnSwbKNtD2wZcXzIPW1Wo4duyq8nhPQwkW51wEqwQG/aaol1FbUZtr4U37Tw1sXv56x9yQHICc4aYrWnoWiK9IXaQTB3aUbuH4zSA4MAGHkecxK/zFrzjEWge+kHhVngwh6/3NDIiRg4PjqPZFJrQIbvYlWtCNg5q/viZjOYjbF19D+T42eSG8wKlVP6/q1oRDrPY5jWAMY6SouDxA33yq68egAK3kzfoY0KKp9bh+YJnKppLu5XY744npRLVSBAZo6dMOZntMqtx76wB2105P1ZV7nIb1wiCAfaxpfYj6lAnEHopq34JICCleceOf7Cs9pd6n4LxVd8x1BW3Rp7IxjJ4sbyvaGNHYna2I/SYZerI0NRYFR4w3nV0Ccyz3utEf1IGXXkwSPSTV8Zn0Zli8ZCXq2SF29844ylNGiPjxNV+UWSaItnC1a+Lh4D3zeEq0eo+ZG+SWixBS5AtDW8axuoSv+VHKjJzddcgbV9lOYF39htjasGCaNO3+MHv1MY0ZWSUje+N2JaY6yRtl5nbztUxvDnQVPdiBgkT1Mj+SqBE2DqG0T+1OJzM/knrBYnRWICA/1qodHyAE/NWQwm5w+M","layer_level":1},{"id":"f058e3f9-1f62-4a61-b147-f6a1d7e86abf","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文件管理示例","description":"file-management-examples","prompt":"详细阐述文件系统自动化示例,包括批量重命名、按内容搜索、文件分类整理、目录结构创建等实用功能。解释如何使用os、glob、pathlib等模块高效遍历和操作文件系统。提供正则表达式在文件名匹配中的应用示例,并展示‘自动整理文件夹’中基于文件类型或日期的智能归类逻辑。包含处理权限错误、路径过长等系统级异常的健壮性设计。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","order":3,"progress_status":"completed","dependent_files":"examples/pofile/批量获取文件列表.py,examples/pofile/批量重命名.py,examples/pofile/新建文件夹.py,examples/pofile/根据内容,查找文件.py,examples/pofile/检查后缀名.py,examples/pofile/自动整理文件夹.py","gmt_create":"2025-11-26T20:51:26.2352755+08:00","gmt_modified":"2025-11-26T21:05:36.9178111+08:00","raw_data":"WikiEncrypted:PS6QJlpgHxZyZMwNYt1TRMZuESTC+Dcl81Zgm0o949nDLDT8oa8SgDr2/os2rvGFpmM16CVNXdyJn7bVovWW2IOpqRn/qr/KSak1zA65MANLRwqxYHycEqtkVtRogNif6kFlbxocYOlt2aFWHriXJL+3CVLKvBtNUukkmL+8r1FfTCcPanwQBvgMh9XEwq0QisxenNDPBlI3tisYjVRGmWkZ2FfBLrECzMCPUuxHyNdzy8oxO6Bpo/M5zMlrCd0DO2F5IKtDgl7VHZLEX9jGt3Wi6eKVrDWiZjixy4tRb2yFkZjj0Qg+vBKvUL7o5AOYUc4/ppWQlz2WQRAxenQ2SGr481fOjRTYoMVqnbjsImTscq3nfxFrV+kSFDIQQqR3vpCjcg3GnfhpUKafTQye2a+Qhbpfs8ZzAdi+cM+wBCUn9EBWw51Y+9U0Z3Ic5EWG0SEIU3AtG+9ioWdyFngyNbS0eZ7h6qsCiOE37WOtslX378ePxkX1CFmT+mVQ9ipyxu8EbeZnInSzzREsOOTCMa4hxRY87i3FvVU3PoleWCqSar9GSh7ETsuobl6YQphtw/buUSHjUp3frd9fQiUPwUz2abRLOYLPT/vNS4SEMo/vO0LP0B5sZRtByM5ONeU+huANg9L0X2AeSCCWmEE0KtoldKg3ZpEXDgaQ4OHsVkUX3vApSgWTFja25A19TOEeS/nKcLo3GvdNCX8NYQSDBqAce2An2dXtAxHc/wezEu3iCyDA0dpF4yqm3Ycv46Ack4q1tQSXE5vf94J3uCBMEjhbR89AagrEnkve1tuRNHHUHGl1WbWBevk1HU4OIfpG68tebBIDV3p32NksWisBEuYWjldCACCNXk3W5HOwzq1SfGY95gEYZJZWCxhLxbqJI+ammnUF2kUlemFMyCHXz6ueJByLUJw2N60TMrcOztz5nLsVrgRqo0YQoc+X9JmL6rvxSvb7Mdc7D3yFCpNs/v8VU8T7Hk/lDJzcywzH3VWogMxWbGC3G834CbEOFoWCnUTWP16Iid0k7nECN7ay3SCem+9mr8D4wcgsraUnaP7tQOU3PDt9X24oUKtYTJl48IzO8giEMLWU83aRkpxB+wxc3yT16c53ZAdoU8oQ/zV1Ba+6gmjSlU74QWH0axvoqtdLWgJlynA6FjRbbHILPw3vn4AdIzW07ugm5W4tb5gX5xj4smUImMQpVTy+6hfT2Mf7HZvXJcYkD6sXC32B8A==","layer_level":1},{"id":"ca6067ef-5206-4e99-9e65-628a084a2c9b","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"数据工具功能集成","description":"gui-data-tools","prompt":"系统阐述GUI界面与数据工具类功能(财务计算、工具集、Markdown处理)的集成方法。说明status_info_interface.py中状态提示组件如何与office/api/finance.py、tools.py和markdown.py协同工作,包括用户输入处理、计算逻辑执行和结果可视化等环节。提供完整的调用链路示例,并讨论错误处理和用户反馈机制。","parent_id":"e2f3c078-2962-4624-ac55-a7ae4ab1ba48","order":3,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/status_info_interface.py,office/api/finance.py,office/api/tools.py,office/api/markdown.py","gmt_create":"2025-11-26T20:51:43.5378445+08:00","gmt_modified":"2025-11-26T21:27:12.0116837+08:00","raw_data":"WikiEncrypted:3xzJxLqEGblPyN03/TBhKB+GtTN7YxiZ8Fnfyymg0puu53HnLXzpNoL/ceUTwrl4M9Gw+Vf/O1OGjNWR2isTA7i81GTBPSlY9lc7hT6pQqoroF5TNHg7ObvHFndZhA3klen3sBAlNY2WciL5TkXYQQNy3RSNoj2R+1VmzyNZnM5qAE1FGc808fQi7QztAeewC4fhi4j9Jmh7KuR0XX4INBaCBvmv2OKMXkSpDzsrXIQM50axISdZxTx9bUHULhAn3muORPNCYyT0WXBdlL59qD5mz3kXxw7MwM2cwOO5QV8VdWWb6p9L8EB12YepK8H7heXaHs8pXJRz+/1wu9+hchfSGFHI4Cz55XmOF8klA4bgIFtYwo46km0h4X9TmLVE5NQ4xTxOw5fKniFCTW8n057HkJLcVaY9ggU037958sX56lpjpPa/MG0VSmXhcdgTcTXtdEKBiPDuZl8HMsXi6aMJ5wiit/3+2RUkD3dp8AUo1jhrjroyLGmeraKLN/nEU/16xDIimcLvrTOODSdRjQCdbbbFn+XlrPg1b0FRflBPzJsaR/lqxL8V+yZ1eZVua+yMpfkfe4O0aP3HvPNFEsTYfznDqVEQkoFPF4NrX7nnlJuAPiaZpwIIwQs/4zAEiyz6C5B6cy6vbCQZ1QsFvfVewTjuS06qo4Op1hTV7vJ3sLiXAO9CLMOrCLMwHm3S4uMTK7SZBJOObWGiIdUAQh/bB2Ck0JqC5wdmqL19W1Y24GN0XkfK9y46WEjA9RSocCtptK1biRwDlNaFzw7FdcSQ51Php9SOE2woRkym4yh6rGjG4OVZILHxCumOLk5ONQhBYPY5xBHGEFAN3oWTrhlrHzNxRWOL8smyMTuSVu0nfViGQpfvk4GL8Nqj6etpdD5kmwClS4Z6n+Ki3XgTI8W2MKN5XMVGxa+ydH/LWy2eBnlN9P6qZ/haVmd0oJ0Tc3gh359abZ1/5xUpeSFp2EUgAwbsKVWSojeAeO63VsFiOjphn/vgQpSrFltydk2f","layer_level":2},{"id":"1fb1ad18-3015-45d1-81f9-e7ddb59352e8","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PPT处理","description":"ppt-processing","prompt":"深入解析PPT处理模块的实现机制,围绕ppt.py提供的功能,包括PPT与PPTX格式处理、转换为PDF或图片、合并多个演示文稿等操作。结合examples/poppt/中的示例代码,展示office.ppt.merge、office.ppt.to_pdf、office.ppt.to_image等接口的实际应用。说明转换过程中可能遇到的布局偏移、字体兼容性等问题及其缓解策略。提供调用参数说明(如分辨率设置、输出格式选择)和异常处理建议。文档需帮助用户理解底层转换逻辑,并为自动化批量处理PPT文件提供可靠指导。","parent_id":"f7bcfd40-cf6d-413a-b3fa-59f8cc0f5a06","order":3,"progress_status":"completed","dependent_files":"office/api/ppt.py,examples/poppt/merge4ppt.py,examples/poppt/ppt2img.py,examples/poppt/ppt2pdf.py","gmt_create":"2025-11-26T20:51:54.8837302+08:00","gmt_modified":"2025-11-26T21:27:37.7336243+08:00","raw_data":"WikiEncrypted:KM75z0iY3L9qXmPYpDjiX1qbdTjesHK74ETswdG6vqlZMsjo1yF8oMSjm0h9h4SPqAA9s2/fY0u5Go86qG0e7puw/egGWxcyFdsHnUAHalzweGkDJd4ID4Ot45RQLDfvOgJ97GHCNUHvMIQ/wv9KbibgZsYTMv7TScYpNZR5PoFNXvckhQ37kiTFnFAO22P7dpPPQKVKLe1p4Yh/SenaIovW8xNWMCsSrz2RoEi/WbZ088LZAPwjqfaTpittmHPNafzCxPgD/5RMRJ2Bvhr05j8WWdW/2u8RUsFONFCVWblVjDlwA059XBLRBAw7/567+0MsJTUXCOAB6QmpVbZQJ9IZ+9RHWzHIZkm1/nbgDkvcfHbYXBoFw4FL23EvsNBpdBnrW8LDlXH8tGVpvpx7TSkgocmSU3WlWQfkYsXM0eZld5KtT8XjRCSSCJV4Nme/P2FShFcdkPyX7zayYLJ7PdkSvhXQuX62VIwxG43DbPcCuEb82Wn35QgODu2hndA1Tl6NL2o6TR1OaJrBvTMTBcpdx8XdJeni50R6pi7bEqud3xBfqHh0inq30vG6Xk1xVqm6DHXknXra/Ba4SRITtZk72hoP+VwM4OlcBvmiBhcV/rsb55NoXEisWRKbAITlw3vL9WFcIoVUAuwF8k2/PtrEBQx5ObnIZ8k72f705euij8QZM4cbs1njToKI4Huv46nRqZVDM1gwvCGr8zc4T7pgXriRnZK407NdWgnhMSGm8jNVGXNH9BJC4wCxQDcQwgcQlNvQ2A8TwZVQ342khJQp/yoT2e10UnUDqfniN3Zn+HwCqnbZxeIzutT+gyslB4b56mBRdOwmdYlJJlEV4M2h9LXt5v8rdZ72jcup5nAQxLGlMgWP1lJ1pgT42qcYNIBWK+zZE52inwCRBh6pg9kj3kxzcbIkkf/iWQJEOTvneWBoL+0bEQ2vy+XWvPfQ3+TQIx4QdyMQzGx2UUiaQ1MNPTimUg1AmRhsd3pVVntjoKVlsL00LvSsEDOmrr4g8Wzzivtia5SEpMZ5od4Edg+Dm99jQN8H8KwLNOkFiNbE27vk2JdZxrijo2ZfvesmqIVWFWZg9Nz5K/qPjkeDvp8C8+Umcj1tt3luFdwQNhQ/bQYMFwXU31jE0ibebAS4DU7aO3+/yCcZUXUscJvUl8gcFySZXvQ+D9cS3r0Z+R+QokuL123t55lVNl97Zwj6XvBph5+VD+9CxvYYiQk7Og==","layer_level":2},{"id":"15df4f0e-7ca4-4c9a-b335-86551e26b2d7","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"多语言支持机制","description":"gui-version2-i18n","prompt":"创建python-office GUI Version2多语言支持的完整技术文档,重点阐述基于Qt Translation System(.ts文件)的国际化实现机制。说明translator.py如何加载和应用不同语言资源,gallery_zh.ts和gallery_hk.ts的翻译条目结构,以及语言切换功能在setting_interface.py中的触发流程。描述新增语言的完整步骤,包括.ts文件生成、翻译、编译为.qm文件及集成方法。提供语言包热加载、动态刷新界面文本和默认语言 fallback 策略的实现细节。","parent_id":"fb4b14d8-a3c9-4f17-8f24-10e8bfdb747b","order":3,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/common/translater.py,gui/qtpy/version2/gallery/resource/i18n/gallery_zh.ts,gui/qtpy/version2/gallery/resource/i18n/gallery_hk.ts,gui/qtpy/version2/gallery/app/common/config.py","gmt_create":"2025-11-26T20:52:14.1919105+08:00","gmt_modified":"2025-11-26T21:43:35.0288797+08:00","raw_data":"WikiEncrypted:Cbbt000XDlthHZQ+AmKcwLIRpSG0tIzKhUZHbw4KEOrHzbskSIiSsaeAS0GIM64qe/0vTDFVFRVnnkAPc2vJFMt3bMyJPTxdbSs4eXxm+BdcGhP6MQpjWPt7MfgDhO67t6nvsSAULbD2IhQs26Ic2TKNmyt7ScRWBt9uV8FVCqOVxXEoCwqNJL3o3AuWP4/LKVyLnpimBmxHoeCGRFkmKKzY0pB9dTMxeWzETXPa2n4HJ+GsRPJWqpRFSWqoUEfcePv+O2+obXQzbCxNEzNeh5Ck97s8fl6SjyNS7kivUmx6syi3JRLWuh/zaI3jX1pUGlY3XUgrj2YBpJAE/UwshTxVks1RhdlwHt2GwDrzFlmMg9Zky/2wQiFG84zej2cmW4gJ6c6lWw/1Z4IDvWNCEjikgZ9ak+Nevw+WaHAsyBJF+tO2m34c15eZ9Y+5UkfSYkuNxOLlL2FxMqBNmvNAhTSImXfcXsnw5vuyNv7YMGVAzKgTkmarmaK30O+S2og5CcyZ2EHIHqhFuqLqujFvzRKlz+22SY03lyCUMmJmGY1NUTMWOMtrPWal1/AOnDan23qqAsd3fghMdHnAm2qFjYjMCKZMX03i+I10oAGC4vCt1zulcCACnr5g3paQmx1QfSUCczqHdN5jXtpTHy3zbRvu3W2TqFqVNVxJZHCPj2y7fyOoNTxr5TYcHQ9jHV0Z33QD1W3zwukEr3GYHRZC2h3JQ4VpZyW/7RG6QDzwds40R4SYMTZtbuMCtxNAAyQf/27ugF8Bl+k0uGeOETo69xqOZY68oxmr+nbw1D1JgIpccWno4xBe0lI+jHAP2sS+3bMrJLUgo4YXRUlSZ2ndfXnkZbosmVjQAFt8qqBiVNAIGXx1Yea/rxAp31Gk2UptV4GjcEREX/2CA/xkeeDvc6IbWKVkF7k+npIvKFkPJMNMnJXRWnBbaMHILm6Wen/Z82cZP2XpJ5el160Sjt/VTLpMB+EAKFqcuqVcdxk4VhCkJPLHo3BnByNfdwDJ3G+2+/w2wWID/wLWPpo74JKl0aMhCwEW6c87rkao7ojaUqhXEvqImC+0H4wp1Sk0ruGqFcmjrLz/HBxSplWNUkL5zwnPYJkQa3A++JnyF+YuV+kjMU67GBFlseq7mSM4r/QK46uAuscsLmCEcAqp8jzGYVNvcHnrsNLl8myxrP6K/NBqDRg8wKV7ixSX1n4Zyxw6SARMoAiHwQ4Q5oVfZS52lBgiF4Fkt+vSA9k6Qyv6PYaBhI9x42gaX52Cii0FglGNTPTdnKvgU3uDjM55qVV4nz5+vef4jJOoQ0VbmPsgreE=","layer_level":3},{"id":"1ccc4ca2-b247-4dd8-8223-49ab2b96a9bc","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"独立使用模式","description":"wechat-standalone-mode","prompt":"开发详细文档,介绍PyOfficeRobot的独立使用模式。解释为何需要独立引入PyOfficeRobot而非通过office.wechat调用,以及这种模式的优势(如解耦、版本控制)。通过006-独立版本.py示例,展示import PyOfficeRobot后如何调用PyOfficeRobot.chat.send_message等接口。说明该模式适用于希望仅使用微信自动化功能而无需加载整个python-office库的用户。提供迁移指南,帮助用户从旧版调用方式平滑过渡到独立包使用,并指出依赖安装命令pip install PyOfficeRobot的必要性。","parent_id":"25cbcf29-42d4-410d-b72e-2c345cf71be5","order":3,"progress_status":"completed","dependent_files":"examples/PyOfficeRobot/006-独立版本.py","gmt_create":"2025-11-26T20:52:21.1790374+08:00","gmt_modified":"2025-11-26T21:26:43.5414161+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tLqYWJRfAHb4qZeY30DLCX4QGDqb3CNAVqavKGP/SQTP4PjZ8UbhmYz3WPaFCkEb1RGFdaQtb4oM7dUH4ay3zYkRqi/dpmPS3IrVqfC65m6gBpcaYBVavS8TCDcNKBsLIhYbE+r4RJ5/Gc0FHL+uHJ+XzEbLXwAaRwtpOA9YqzQm7S9Gqc/6kEA5a2rSNXbSwT4Gfe6NuVBvf/b1aZjPB8SEzdLUulKa+nBJX/Kzt1yOYPMNDN5d5PyR2rVHTGHrYzXMYyUl8coxLHw9B7fjXEP/4Ogoq+xbLgN5dEOx1W+C6Z3EU2fdZCMbrZizHHnPrOrGyhjBAsSG/jaPF+fdIvkl7nYkEDXgaC1JgeWXFeRy64noBmkatZWVmUSHVGGUBNUCftzkYMNi7CV25lq/zMfvfB2dBteswIV8oRm+GOBt0zL5FEmwbNUYO/HCZN44pJaz6ueCuuL5hunF27Z7ALdhHZKZDAVQeKuRufzX2XXqWs1+eFAg6yMSbu48Ho3JL5nlpSf4Iz0np0hbPYNP7hvGC1lUw09kjtfx/vXA2PRmo/y9PMnjSO/a/fiW0NdFgo1vpcMz/gLDKzl/B1HrAAcd6rEqU6S3rXLyRcq36QalnZPyOflR7od3wEfqPcAkjj+e3R9GmMXC8Mzm2V27A0U9D04Pn8bLte8Zo76on3wJEeLxJdaKrb3gPOfW9g0k/AX+odAHPjOg32uZG+t7j3vhRY1Rrk2S5LlzBXI+ngKqGLe1PcPEVb90x+IZq56cIx/HbG6qZJKGXBKbu2CSZs7YGOwJA1pI3OiyfuO5CwJkZlJ1UtpiNsMLiFJuw/W6efjZLl28kHM8nui+RO8KzK80wUJoFw2Wb23nRRCM8VRoBD+0AaDpsKrfRp9cIQGzOwzY92gZ1d+uFFUhuZ+0fJ6fsvj6MtYpwKvjfm2La7e+5U4tmKbyGNTCbkeySr5gL52hwp0WC4RImHB1sJ3wVU0U+MdqG5ROSrclE7togyckqjWFasxKduxD3UokIP9v2zhx7uenhi+kIY4AdQo9mUZhhqaZ9SAhVpPR1e+uUVd/0Bfj88RQXoedj9M/d9MlH8SmH8ndHCf1i2ThU7GtGU8VvAItQfaxS2/QyKVFq24SZTMSADGsYj3fSNJg2flhPMPvzet8XQKPO+lfwXgyldY=","layer_level":2},{"id":"2c1a44fe-6eb7-4a84-b4ce-dce23410b236","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"查询Excel数据","description":"excel-query","prompt":"阐述find_excel_data函数在海量办公文件中快速定位关键信息的能力。说明search_key支持字符串模糊匹配,target_dir递归遍历子目录的特性。演示如何通过该功能实现财务审计、合规检查等场景下的自动化数据筛查。分析其基于pandas.read_excel的逐文件加载策略,指出在处理加密或损坏文件时可能抛出的异常及应对措施。建议结合文件过滤器预筛选.xlsx/.xls扩展名以提升搜索效率。","parent_id":"3aff6fd1-b9c7-4eff-b8f5-26462a3f14a1","order":3,"progress_status":"completed","dependent_files":"examples/poexcel/根据内容,查询Excel.py,office/api/excel.py","gmt_create":"2025-11-26T20:52:27.4990924+08:00","gmt_modified":"2025-11-26T21:28:12.6381146+08:00","raw_data":"WikiEncrypted:8x3JSVErdDUDs2nXur+vXQPzsXShyML3sZc6WFlkKpbIHRUK+SocY0bsEjQvb2egEWiBLEEP7xsBq1b7erFxvZpZR9SY6PQ10z17Td1k4rVGriJb/effwg9XcElsMbmwbHk/OQFhufLvcWt/VrsIpWZ/nm3cc8mcEgwiES9rwLavJLKoattaB0tLI/vwspbzsEXntKbar2ECwcW5HbQNHxjMu343Sxl+EJX8w4aHtmjYTear1PuJJsRs8WKpeQeyJTbGKN3LUAlBC5VgY//ZCpiBPng+zd3bf9dvT9GI0lUO9ZIHd0xeUqO7JnArcfLN5QLIeOYcdeJwKJsKUlzmKpK7O9vDkYhlIEl9MSvHqqs6+vpNztmbGxEq4M2Dmji5KP/NVkfSHHa6JZ3l5vY8CEObOstdSz075Dn6gyEEmu0nyTk/PeMp++HX2uQ2+gg00Pv4y8cMA56F4wtbcTL3J1Ke835CoCHzmk7RsB4f5aOpk5jQmUtTr1lGeRYMeHoeZErudtzieikqkJbD9xH0bdZlOHVFW4QdbC04Ootv7wfxKG8HOc+UbJArlxQC1TWRvj3kbKLxFo+ao7RxbSECicqVYbQSB3HjTaGsUQuF91l/tTac8T7GBx3qyw03jvQHazmWO7HLZ3bWe6UAbApUliNhXSwLdPukBokmT0wzH/2I4D7zG8AN8AYO3MqTMLOvTD5NwwxIv5+MX3F3RiPXNbceZXZKtB/X9e3nZnvZaApNJnN2fgAB6DLE4eVoLWqcW+va4drOCHYtkx5MzwiSt3cIqc9qBf0T9gcm3fSL5dEldKMEuBgkHXuNmTw3D9ynA/WHXBDHs8t9NoHNh0W4+/EqgSJlCG4aBL/oldQt1c3BfeDdzI5Z4SHkLOqzzO94wh8+w1twhfFM2DZz/rlWEeHLS7CZhnxx9nroXdVq/qacxSsDZcR1HUUbRrUsJEz9sfgjqq2xJ9qH03qkZd9EUj/qNSWP7B5Z59PZB3atxSI3k/k+HV7uLVHsk7s/VQUb","layer_level":2},{"id":"c0055399-8433-4f3b-9bce-4ef76edd683a","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF加水印","description":"pdf-watermarking","prompt":"深入讲解如何为PDF文件添加文本或图像水印,防止未经授权的使用。通过`office.pdf.add_mark`接口演示水印内容、位置、透明度、旋转角度等参数的配置方法。说明水印叠加的技术原理,基于底层PDF操作库实现每页自动添加的机制。提供动态生成水印(如用户ID、时间戳)的高级用法,并讨论水印安全性与防去除策略。包含处理中文字符编码、字体缺失等常见问题的解决方案。","parent_id":"5235253b-7037-4298-b76a-147a71088bbf","order":3,"progress_status":"completed","dependent_files":"examples/popdf/PDF加水印.py","gmt_create":"2025-11-26T20:52:38.046451+08:00","gmt_modified":"2025-11-26T21:28:20.1588745+08:00","raw_data":"WikiEncrypted:GyKjus19dLW6uT5g8+UooFOJMFgfrJqPCX71fOHgznORU9KRF//qgQrjhjSAzMCjJtt3KuN77uIOYcTpnRT0hsClrBI3KQO87eXPnnDdrIlMNMDtF9s+F706vvSPryjw15yxwIxZB/IiD8hzZqJxeyXPXIQRv1t2Lc6LzRrC6Vz3DNCUqGpRkKazAnQmLgA0IMlO9CwE/aUrhSRBXKrVz/GxuWMI2ciGa/mhv1P7hEClRPFSU6wGam0Zj+1pKirkS8SalyuyHwt1mYxN/+dUa7+OX+k1nmU8cgV0nsLu93aoWnYN3CzrXbl1+/SE1pxGpBD7kFIPHo1LROUve5Z8KwRpoJOqdJgHu4sxmu1Je0Gg3IXUEbgFekaDX4XoxRPDWMcUtdcGqusCrc4GoW/V5x74wukGVSmLUeOCqNmgtWrWACVCtr4XqfBCz9HqRPek/XkhPLVRpduya1jIY5oXDpPDZkyrlZQMOXljgW2zCtTQnzjymFCy0Ga0uT83xDhtX9xSTzz7eaYssNHnSZleGMkygoarPZvkCOVQlAF5xXeQKpE/42pJdfcgow6iZccYl7Dq+kRqZDi8Qj3zAX/EDkCkASs/edrlKrHN2P1JnUzawLieTPo+LjoDSyca9dYFXSwuy+1UN7+vuN2f5bic1ER868kkkW/LUMzeIjcFfmy+FwNZbGUEs+8fiOK7bMEuVOZT8/aBjlYPftXNBvZbQe/nwF5VoqNFqh6jGi3biNlSPQFCzDzZYDPqvFlxpFmRBuxmkXcZkXBiUkmBZlK5XtZBqnKKelxuKkOsmXfc8IaSLM7ti8AWyhYxR2rlZjKo1HjwJuSetPyeRhAr9riU+og0OBXi2ncjj1dR9rAhqBGMrW6atqS0UQMUwHsZoGJaZ7fg19j31mmSG8xYuV2zpMl+/WVcQGyuIc3kU4DoJt+JQl384ORF5fLFhn6/NOAN3Lapxf3CxlClhZRbPT0iVRQRHy/h5CJ1Mfn0SvaWxHQUpmw/jT8bkQApVIOFl27u","layer_level":2},{"id":"1a3c6951-ba4b-48ae-b80e-a32db8baef31","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图片压缩","description":"image-compression","prompt":"全面阐述office.image.compress_image函数的使用细节,重点说明input_file、output_file和quality参数的含义。解释压缩质量(1-100)与文件体积、视觉清晰度之间的权衡关系。介绍底层图像压缩算法(如JPEG有损压缩)的工作机制,并提供批量压缩脚本的设计思路。建议在Web资源优化、移动端适配等场景中合理设置压缩等级,以平衡性能与画质。提醒用户注意原始图像备份以防信息丢失。","parent_id":"e11e3a92-fe01-4716-8371-3f718d2870ee","order":3,"progress_status":"completed","dependent_files":"examples/poimage_demo/compress_image.py","gmt_create":"2025-11-26T20:52:46.6711546+08:00","gmt_modified":"2025-11-26T21:29:05.1594684+08:00","raw_data":"WikiEncrypted:vw8SwXDMWAcq3MVrbhINPIy2lFIyUv02K/Vxf8APT+buotBbbd202WaMCDGxRot3YY8pd5jD8L+wha/AjF+pD86N2wO6eLxSlbdEJtiknaqWpPZKp9D9oLdQ6E3zg0kbnHNA17DS1Wd38Va2afg1OsZ+4i/ipnghbZ7lJXOcAZYQZsCJ0XR/6XbVhydh5t5aaUbEYIWvJjy2TGbHgt2bDT09Z/3kQSqVNT0Xb5rwrvCZKjKIvkiCod6YBhlYqgbmQpzp+mSPRZVIG42zq6uoVG/rrUFcuqwRA6G6dBxFpY6A+BBGfQHnN+1mBqt0xwVjK/ELX1+hC3M1DBsekkq+usq9iZOLn2+JUjidPqPHtW4Q8VUK4PudUe6UZEQTB/kgqSMPYHkkXEz5XdvCeYzkWzd3EBsmGXuDZhILADhr5Yrf/rS7lmI8d2fc1AKFbECJSUOc1qBGYndeigmxlaATUGObd/ZMn0d5/4vMIuI++PkE2EG4JQ3iAqBSic2H36YMqPGONTgZWoL0Cx8/GoESZtSdswnEOGjv3BVQi/FdgksZKlyrsOU5QX5BTYDPoHdRsn0htfR92YahOM5IqTRhmta/HME7b7xeWMg6J8M1tmkiSzj9OeK1rWkdgFSziqxvG/FE4A2LWiU9NqNxDkXB1dgGo/LvxkJkmtlP+dhdSG93YriDluPnmjQrcN12WrbQn3af4p4+pZ8N0XPqaX6MZfbd/twCpCoh7VaYrNm24tqeXYIR9qAperNYVcpClbzloCaGKCtcjpHshQbr756xaqXPjb6P4Go5t2bEYGjNSSUZparUUyG9FjWEmt9ikWcs+8/eSdRNZ3tmlddgDmsQmPRVBHtH+x2Au27YBLza+wIsDB99Zzil9+FUxIg+krC7GHoU8BBjH7fyJtvCBoSM71n+KWKKxe84JBMmpwNii2HIt3B2t/cu/EMDqWXdDByz","layer_level":2},{"id":"e2290a1b-b483-4662-8951-f98c14a0196d","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"数据可视化与词云生成","description":"data-visualization-examples","prompt":"系统讲解如何将文本数据转化为可视化词云图像,用于报告展示或舆情分析。说明词频统计算法、停用词过滤、字体与颜色主题配置、词云形状掩码等关键技术点。结合`wordcloud`库或自定义绘图逻辑,演示从原始文本到高质量图像的完整生成过程。提供性能优化建议,如大数据量分批处理、缓存机制,并展示如何嵌入到PPT或PDF报告中实现自动化输出。","parent_id":"9f1b3695-d545-4923-baac-47827243ec01","order":3,"progress_status":"completed","dependent_files":"examples/pydatav/数据可视化-文章转图云.py,examples/poimage/文本转词云.py","gmt_create":"2025-11-26T20:52:49.0253635+08:00","gmt_modified":"2025-11-26T21:29:04.0180806+08:00","raw_data":"WikiEncrypted:LlssVZ/E1BSUywfa50FLlarCPzzhkcNEpckBoWTMqT3XCCe4OQg64oGn7t2HCfkW5ViIXd156pK8HLObn2bYtaWh1grlrsWaGSrbcYmJ6pm0qbsedS/S3y9SIgpQrafwYqKx/HuiarAGGgqa9DrpV9ef2u3/lMfXEVlrAt6W+YnUETWd7ctd572GHZI55lJiZv9TdZSJFxqG7zIwbv9UP5V/FctmuZnbVukG2J54PZrVtjsjvtovsBJMvSQ1Rhxmmsmg6OMQwn+qzwWARbnc2wafZsEOfFWHhw0sWge/cUNxw/LfP0Dpp4JWL3R+txOKNdapVWymMUfh1f2OaCvRJ7B0qJmIRzzgLFsQ1Y5yjIU1MKB0ZLMg/MD1EU8PiPlsVKMTqJ/Uv8puWH41AJWpup7u5kvYDU+Z5vNEFD7mJAJEDwq5tQwFXhmQHJsaUbuGIyheYnZ3diX8LmhaHMfIb/osd07g7AimvYIh3x2zBpsql5ebAqjZizljd7AVXahsxXr+hdZ8/WUunl4n8sDCAZngDdrwyfzD5Cp3UPqfoIZRiChwZank0SnoWd31CVtRK/ZCHyfRPvvHIJr8JR90ReQ9OvBQ+4FpLlLiZhNxcJPD/vsf/TR+MNXJRc9Hid5bNKQ6ldgqAnlDPZ1yQA8TFTENbCY1LToJGETN2BxByIXXNLM84+BSPEC8XyXvD/YCj1naDefScf5coAz5yz+xH1ZFy+uLC0khQNx7deH72RcX1cN9EDMUEFXlYgdcyn3Wve3nWJpdNHLV9jmg4YxhQ/5KJWMprE6hy72w5LORHRkk+FLYJEHzM/mAj24Yh/V//DPYxlzuwe9dR90bZd5+FsaMo0IQvUNTgV44tlszEhKdhbn3B714j+UzffI24FVWYFc0CLheuxIaV+LzzU9skVg/7w+RiuIDZ893p1GRZzNuDLPj1EAzNAGxa37kxXPr43G5T56dJS/DPBuLjamY9QAlQ9d2rUihOwKUh20LFo3VW1NAcT/ae8LdUjJ4Cw4ok1N1ZWUoZ+bqwDKdNUsqvlu7JHY9nxRjsO9D53kOz/Xb3yDSiM6FN+jNSuhZE/k0nD1ngTKllJfLFHPMvEj+CBatUjT1h2tDp++pWam3n30=","layer_level":2},{"id":"d164713d-2f96-4208-8d06-d124cc50ab2f","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PPT功能集成","description":"gui-ppt-integration","prompt":"说明GUI界面中PPT相关功能的实现机制,包括PPT与PPTX互转、PPT转PDF、PPT转图片等操作。分析basic_input_interface.py中按钮和下拉框等组件如何调用office/api/ppt.py提供的API,描述文件输入、参数配置、后台执行及结果输出的完整流程。提供实际调用示例,解释异步执行时的界面响应策略和错误处理方案。","parent_id":"a4bd1c46-ef48-4bbc-80c4-8708947bde3f","order":3,"progress_status":"completed","dependent_files":"gui/qtpy/version2/gallery/app/view/basic_input_interface.py,office/api/ppt.py","gmt_create":"2025-11-26T20:52:54.8033682+08:00","gmt_modified":"2025-11-26T21:42:36.3213674+08:00","raw_data":"WikiEncrypted:UzFiOLRDIflZELt6o1u2wMiaSbWO6+gK2CFB3711CSdi6I4WRTBwnR5EHUm5UljhB5Etn+w1WczJIxnt6O0laPwtmEG0h0JgigKCxG9j2iCHxEtiVIXDK1ZyXIDOUecx89vFTbs1seocnw8Edofl6/vqHBtyezJTCnPhFkjBvesKIRIJzdLzcvd7fAwfdxD9kZuVOKjYX8PYP8MWPZbbuU8Bop8adYXEQzdSSwxz/GlkOLrhJ+f7BfmqsJ/uHaYPkNOvfgjFtZ/aD51pa0dBnfb8OiDF0YRufGZqCgqa6NcFqrI6A7gwPyO4I/JXhH2yCFPzZ4Vjhj11jhAi8e4Ac8n0iIwrqBjlrfJtHGTRbtW4IWLLiKHVxvs+rDFp/YPV0n7BUJIadCWKXWeOCX/Sxq5pVMM4wkZ69yv16w6q7YatQm04M9XcfSDJY1IU6wtIw50+BtfR27qAOq+kIOuN+OJG3OyVe4LAn5LNuA2pSRWq0YdXGTJy3KNPm896DDRgc4c/HEmEdzN/NoPTHBmwzZrEYI9Uxwf/dUH5uYbFMIY4ssJmhRuSGcocAdgnSWEyd5VTsuekciA5rQcPBkP23l8/Lg6hwyvcsjrzpqNey077GLTM+pwwaBMNmq9rmXrUpdJJF5zQYz3tYOezp3IXcbbOYDBf5AbnZYzqYSD9NF6VrR9Zpw7NuFCZ8v3eU0hRgoLOI3Srjb61iwYQ8dq92b7rhy9pb2jc8FKiSY1WnRUMufzq/Lpw66Tof4ZgMcxoFnCbkGKu4GcZ7kz/q6ekbbTq3CkIT7xzHcizR9QGDzR0R9euYf9LmnfSut79F9L0jUFH3SlYlJprujVNn+0eNNJMiaixLyvcIuwUulylLfviwD+YQaEf0D2OgOL2eDM8VJcMMpjdQ77JF2v1HBdvEDbTdHUac4psjT+HUphpc2M=","layer_level":3},{"id":"736aca01-df8a-4e1f-876b-eb8f8556c0f7","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文件传输","description":"wechat-file-transfer","prompt":"系统阐述send_file函数的文件传输流程,包括文件路径解析、大小限制、支持格式(图片、文档、压缩包等)以及传输进度反馈机制。参考'test_wechat.py'中的单元测试用例,验证文件发送功能的可靠性。结合'发文件.py'示例,演示如何向'文件传输助手'发送本地文件。强调大文件传输可能面临的超时风险及断点续传的缺失问题,建议用户对超大文件进行分卷压缩处理。","parent_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","order":3,"progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/002-发文件.py,tests/test_code/test_wechat.py","gmt_create":"2025-11-26T20:53:29.3889321+08:00","gmt_modified":"2025-11-26T21:44:29.1809539+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tAXbkJxQOyA5I49P/dM/UOZmiIdrbi6tEToiGiiWSsmppxhIZHcABrFBChf2Gjn2xFobMAIyk269cAZD3UWB9BADgvKf+M6kKEkFPdh9XGslNZWrm14DIXOACp0g5nK/MbjtFcZdi5KEme5GpdlJw2TFmi3xYuCzlU/GE7b38J/hoBh9RCeb8wXOv3h0PloZYzQFN4kO83mJKv3LwbDmhQL1aH38vEsF+lRWVsrN2YNQtA7rcTetLyk6jhbyQVh50wR/d5YBPSlACt48WEtUjK7qeecjCDAm0WpOeuwtnxQhMXzOFkChonSeVhRgQMd9gripbCjrY89hvOhAAN+VwWKA4CDyJRk1qdDWr34iIxTYmtgIzcU8KoRDqBuYc298iFx7POWj7Qt0R1YYdFeKeIIhzbBu3HgS/MNT8DT9bmaMnHphwcr39AsWol08B1Syou+Ykkh5lOs2n1vqDZuOkxLhWMYluxjlRuMmkIjBwsRpCm3Wr4qNBgvuZ+WS4pTQLP6chdnTUtESyc1xNC+RNEpTKHW0S01YDL21A9WI/46gGorzyG/3hFhl7MgLdIRiKHmk/dQ5h2/5CSaj+fNgNntEDfgNq1m7ZFeIrbqy0mPaBy7ZmlfFyyPf+fikHaFQC/JEh3PwFRIm5R2TU+O8Z6vRiDCZjQZGIzpLVLCag3nPEw9jAgVxasfrBow2aTfzJU3rDS26mT1BBBIMdbQgvkJxUeH66qYK7D/I/+2jt8rDsKiKMhSr/2dpGvb3uTV/xHznVA0quONsleBabVLypdFsaC4tghtB3pjLpyJCSky1kCvWnUXDdrfpz7axAVNL/BRPUZtR1JeV7hPCrSQfRGD69xCGswjGcmLW8TGl11Fb3qqFRFvW+Sh9+4owG5UqmzBlpp49Ab9UPdgR4n2RMUO9wDfqu85QUfIIx4AymV9KWDH/bF8GRCqeLoWNy9NMADX1foorqjgTFHEpk4GX7QhTJUn4hJaL1GF+hujyKRo7ue35+VOkPCOT8qg1Td9SMnFCPO3vowhJz+waZAK6GSg=","layer_level":3},{"id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"API参考","description":"api-reference","prompt":"创建详尽的API参考文档,覆盖office.api包下所有公开接口。针对每个API模块(email.py、excel.py、pdf.py、wechat.py等),详细记录其提供的所有函数、类和方法。文档应包括:函数签名、所有参数的名称、类型、默认值和详细描述,返回值说明,以及可能抛出的异常。结合源码中的实现逻辑,提供调用示例,展示最佳实践。特别说明`office/__init__.py`如何将这些API聚合并暴露给用户,实现`import office`后直接访问`office.excel`等功能。对于beta功能(如testApi/ruiming.py),明确标注其试验性质。确保文档的准确性与代码同步,成为开发者查询具体接口细节的权威资源。","order":4,"progress_status":"completed","dependent_files":"office/api/,office/__init__.py","gmt_create":"2025-11-26T20:50:26.6686164+08:00","gmt_modified":"2025-11-26T20:57:46.4098368+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg+WPNa2UHH7yP2PPjE4/OPkUytUlTK+XtmhJqDmkbtEH1UqYxIFVrN6fOXvJbTA3fStO78uxCbAFpUd8odbSP6Nheg2GH+yAnXf4UyOYsn0XqCuT+ALZYktWixOWU8ePh1x1IONk8sVRVouS2h+WlFJqePjg0TOFj9nLJLJv2aIG3bHwACJPn20xy4DqKlzuaTkPSh+Eg59jKwq7xa2mNDG1gjbrWnEdW0ZfYiPPeuAlqbOkz100MqxPoHrmNWytsw6K57FIdlcBv1o/o8ukgwfEC4QfOYoFD8XepmKU5hl+T0sH+iEm9tf2vOTa1TDorobmFi9nh9oCOVz3niqXm4P20A9oo6/nG2yUbEFsr/Np7v0HR0na6JkqVnHKq1sdGbZDvhIPinPKslhzMu7Z1y2BclfV9cc8NJOunVIMGaV541+FgqvV52L9PGvZzAhHok2TlMTSDN50R7PRfoBK6eTFEBZw+RvZsql3iIUBeymJiAqTFsNjCSykkmBZQ8hM7rQK6b1EDh73+jhaKr7gL1Ii8prbqRbw/1o2sLQ3rpEw4RTP5i9Mc9V5ufSPvRgby0Rbyu+q/27iITrwgF6sW/e1CDGSEzgjqU7uofI1pU/pUGZED5Z6Ah50bJRav9AF8rrmYUiCD8OrujEq346U2oTzr6DfkKCubqA/hJqJ6ERQnrWNtLEXQTUiFjtgb5zJSf9i4pkcUFjHjJCH6ACQcW8aHiIFxBB69t43ZQelXSrlQArBkjG8RZNBOhxqv5flmbJ6p1eV4HaZDhb5/7N0mx+3Sx6Wa0pUsD97y86vbudUAB7pjtZ5Slbn4TnXWfEdikwNX/+a/Dz2GKgigbxZzgxrTzQIb4/Gx1hmfwyQWHUb+2KidnhFxomcHZZtCF9RMgNyIKzyyFf0Zorm/sHsceb1RsDSyQtPWume3O4y93OKrQnmRl79MdnuzKxnduiuM0oa6+gQ/xMU0vhZQFxUMXQq2bfDc1C1uEt8v4ZTQWwNyDUmwKAjkwK6oRxdorTLLC4WOtVZwA0jvQX7h3SuHfrX+RrT/+I3HoEo5avE3GFttbIdONA/07IAFhI9D3Bbz5v/i1ONvmdZnFvmng95iJ1zPVXDlalwYknBdocQZAQXYwZ4uMEFKetmGPCaxYCeDQ4QzQY7C9EnhB1E+gkq84rku0vBZgcOFDHbqq0DFG3epjgXzJLkX/HOyvUwSaZhS0DE+/SFh0V9SvuoyQYJbp87FqP5p+cqULY07WEa6iWsTHk3wwWWIHDYwPgaPyviVrliKc9rKjnQ/hWcvt7npB15vxxkkKX6OWmYuPaLkCTKRJn4Fz8IT82iuE04cb8XHqdhRVho5X5ZnofN/C/0ZDoTMlG5mP+DZB4xxQc/9Df/K378wsA4hGs+PSmdFYynmPNSuwvQm78epzMEMlhRrs4hXRI0Ez5OhjB7J5lJideD"},{"id":"d70f8411-b612-43e4-9d1b-04300c977a54","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"运行指南与依赖管理","description":"gui-runtime-guide","prompt":"提供详细的GUI运行指南,涵盖环境准备、依赖安装和启动步骤。说明version1和version2所需的Python包差异(基于各自的requirements.txt),指导用户如何配置QtPy运行环境。以demo.py为例,解释程序入口的执行流程,包括DPI缩放设置、应用实例化和主窗口显示等关键步骤。列出常见运行时错误(如缺少依赖、Qt插件加载失败)及其解决方案,确保用户能够顺利启动GUI应用。","parent_id":"bf12cfdb-30f2-4b0d-bc87-c1bd097570ef","order":4,"progress_status":"completed","dependent_files":"gui/qtpy/version1/requirements.txt,gui/qtpy/version2/requirements.txt,gui/qtpy/version2/gallery/demo.py","gmt_create":"2025-11-26T20:50:50.3267134+08:00","gmt_modified":"2025-11-26T21:05:49.4673412+08:00","raw_data":"WikiEncrypted:awhKvzn0aoQbHRmiPXBKdDgqdO0oEdWjlfPznvgZe5ae8utGN/fYLEVcB261S5IAEq2l9bPs/mjH7u+bsOz4rl1G+L81qRJpM1PqtRlI61tr7nEwjYyr8gZ63qA5xgE+YN5qkqHlSSwSVWRtOSqcALl/sWkweqmpFkfi9XH/FdH4quts1RNmXg+LbLUd6ISbctRpEymRk923f4b8KJ3sHJukFjhHjW0PI3qS2a3BNzbyCXzvU59qNeknjpfpU8Nm7T5gG5DeiOaxffovBgFcyPAtB00H8SWpSdfg/ZsWW1X1nUDC1kgw015NxajWT14VH60nEuLn9KCJDQBAMC+obJu4YvbkbonUWT+ZOuA126uH7g6mwFlMNrFDa4y0/L7eT25X2ZGYDQXbbOnAUrzi+BQrPk+ZSUmhm0Dn5MfC4O+wC0eqoDpkkvt3RtPSA+YnZ2+ZdTliavk7evA03fnlaFcRHR15Pc/6kF6gv25lsaoDoumYJZLJrmXd/USQDi7nNevjpCHFNUjOB9gRuzLkORrBoaD868/5GYTthvE9YeqwoFKpiTkRZm4C5khybc0tPRuvFZovrsClfXh11d5Ym1v1Pk3Wf0uXcEPbegBFLQGjYAPgHx8qGwEn9J9icjytnAP15Mp6hoRwUz7X26sw5QzDkgOzkMk0vaGuw0LgtpcYoGbLT8rfW5dLSs/V+AiQVweBVt6Dt6pk4yI9ZN5ZiHJsLRZIEyCCMUtRJEKeBMwmVMubfR8WicLgPSvfbd5e3iTeFY5yK4fvZxaddE16JA+1LDoQZZievq3ayIN6SS869JpM/ddt4Gz3WTuV10gYqaXunO4dHIUb4s30F1SIjBhaiDr4W0lDZTjnCkPsiC7TnJyjqZcxECQDzfpkuUl/AhXXLSEf3PuOnfBJA0ex/4yLp/3QutRoYyFQLx4MUpfA0DLq4rhQRlIkToHCGcmhgn285shR5lWOnq9I3p/Xl6k5Pz/gSmQ39ZPRxdNmDoBEf3RzXNXNEM/U0dlM+egDPdVxogyYsx+m4nVSfKjM9vla4/FgHgmnAi3OLAU9HLf1Ikere0j1kzSyO2gBxpVqCys56cAdly9Ejy/RH5rhC5KRh/bAtGKLaB5CW7Fj8to=","layer_level":1},{"id":"f14f8d32-b1d1-4726-84ea-35edbe9520a3","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"多媒体处理","description":"multimedia-processing","prompt":"创建多媒体处理功能的深度文档,涵盖图片与视频两大媒体类型的自动化操作。系统介绍image.py提供的图片加水印、去水印、词云生成等功能,结合poimage/中的图片加水印.py、文本转词云.py等脚本展示实际效果。说明povideo/mark2video.py实现的视频标注功能及其应用场景。解释底层依赖库(如Pillow、moviepy)的作用及配置要求。提供资源消耗评估、格式兼容性列表和常见渲染失败的解决方案,确保用户能够顺利执行多媒体自动化任务。","parent_id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","order":4,"progress_status":"completed","dependent_files":"office/api/image.py,examples/poimage/,examples/povideo/,gui/qtpy/version2/gallery/demo.py","gmt_create":"2025-11-26T20:50:56.4200262+08:00","gmt_modified":"2025-11-26T21:06:41.3267687+08:00","raw_data":"WikiEncrypted:0oD7wsAnkpFD61eHf5fyPzIt53uhL+d1zF+QQLRLXDxYU90b0tTMnuiJPTUchB6cz3s4iqxxoaHJEujd7kgcWtgfjy2rzSntxcCHy3p9j0oUoncKKYTfxRclAGWV32mohdCKRFpK9pqpR5qLpH99hrXmgqpTkR0vaudkNiHqoqdKCP6WCEHppQMZrJ92j/ivOGIOR0OhF/K539P5jf56qvzp1m8OvckT8yuRcsZpUNQxJQllsjiAtLkeihl6WH/eqnu/cRLyWt+0MO9ufcrlOVX/97Re+oM+/yEXdpUBL25v9ekOzu3zNfQXdLHPz5tTX1aMf/GbESr8M3Yxl96vqcguymiQV1Vc9EQMN2YWWYO5QTb0MD9k1srV6GAkyeoNtwRAFCTLBE6hBdrPyuzz6dyXijgcqeSr5d6+KjrmDrrLN/t68hyMZISUIy5UWd8FlbPI0F0Tan9VxHuoX8vJVIyIksDx5G1XGDu1sUl4gwGVau95RnX9QqL6zOIdyRqwXv7Mm4UesA9ox/ARh9zD2oWp2o8om2vHPB9Qdcv97JV/xv7a3wVy3D88Hbx3CJRKWO/Ouv+Ixj2ES0zC1ZC3Jh97Lk8piSGu9k75hIZt1bGgJXOVnLz1iMt/Xxi+saUROvKmcWukV4R6lzfIokUhDKHXTZuE8R8RBrwfJg1MexrQJvgCH8Nwmjcee/KRWil7R1+GGruc75zVXyy99EIM/MrXM4SzaOSZMDjllKJO9YiFDs26AvdozgclVIVv36M4WxgnRxdf7T705yszcCd+Ai4dhHhOQu3i8iZfe1BLuEcSuHcpsD8zh7QM0rJfDvPFn0gZalTNytR0xzKQf6O7wXK+q55mBGgyFz5eWnaC+JMKO6ne0PaswZw8hAF/kfTePankdz1f7PTVcq6pVDeulABTkK0ZDMJiisRES45VmT6zaA3wRppXwWMVCLgfVXTN3tTUnY0BxbL4hb2Uc/yh1gFZkhQIRX5pzyiXHmmlzfvwVr3GH49fWkp0xyfYMZDjYvPgFPpSPasUFsrr+zk0F8TW7XrlHJkj3K1kBl7dI6WnYEvemnpEyx3nuZ+QchGxnDV7MgZP6MKL22O4tg5hze8Qd3RR8tZVG9jJVX1v/4l3DKMeW2rQ3f2eOtJPYtUCobiWCBKpWI7WV4/uv/mu/hLJK96Es2Sq/jNpgWyC4QFHStVkL7dfkJkCCIrUMhCPT3Zm72bjH+mL9urU0ZYvjI+vavrrAolDX/Tk0X1fG6bCEl8iHkj0XNgDzQvEdfFju1rQVWoyVeF+U0n/lcna8lYfBxXHOUM0h2sR8SPwYes=","layer_level":1},{"id":"d4ea9cc2-c7ca-48d5-b39c-37c2b44830a9","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图像处理API","description":"api-reference-image","prompt":"开发图像处理API的全面文档,涵盖office.api.image模块。详细描述add_watermark、remove_watermark、download_image、text_to_wordcloud等函数。解释参数如image_path、watermark_text、position、font、color、output_path等。提供为图片添加文字/图片水印、去除水印、从URL下载图片以及生成词云的完整代码示例。说明内部依赖(如Pillow、wordcloud库)和图像处理流程。对于去水印功能,可简要说明其技术限制。指导用户如何调整词云的形状、颜色和字体。确保文档反映`office.image`作为统一入口的集成方式。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":4,"progress_status":"completed","dependent_files":"office/api/image.py","gmt_create":"2025-11-26T20:51:18.1849227+08:00","gmt_modified":"2025-11-26T21:06:50.0970664+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg7HT2XNMKmutSipf1Pjhrh43QdkehiciOKujKzOCOazPkjtNpn6mEMYtCtz7jwzT8yeiuhYTSmVTWsAmBn1ajQMXJRuO5FIBgpSh9yAcUnEAIhbXoB9cA7UyYGPvaJN23rNPhwqJz0XjNjQ8q0Z2aFGGkhDUjH4LBiM+AaTQTZjLC5JEuyEm7h+xMNppJsyeLRcYmRY93omtZjK3jCXtgWVcDv9LXZFdzI0WS6ONocmIhRbZEO+p5xsv9yruu9/D+E6hicFKBm/T4+271SqMxPkCR1IteYUn4Bf1hLp0l9ne4CQ//2vGYi4n2Jzp8j6/4Yie+AZdhULcKXU0et0MXIjnBjfH5Teb84Hw5JHFfcH0vKNoCxrSC09WbuoDUTcwUGk8xVgxYKsKFpk1/HYmFoYzRPs/5FOZXuWFeGsDKE0YNNNB/rJiFNLCYSQebFJ+28E7DDCPgHV73bTLbW2vi9MhmM/x7FirzJhaKqPQerx+LE5Nd6xJD+ifcP26kgxIqp2Lo2H2Rwt0xaik0jQofgHRU2Ig2WwzVVKGC+a/X4H1mQ8afbFy9Mysp3o7xHv+Aqht1z3rJv/IM9RrJjGd5YGxqXHRb0G3uLJheGwBcdZEtJCFn6nvkJnj/tUiTootZB5JahhUsF4l9cs04Rh8bgDkGzesU36VnT1xZ+ZVC4ON4dRk9n6jmGlq13PqHuNJ9iiQxrDxObcY/xvwCEJm1TvH7we7rbOpLdEliDr1tLgObEf3iPj+Xv/lvF7vJfqGBOayChVn1k70/FYENT/Sq0hLOsQMcuuLfPogS2bYiUh5wO04O1pwe/ClSjr3GX1P5TzEoMjhKtavK/sHKbOqtU590f1ujfmg9g9VLhkziwWeneAwiw2cGDQ3bvgDI+jD3/2IlEen4QTPeSfVSkq9jEMggHobO04LHfOzb1qo86zzOkNv/jZR5W//cRtiR4fhNbsjjiNpW7ZTAEXrgdaGQQ7emMlXQgSzngrLJkZjJPBb1kJyCMgxtEQuhHibf01VAw2ubEpZhBZ6WauXpT/ItGfTY3VOHcMLYsRDqdUeV8fujb4MDYxqQZN630YtTuw4zQQRX4obpAeZK4gP/tQTRM4hS92195fxCq1INqr/49EdNSQifO3BjTP73vAMcqR9wxSISdYc+1jmYJZqeE3jz0i/xxR93by0w0nJeAeux8eIhP3VFYaO0xKgOlgAUEYgkA==","layer_level":1},{"id":"e11e3a92-fe01-4716-8371-3f718d2870ee","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图像处理示例","description":"image-processing-examples","prompt":"系统化介绍图像处理相关示例,涵盖图片下载、加/去水印、压缩和词云生成等常见需求。解释Pillow、wordcloud等库的集成方式,说明如何调整水印透明度、位置和大小,以及词云的字体、颜色和形状配置。提供批量处理图片的性能优化建议,并演示如何结合OCR或NLP预处理生成高质量词云。包含处理不同图像格式(JPEG、PNG)的兼容性说明。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","order":4,"progress_status":"completed","dependent_files":"examples/poimage/下载图片.py,examples/poimage/图片加水印.py,examples/poimage/图片去水印.py,examples/poimage/文本转词云.py,examples/poimage_demo/compress_image.py","gmt_create":"2025-11-26T20:51:26.2357849+08:00","gmt_modified":"2025-11-26T21:06:53.4132234+08:00","raw_data":"WikiEncrypted:vw8SwXDMWAcq3MVrbhINPJYlCru8TivnonlK30HLqOPWcc/KvfRqGE6p2KJ40q4F5OCJrGCfqzTRIuAD7c4Leg9a61ShxlA2Yn46gerUbLZbiduKD1IBuPr85JGK4AEPuiDV6vjYPoUZl7RGDoWxEWw9bxo1SMLU65aNDHIBeMy8cCEhX5bUelzgEO5DKc7lF2YrZEtFm93zZMh5Opwo+/Cdl9WAxESWV0a91UlMMNkjI1of3ZMf4RDVIUhlgXj7TQtXFQ5U7R+2bc1bwZVik5NATr/aOjUlLnbTZt1vcVJukjo3jN+A69i43TJj5l5bFlke1AfWa06kNApy9Ih2wofhypO066dI9o6JcZHhSSDqCONJX0zZrWP6k8utx6eGuLLQifAXmU6k7jIV2z7g6MrKKJ0Wkx8UT6S4fUW3szSGPNF7l3e1puASeLkyjdS52OCku7xhwgQS9JbKhGAhwl7iYmDBV/40I8/Ogs1GSquozjcszkhvDi0ZtVRAQhWT4HxXgyxmaeneAAUGTjhGSXOcOFR7JUtgOQJLyq1g8/rx6Ivxhpz7S0LKhU51CJvXQGzrsoWEoNMYXRTuz0+I7fCvFVnEBuUuutCAxqoPeHn/sYMU/3LSVlg+JBH7nBZFiPk6tKcC2vpD8EY+Iu1fb5tebXiVVUwicKi1NxJ5FBYcuK14HJhQo9e1I2ItpOJ6gtAD6qkC97zCat1fY9HOJ9MF5nUrtaGjtFtFQNtVd9PYMi4OZfKRR/NSuh4I+BeoBah+HPg+IJ7JjZ5JszvSm73fZHC3ECJzdB/UM0Cem6q19g9OTSTIvyVv1Z8XTWScppPaFEWqu1iBWWcCF7s8AbJ7JKlm/BSqsDGBOS3nbuVUf7EOlkOmiAYOCTCTBNW+Ftv5JxMpjR3DqjnWTw41l23mpCCtyc4EEUzaRPVS9CVTgF3AjhyxeEpTuTDQtBMk0L7PiZNLfodmcaVKvALlW+sFfal8EFIkayARg7U+kjywl3b6mQtv8csddhDzQwcRrbBc6OIFoexgBKOi5l2EIK6vO3QGfn51cQpzvgA9xqLkFvNRsLtiEakQFet3TFm9QaFpIEFTKJyYkIVnVdEFdpWlhTu/bNyj5nL/8fAjlTO3QnRz4O+7vJJPlIkT2ELrhW5yib3YCoT/H5Y1VvCY9ivmcdFe9rcYsE3jII01sIA=","layer_level":1},{"id":"f8fcb270-61ea-4ccf-b0f5-92f482a19e16","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Excel格式转换","description":"excel-conversion","prompt":"深入讲解excel2pdf功能的技术实现路径:通过win32com调用本地Excel应用进行渲染导出,确保格式高度还原。强调必须安装Microsoft Office或WPS才能正常使用。说明sheet_id参数控制输出特定工作表,pdf_path指定输出路径的实践要点。对比其他无头PDF生成方案的优劣,指出该方法虽依赖GUI环境但兼容性最佳。提供批量转换脚本模板,并提醒注意长时间运行时的进程残留问题。","parent_id":"3aff6fd1-b9c7-4eff-b8f5-26462a3f14a1","order":4,"progress_status":"completed","dependent_files":"examples/poexcel/Excel转PDF.py,office/api/excel.py","gmt_create":"2025-11-26T20:52:27.4990924+08:00","gmt_modified":"2025-11-26T21:30:06.9285768+08:00","raw_data":"WikiEncrypted:8x3JSVErdDUDs2nXur+vXYodySI7v21EqjfYoZxjkSA44PUJgC5ZxjYzDrsAuUFONqg9wFVWPQ8S55K8Vd5ZKwkaBj8qibTIwYo8JHOypZBQvUMnE+m0tioVhsuUY2/4xLAxO/AaxZGr+kairtU+x/GGLpZsq7r7aN3UWJcmg9mt/FZysyDGGTMfLZxg2o8QWKLzX4ek6qoe1J66YNRZJ4Kg4TieQ1wM5XMWY02an4e3h4tW1b355SZ3naDsSY6gDn+kpNqEaJ2svtC+15LwwaYi84jnh1vKuc9LDPvWGj5bJe1+wD47inqyofI9ixS/4KT2mRZ6uICE5l84wWtsmi8/ys0p2vIXiJB8c/hFvFD9efRZOdGrx9z/t1KcP9BL4oyJkCd7FHuBOKk/7xMPVESSupvdaE+3g8T8v27z0B3YFOhBZEaLwDEplPbCtcyb4/I9Rsr9Wgz6EiWxA+BSvIEyR7jiKYfzkTXsCunUTM5zLo+PBthTu5+2/aku3kv+8kcsU/UoPvieCfUDP7etPQgoAbRDJPldi4GhEENW46H8NlLLyhjwpl3SfYQntdlqVQ4e6DRE5fAYuoxITYBlbGI8t3VznyVQCtT+dbwYWmeIaegO8Y3T6PyEmG2rICSjpVQQLr4b8E/cxKQvaAigozUbpjVu3JwT9xvWP2oxfN34F2N+cQFunabQzJ/nrtnwQfyqPX4byLDhP7ykbMFQLdKMkANdKuBHXZqPegkjuXYmr3r2sJco/mNA8T8PJZEfzmn6OzU1IFHjfIt2BLcy0EY90ZVgkvvO7iCjLTcXXzSAIM4xM80lkn6F09rWjtKBIB53LB1c/s9J00mX9NyhH/C/S1GjfockTn+xsSGunc99fLR94MIiSj+vb9LF1wr92+DghOJtTr3kRIqlysXhi1h+eGPc9M+qOc1rd/Jd9TtvwcPqAQ3RsazrQ3BJhqJoLFJxmds1mkAjMLAtXjUy3A==","layer_level":2},{"id":"3b746c52-edb9-45be-99b3-389c0e49005f","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"文本转词云","description":"text-to-wordcloud","prompt":"详细描述poimage.txt2wordcloud函数的功能与调用方式,说明其如何将纯文本自动生成可视化词云图像。介绍词频统计、布局生成、颜色映射和字体渲染的核心流程,基于wordcloud库的集成机制。演示如何自定义词云形状、背景色、字体和停用词列表。提供结合NLP工具(如jieba分词)进行中文文本预处理的最佳实践。展示该功能在舆情分析、报告生成中的直观表达优势。","parent_id":"e11e3a92-fe01-4716-8371-3f718d2870ee","order":4,"progress_status":"completed","dependent_files":"examples/poimage/文本转词云.py","gmt_create":"2025-11-26T20:52:46.6711546+08:00","gmt_modified":"2025-11-26T21:30:14.5349726+08:00","raw_data":"WikiEncrypted:FFPvH6fuTdNO6tSZRuIpzcoYQmcQfqukzn9U6pQ9gYbdEYtSlVbK0pcp/UP/VUJFa5nVirtee8stKHTrPcH7hkAHYPcsoOJZ696pf9rXbAuXuUdzOVMCcgMgaDfsLnGCHCgvaQh9unBsgUUU7eCKil1ahhJQxy/m2XhJYW1KGc1w9WI8m7gDRLlKU9/qQxw+FNO/6tyXVZgMgmoP0TNicaBt0D7j3e8iOBbCIps4CVH7GRsmqwZ4rqlF5nvg25FF0DQ+sAzYPHuBO55RZw9hatZ21qqFZH0pApn9+E+jXlsge7bkUjRtMZtSprlL++O0+34qRw9PPIUvLjckdwrf5arLUioD/psOpH3m0T2vewQ+NoEKLu7psLLxS+yeSGvVR6t6Zb+NHMdbLWYTeSS2eezBGw7VH4Zwquu4HeZelY55fau/lL9NGwdGNLOb3sUPoopmhmwyk6cewLqBSWb31R5BpSZQuIGUN58K44WSnvSdySHIX0EdAAIwq7wgcTjiG+umGlzahcuLZjjRxOS7c9XE5KFvnbWwHNqTiEi4iFkTLBmkPR88h6LYZszjrMkxUjWlr1cKontrIXwAQppCn5Xmif5kRXDdUi3mdli5vzicG4+IxWOwN7uP/yO+rqtlGN9JcZ40Cwlrc16nS6RzUC6ujEVeAZeCLGwtjd9onpWTL6SFXZGIokRkOd9vVRWhHF8+9fiJ18enh6wNkfINvZvIWWLHIKjf65xNNfIU045Zouxog6dQVe4Fki+wjbNB/3Jt2k0uCItXrwp2kofgN6xfGa2X0quS6DZfqTFLrZD/CrqpFZf+fzo8jKQDazDnxvQM5iXLnLLYrh7ziV9fcyVwyprYDQwiHfDE6r8mOhSQ6/CsCwXA9qToPc+iQ+devWn30BrhmtHq8YkD7FhTi7Qs1d0Alt5tiBJI9MxQNf2aV2Cb2SiMWihizQyhUVZX","layer_level":2},{"id":"ad170c9d-4638-40af-883f-06492e44ff38","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"群发消息","description":"wechat-group-messaging","prompt":"详细说明group_send函数的群组消息分发机制,包括联系人列表加载、批量发送策略及发送状态追踪。结合'批量加好友.py'和'定时群发.py'示例,构建完整的营销自动化流程。揭示该功能如何避免被微信识别为垃圾信息发送行为,建议合理控制群发频率和内容个性化程度。提供联系人数据源(如Excel)的集成方法,实现动态消息模板填充。","parent_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","order":4,"progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/009-批量加好友.py,examples/PyOfficeRobot/010-定时群发.py","gmt_create":"2025-11-26T20:53:29.3900673+08:00","gmt_modified":"2025-11-26T21:44:10.7337782+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tKXNKdLZP/0RNXxGmQAAcSSrGb+Lt9OtLA1lE9h2wLVI6AQI+cm8yI5H9PURBknxLImI1N3Kc1/uovAc/AxbF3C/FKzGrele7AEiRVvrA6xzjZOiELHwOoD9wXz1Qcj6lmjpV+RASqUZpPkcfqvzuMZwPDwHDqnKP37WJ/pi2Y2ZibFMYCnA7qMTZqbKOrIYr6BMl8VY0oaqVDgY5JAi8DKySz6/M/xMFJgaakivozMS3tBIhQMD+kYtsS6o9CuIgWRUIDrEav2dfRIea2mNy63KrhdCb5IGgfsQpWGYuYTkttwmHahsljtt4vp9ulZsIrq3URYzClMOO7sJZsJoXl3JEjAxDCKIhmsWtOGlW2kDUAnNrECAgEdscLz120uPNP3V9MZ30CBDzSZuD2MOC/h0v087sDoAmVU154PjYm5Bde/j8WptzXQgiqwCexs3/mTL5jzen4IhqvS4I5msZ1JsWGGgRzXAplUrSd9OVDJEvOj7jHrer/goLdVDu5SyLmdFlRpaV2CFeYDu8P9mmhsQliMky0P6o2OsCrpo24iKCQL1bgiW20VU0wGAMzhFprUJ4XhWLitfsm1HSmtd84tEPgA+SLXtnmDabd77U9x4Z1/WKOAwZnc6QIKf3Hpg1A9IQThuzmMEEvbsG1L1OCyddxh5qhTDjxRmuWEugC5SKge1H173yk3GH+coKbklj5VKeeScWXCVvnWPgKDvWtF0TQgFko6DT8TVcny+gAeEUxpt1cTh75GqepH/gt0ebc0O+VuttzQbvquSqK/gE7660t4PgDy4yU8sovyOx6Sw83pD9ZopDtJdQ/umv15TePpu9hLFsbAZDmw9LYDxKTzNz5fd+viHKhpNJwTo+BG25tJ0i/OXf5uGhesYOB6Nfm1Ph2T7SOoJnDAvBN0UBFk1EcaPZerPHzhs+P6Dekkei3QY3R4KyUdA5zjycPaDkwdk8NTu87HKfbzmVnOoTd1WRvcnfWucvZ7zAvcYPZBdILIxy6eAtPYdq/oaUdBd3jJPm44WGnkai/EQ4HavmR8=","layer_level":3},{"id":"bf12cfdb-30f2-4b0d-bc87-c1bd097570ef","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"图形用户界面","description":"gui-interface","prompt":"编写关于python-office图形用户界面(GUI)的文档,介绍其作为降低技术门槛的重要组成部分。说明gui/qtpy目录下的GUI实现基于QtPy框架,提供version1、version2等多个迭代版本。重点描述version2中使用Fluent Design风格的现代化界面,包括其组件结构(如main_window.py、各种interface.py)和国际化支持(i18n)。解释GUI如何封装复杂的代码逻辑,使用户能通过点击操作完成自动化任务。指导用户如何运行demo.py来体验GUI功能,并概述GUI当前支持的功能范围。讨论GUI与核心API的集成方式,以及未来发展方向。","order":5,"progress_status":"completed","dependent_files":"gui/qtpy/,gui/qtpy/version2/gallery/demo.py","gmt_create":"2025-11-26T20:50:26.6696322+08:00","gmt_modified":"2025-11-26T20:56:41.9715501+08:00","raw_data":"WikiEncrypted:7L7SSUtpALuJ1PGG1aUhF3UyvllXtKpmrty2ZUztCHYeAjB0bMSMF4gu1UUxJPN8ascDcmUbXHvORC3fj6TAfPBekKNUo8kVAsLRa/ReIsbhhNi4KKnUOhnHv390vPZyWdNFjdPoG92XQ0dEsDjss9KQb1L6SwGgU0cbnbA6VDBcHB5PLKJGKnSdPp6GFVI71Jr/KB9D+780l5f1kn+eetdtCfghWexIUXKEod6tfTH4bxiMS0lm2PbbOmgrrgGAJapn5TOE0YRaiKuYWABEmNeVPOvwRY9Co/cC0Pf/sICXeCRU6xcQgcW+izsis9ALaoU6apHUi1HHP2lZuoYJRWBhGjjZ4RsFBj6/AOhD8Kz2EwM12hZ8fl4bhocGiqwJPWrP2oG6jn/OOoRn6YVcKIK/LQLQN/txOle36op9QM9uOfOnGkmy2EPTegbw+DEeGzH4RE4pA1b/nKud+voYTDgUodwueUgNLfxWdiPYoH41n86EDUkUQzb+J5fWODAYXT06YuWv6FSRLZ3MNkkf2xc5RvJmx2UAkpVPvM3SIEjvCf95FQtNNEBP1LNyCgx/Sh/L9kf7nweEuSmj4tTlGgLic3ryBLMzOqULUuLgTHX4IVtVhS58X+k+IILGBrPz5Y0PPubcE2NM8SeajGI2uteM+xmYiRsCW1RQ4c/f+xnfFzfgu9Yg0wNZKFlIjleCpH8mGsiaPii0OEH+XfTZaBY7eYRs8RYDj2RCyAOjZacP/05ZPmGNryYrCl5AhHU3MKqZdmf3bUuQ7qSXGqEsY8UMuZQznIw7SOrjyk+Jj1Loz8oRl2JX0EsfSGHpyLWCEuSLcWVbJ3f+17S8IPySaflgM4dwetZGe3A1ayKFSorXb84MsffK9pn/OOq2XcfhvahufGig3MS61rhqyLH8Ikpt2+dRD3y/2zZe66nURnw+HyzjQUK9znrJwK76KFvF7sQpZR0fmKtF9XL+YGEVmtGyG2ZjXlVIgHMmymjHWOYP/jWAeeTogKihRmlF4hUtoN0mgnOZ5zKU6Qot8/OjghCDPEKIaHw1NsDbpBDW3c0LXVLO+NqN2ESUcJQbjViDTUcx0lXS0yGMCQ2C1C/UeDBxzTt5EI8/U+wcOaSC35Cl4bzYKLrkRNDYHUmbw7611cvm7F1QYEjDPx/9yNhhzbtqOKVFWi2TEoNaJkoaLgrTDuU9jWgf70SvCGxxfPsZvTCOdPinoyWYZH81nN5HSINS8hnJBkoYIG0+OS67llx0Wv+N8E4yrrLVxtirt7lKFxMcqqWIKlFHOWGN457g1vq7GLkdHewHH1gt1dz5WJ5XKNgQoet9qK1XzBGwx4O5rRx5H2m2yFXRrCr3IMlm8S+sUOxKVTOaeN/OpswKOt6BXbu8MFO+Ei4ONTCiNeWlmzM7GXEAnIpsIGZ/hra+Dg=="},{"id":"67a694bf-f5d8-4fa9-bdf0-3b334e207470","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"AI集成","description":"ai-integration","prompt":"构建AI集成功能的综合文档,展示python-office与外部AI服务的对接能力。重点说明web.py中封装的HTTP客户端如何支持与ChatGPT等大模型的交互,结合chat_chatgpt.py示例演示对话流程构建。介绍pospider/网页转电子书.py实现的智能抓取与内容重构功能。阐述weather_service.py等工具类服务如何集成第三方API提供增值功能。涵盖API密钥管理、请求频率控制、响应缓存等最佳实践,帮助开发者安全高效地集成AI能力。","parent_id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","order":5,"progress_status":"completed","dependent_files":"office/api/web.py,examples/PyOfficeRobot/chat_chatgpt.py,examples/pospider/网页转电子书.py,office/lib/tools/weather_service.py","gmt_create":"2025-11-26T20:50:56.4206033+08:00","gmt_modified":"2025-11-26T21:07:33.4588066+08:00","raw_data":"WikiEncrypted:cziBIEQqiXGL3msY0WwrljD7FmiTTtz2XhrrJYKSVvHH21cTXO0Bf2Koc7/AC+5SYs22ZKUW5q3NKkFpHOtU0jjeR4uj0G3xOqe0tJcJdSVMaZwgo+dTTfz009EaezD3IsI+noKu8ht1Up0VKwOfq5OaA/cuAZweTuAhf+QQd0WjIaiyzc6UAiMDqMRVd5m4CrnPsyZHwrfme47GjVOh4X4XPdbAmnjrijR3Y41PC8mWiDfY09TgmcLYjbM2LkV65EnkscRoxNzwSSVOGb2qmW4xDAbwhP9cvUSRJIdjsnlib8sCo5yPV5SzIQ4Vg/o96tXwpiFC3o88er8CDcyGeNlHYkhXM8tucGl2liZp+yj3PLYvZgnz8+t2quGgwk/TBEFQ2Bn2MpgjC/5pG3Um5HYGIKWShk30LpOG8DH9Jh4TpBWg6vFjRavTlNPJhTR7KJr9eciz7A8rTyRnVOqXxNLRbb86andNTJSCwaejFITSblc/LqZ6Wcf/HeQe6LWNmYdy2zjrxLU+QkD20cDxNkAOQ0H+BX3/XAkPgZmqaXCL/VqHfutMImeC89KCDw3qXL0N4vjnLA5mACPuo/3uDH2oRG99JoMK9Zx77tcRPfXHUYpFwut4BB7MmrohDRoz9WUf9jMu2TNb4RF7pnw2Oqep/8TahQM/eOMGskORsM1EbdCoKnfVKY3BtaM1NQr4kg8QKb2d1Iz3uMYlpVLEm/9QeCSrahaMd3x6y3Kq4S7QdwGuHcL3Ao6XWPY6EY72uLDsLdFna6g0Tf2nx14SD31ol2Hph/zfztYclPn7E5fFb/ZsvppBLD0Rk3S0yINZB9d2AVXrHoWkJyU09UerGfHBDIFoofF+Cs0etHowgG5VZH8R7ASybJ9jtvRSy8gyPDLyJmchAJ+iD/LfWUdat09O3PcXUZQLDzMMxlykttA4HA2nMQotGg+sMrzKG2P8W9LP8VAlxo9U3ZAjhUtGM34gwMJ4+m5Tg2GvzlxDlUNCHhY0s5ZFgE5muSgAvV4p6d9B0xozI38/+Ryh/VFWSWucYMxg/V7qUqG6v521D+Dx/diK0lzQzGWjKkf4ezaB/I4VaiphJy/BGy2SIKAZTmGnjLNvfBgbnQe8gjSWbMnqlXha0TvyVCUPoBiIJ6fQy7XdgaUtSp7DS8SP4GA66cULZuhxD5jx4DR2ubbN3ZBXmGJpml2q7zVm2vr318MjKDAXD8a6x6E2SWqUhzBKywE2QCu9fX2Y2FAD30DPIixJTnvGQwefS+6DIuW9Us0XA39N3ytmCMz+OolDHoTEKg==","layer_level":1},{"id":"bcb8ef1b-e3de-448c-8982-1cbfff71fea0","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Markdown处理API","description":"api-reference-markdown","prompt":"编写Markdown处理API文档,针对office.api.markdown模块。详细说明convert_excel_to_markdown等函数的使用方法,解释参数如excel_file、sheet_name、output_file、include_index等。提供将Excel表格数据转换为Markdown格式文本的示例。如果模块包含其他Markdown解析或生成功能,也应详细记录。解释转换过程中的数据映射逻辑和格式化选项。说明该功能如何通过`office.__init__.py`暴露,使用户能够使用`office.markdown`进行调用,满足文档生成的自动化需求。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":5,"progress_status":"completed","dependent_files":"office/api/markdown.py","gmt_create":"2025-11-26T20:51:18.1849227+08:00","gmt_modified":"2025-11-26T21:07:40.2654246+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg1bAq5PpM+pV4jyBnmf34kBrZfptR8qHQiTNizB8GzPPczViU6KmZHg1JBX9AD8UDfNnFZFpCT0BRcSAC7lMLXwkvcqRofqBXBJXmLtT+6M4fUBpS1TJqWb/pyImZQAWGHnJmv10YLcJvwdSBwwijXaQdt3O/79bEV1V2idgkeKx8J7noZO8cR6miX2K3cH5fz5+E+pPTgOWw4pmEk9JHjVVPyGW4U7AIT/qmjiQAX9s/YcYp+b7Kz2R/aOMJiVXB02jTHF29pdiy9nNZ7Wby4yOFqeSuues//b7L+YVat+zbKqwY4IRU5gQN/YasnlF7WAlAV5XVWesIMoEgSZMMYYjBkFyhkgP0AWdJcxwMAoNsxjQzUbcAMdDGUeu5v5LjjSzmOnVGv79lYsljIKGg5FPzlUy3d4DHqeWHcR5z7QrcKaXM3aTY9zgqDz1+q+XGPXNfhEdPTdCJLW2PNJwEYTHpPg2eXygUqMPUGqCgStjBLp4EDIYkpaNy+7JY2a+h6qAJIbQfVwpE0bQKgFDLCvh3FBz1BAITmTiU1KjxAdALeGAsL9AAWY3pvgfoLnsk/H4Ot7tR4bS+qlTCdq1CMRxW6sNsjTKaHOSboJFrlYng6Frkb1tdSedlluyQul2JJ5i9EGowjbmaz7o/fEHe58709Hvb5Eec0e61jyrKZqFYUV85OOTNfiCQolAddmqOvvATbPkt3CGoLpBbf1xO0pXCjEvt2s4qcQoj6IqTvPpgb5JREdxfdGeVeuXDk9dFLe0Kf1QZ312CgXZuPqecS6ZLnm3YAgn0fQ5QwhOqcTFviB2oohAJEg3ECOsmLXpqTuYshNIysHvV3LL0GLg+xrxXZXHfJ0RNXDesmHCa0rzDiQeIJhj8EibTdeg1S00csQqs2NaONJ4O4TINKgtvvmSXzXYxVfYI3SJWAKIAZ3YuQ7GTucTEYCaxhFoVGPUwwOTfzLjTyP51mApkmnHfMNICPg3Vx8fglof8Mfwi8UB1nJGM5+f096LwUQQmT1Ejow0Tk4dz5evKfZN+CLJGSRU4CrDLHZw+T7tNnw5i7EQOQCSVqQ4lCurorTb+A6QZQ==","layer_level":1},{"id":"ce5c236b-6e80-4e88-9851-f74b758bea43","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"邮件自动化示例","description":"email-automation-examples","prompt":"详细说明邮件发送示例的实现机制,包括SMTP协议配置、邮件内容构建(文本、HTML、附件)、收件人列表管理。解释如何安全存储邮箱凭证(如使用环境变量),处理发送频率限制和垃圾邮件过滤。提供实际应用场景如批量通知、报告分发的代码模板,并演示如何集成日志记录以追踪发送状态。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","order":5,"progress_status":"completed","dependent_files":"examples/poemail/发送邮件.py","gmt_create":"2025-11-26T20:51:26.2362933+08:00","gmt_modified":"2025-11-26T21:07:53.1370287+08:00","raw_data":"WikiEncrypted:/tgmwByRb9hMFGCVx/eV9+B3Ww5jOU0IUPUpR+975YaXE/pE/w5k8wevClI4xXn2dPsexHTDBOoXDTWLusRy7kVvhNSu4WRbWpZfZdgMBc4rEc0ONMbnDJQtGjrUrmUuRs3VD85t7JAeeEgdnYnJ6VK5pDep+M3ClFZUT+Hcb3VfqgrjgtlUyIcNv+9m91mhDjLLI0gO/R5v7ddMPRuQstYc0/xE8DZKoiDVk6JXF6EsvoAiDvTSZD7DNfSAVoJ4KHa+dBeGlRDwQSCklDmNLo8nLxaC8JuvgA/6BPK8jKIbrgUFKmUNiOET2aSC4MB9BMYKQ/zrP8sHeUaKSOvYMgD2ECqrGWqXqlMQaUOWUdmAUPE0/eAqRtXkOUglY/1RFmCyebHZruZoypfdD00lXPcp7syipd/PBTYLyfOQc4gdbmCHlVI6zvDADR2FTPgDwR2+V73jBkhQe1bM7KBTgHNZGcKpC/A9x3PSZRxpLKE/tgab6WDkfDRN4vMiqaOWfkI/NZav5syzm2NUoKwg9bPGVVH/BfqI8eMVNtWkailF0j+YBZ9pU91DjtiG3v28eT6RlAT+Dwrx/1abes958m5NykzNj4J9Xsvxa0u7lqSIR7umLDQrB+bXVinww16/F1zwIkCTsLS6EMMSZGeWfbwn++eBr8l14+Dk1sERzY8R9ukhhsyyNoLpj0QEXhVeEExEWl9koFGTwEc4UrlaKQmsakfWuWwjAz+zASctSP1s4PJ5LsAA0AjRx3u+oPLsrknZBK3CYY9KGZA5IOhuP3wIiEoQYikAKtZrBH8Kv6AiBKCVVFI04qO1A/TfiviVg7kKNaAvoTvLqQ8Z7w1gfQ==","layer_level":1},{"id":"322e3ca5-edc6-4ffe-b09a-323c82be022f","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"消息接收","description":"wechat-message-reception","prompt":"深入解析receive_message函数的消息监听与持久化存储机制,说明如何将指定联系人的聊天记录实时写入txt文件。结合'收集群消息.py'示例,展示群聊监控与数据采集的应用场景。基于'test_wechat.py'中的测试代码,验证接收功能的稳定性。强调该功能对系统后台运行的要求,指导用户配置长期监听任务。提醒注意隐私合规性,避免非法收集他人聊天信息。","parent_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","order":5,"progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/007-收集群消息.py,tests/test_code/test_wechat.py","gmt_create":"2025-11-26T20:53:29.3900673+08:00","gmt_modified":"2025-11-26T21:44:40.5363018+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tCeokS4VtrOTDIAN8JOsLye6dUauvskjshCxG4OSMHvHSxFOFozx1PlIg9ZrHr7c/VuJJst7PiMAGzrhQ0p6hKJPyPuMz10J0jK+l98hfwcCABhcU/EmH1+8pnxtsiHGgZouojNsE46lgUYKESP/qfqDlWJ+9PTEDg5Op7CSi44VHS5OwEBDpiW3MfsoWyrqSbFMMbUcvOyGlm4WeuKYfxQh1Ieu/dJUdcs3EBX5fqwh4fyGSxcKqg1pEmQNJd3m0+qdj53VvwawSFTfR+PgYzSJEnZ0Q4r8oc09an/ti/qsXkqphp0B7nq1OpcOwJ3bVxFxo49cenlSUKVO6O5TTlQiY7KzNwkJX1lDSzhGog+tGkkLIZdflcZhCddHHhbBDBowqSA8ceFPGQN6dbrVTND91APThgFyVPnbUzmkK4qrunbeZSu4lGHFJZ1XQzyRo8DmKTWtXPlO5crb+lhqUppTkf/NfsONyrioQ6yidP7MeLP92+WMy66XbCmGHjeOuA2+ZcM8pJsLW4EsjGPgARovhS758zCNtqzvuqr8lWFhCyNNUw89yP07kj+1AzZ+OD+HeNcG8hSqz18TnZ8rK20LeiBi9N2Zg1kXKD9DGk2Ofrh8nL0k/w/B2NJt9R5wKM4EOS/M0p3xdJfg+E4L+KRFTXGE2fvA2wkcnNEciFHIAIb7R+vQX2UbQRj9qSTtGw2jS0OGYlCV+f4YCIYFCo7XVdVAHvOyAo6X1+dzChGSQb2HjgCEFXOByxm5GJhtTo/I74OZQs6bJWOXtjyhY4X9H+5d9Hfk99UFA0gENBjamTdtB9KruBz3bnZGPvSU7v9DtGz0GKokKQbHkAdSZyy6By4QvKLkLjZDgnH1Rk2RZa7Q+jMTi/gNs87xa6AmgK8vZy3ncnhXVjy0XJxY+DuAeWKirNzfB3NhdzNc7GIK3Vri/6gIBdZjALaU+VasKdC/PR8MEYxpOYv02XO0GfOQQef9NghGpzaiAVEl9Bz3gDdYFFnbgBkFlMsYrvDvmOnKeyoICN3tF2eF3MNZlyYhFnpB+ys6IG81AcZOolEC","layer_level":3},{"id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"示例大全","description":"examples-gallery","prompt":"开发一个全面的示例库文档,系统化地整理和展示examples/目录下的所有示例脚本。将示例按功能领域分类(如微信自动化、Excel处理、PDF操作、AI应用等),并为每个示例提供清晰的标题、功能描述、代码片段和使用说明。强调这些示例的实用性,它们不仅是学习工具,也可作为生产脚本的起点。解释示例文件的命名约定(如001-发一条信息.py)和组织结构(如PyOfficeRobot/、poexcel/)。包含如何修改和运行这些脚本的指导,以及如何将多个示例组合以解决更复杂的问题。此文档应作为用户寻找特定任务解决方案的首选参考。","order":6,"progress_status":"completed","dependent_files":"examples/,examples/readme.md","gmt_create":"2025-11-26T20:50:26.6716341+08:00","gmt_modified":"2025-11-26T20:57:31.1621251+08:00","raw_data":"WikiEncrypted:VDiDZJYWRQTud/QhSweUbSqFQ8SKVA1lEThhoch3oKG0m/BQMJkM2SQpYxs1MX+FLoYuWsMIXzserbcrisT54drDDrvwNpD6hbm0qcVFBPDJHobCzxtQSOR2qkrI9KRp6X1DsKDvxIww0spsEA24fRR+VH/R1xShyGlxfAaSvPvppadHq5VsUnxEIVxhGxWgVuhEMc1Mt7wtKGhOLR2tvMRj4+P+zlRGzk+UpCnDJMRA0LNafiu/pBU1v9XcHTcJfREKm32T3YP7txb8ZtF+iA/pLKyhRXgw5yjLPvTGPw6Y5PHiYzOSX42/v77Nob0r77AQsTRUck7m/r1R9SClDmBM+0HakY0TlBr0r+97RcBRivlcUgIJzHXLCwIeYilw9gVhPvlrlgPcYpJqPDNC9wk5zevaSTIKwUs5OIKXwffB8LMyq2cvcuQ9edhgCunXeRD4eBMAPXAtdUNtpcyyf0oYAPghd3u+L5m4owUkoKceg3Ivl1fL1gppL2kWP7Xer/InZfgUKH8GLuoy/JUjd43XG4ZuTo4fd6mcHliDsLEXvZhbEfmhAwn5KywjB8XU3k+oXN/RK+lbu9X0Y3pr1D4s289fzGCe7pV4OvHPa6EPojyfFeSmUzRqncVb69y2gxXjd6R2a9mKXZV46HRwkZmbE+tS+zZ19kByq3/GcbRe0ETh84MsLhlTDYI1UISPSztSzBfDbIfAHnuU7PnSKzqoy0LQGXJKoEFOg6gUYJVhy2fnDgSMf6kNTm5VzUh4vHYtK4DZyzRDeDdmnMQdXPUJx7Cnal5ISCCEXL5nB4knrqQV0QQESQTTYjsxOnSsyTslWb6//PaKGbzF+SP2j5UqfXkMc7RrbtuATx/8ihkF3Vvx7fUKQAk2A58zrwd5nPUUloThXOdeIn0moz6LJ7WV1x+suTusRBjVlTyBD7mW32038DwBbkGx8Ddo5rcq1uqVZHkkQgJWYOa8sFO/ZaU8yjpi2feL3HcMbPLpGtu1EgWgvhwvOCcRC6yshPf3VDTID5YAwhxwgginkuAO3nKQnpzqYpum+JlI21sxvsYGP5BBEeonRYgTIp35eN/GlVUNSN7X++iZCBb2oDwjboxiz+vBux7bSc2G9jfCCZ8WVIn4fLMRXoRXXDR/BTZ6YZ31o2hHQqRoM5rAsxtO08UR2ja9Hyg/qPIZNI/CU7CWD1SHQOeBkKyBKBq+mCAWhIHoBfq+7eydiCwPREV69SLZXnv+tiubafdw9aTtRAoCap+8ZJ9Vu4UY5s93FSHrBoGoFNg6YfEfiFsmsT2nMnHnuxjAvdm7++rnc9/GvKOpKOqPD2yHRKM0zsYJb+1p821X+YfDwhomODIdN9mInI5osnWdywZsAU+y+A9D9si3w5KpbHjpA2f8oH4CnaD1"},{"id":"4d76ddd6-c314-4f7b-b09a-50112a6fe67e","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"OCR识别API","description":"api-reference-ocr","prompt":"创建OCR识别API的权威文档,聚焦于office.api.ocr模块。详细记录recognize_bank_card、general_ocr等函数的接口。解释参数如image_path、api_key、secret_key、detect_direction等。提供识别银行卡信息和通用文字的调用示例,展示如何获取结构化数据。说明该模块如何集成百度AI或腾讯云OCR等第三方服务,指导用户配置API密钥。讨论识别准确率的影响因素和最佳实践(如图片质量要求)。明确`office.ocr`命名空间的构建方式,确保开发者能正确调用这些AI能力。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":6,"progress_status":"completed","dependent_files":"office/api/ocr.py","gmt_create":"2025-11-26T20:51:18.1854505+08:00","gmt_modified":"2025-11-26T21:09:03.3406516+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg2K/RAPh208NsXgioWguNgunM9WpkVOoCZ3mbLySIy70ySH4hJcVaCNJEGImosvK6KbDHWmq8fPHA+a3ru37hiY7DecDi0KhSBJjaum5qpQnbTKm480ooybUjW6NHXaH8Jl7KgWGxsLaOdPpSt1EKXpkY20PSyLwKRztVjKteoFt0e4xxnpz7Ry4h54TZlydNCPvaAtD7/6Fyt3uTfLMVIk2QVm50/6ghYYor/XV3oeDzeM9fKMeHnsd+mGoFcYES/xXMYgri32zR+ElY1sam9/tqLIYs+cyyQaEJ8xXTYdYRy4/lrFJjex1SUE+kBwzWSsjTwYx56YXwnJnr/OrhEzk6rEEpYilVP3ToDrPPe9KtC5koAh+b/iWi1xzXafQPedyHH2hdoOBw3EB/G/wkwAsziabDKEdG4Wr/1pzOdqQeoHmMKnfkyofYsCpR4swVBo/h1ULTbAl9K4E4UrLRy8gh/XBufSP3bkvHgIWTSlCPB6cf7LhaqRvEI7k+L9S0oJZ/erP1dkpsmKjxoGFNUpJDTtNTTbVvnt7jenycskItWnOPAZqFmIep65f5WLI1krDHb89ovacBOPhMG2mVE93xUfjRNAssW8BjFY+1tmGwD0FStvGBVPnf8QEc4sv+nG144oKQ9aNTXSr4gvgaaKOX9je6QfX860xcfwhFE2EAXyv5n3bXRwItajrPHV8brziOHL2RjgSIpASrs61mfVqSa0CRho9aWhkMRFBMoSt160e+wz5iSHRkaM9IJyNSNgQxkpSxyWB4SU9RwWF7Yok6PIGeU96ES+f3BP8PYn+B2JAtYKI7f1GA8lo7Q/YTMapMQHeptZ1tEciuXtyM3jG42aed/uS7dPbElKbyF7+A+6KX2hccU9oDf7d1vgjZnhieqim9gtWfMoZ49tUaDNtKTcCn5mAXCK0RB3ugYLixCnX4FnIsBAiVJADr0rv25Tej3Fi+fhwVZ7H+kjiLe9sOrkVxl3WN/ALiOipD9EtI+iCRIDbdWmr9JdpqHMB/ZzELSBrl9W7qMWugNBUJTp8qvG29AbzjmKZFNYalKJYkAo6f7Yxw2k+6cpvcO8WsUKEl9cg98WdquX6zQPpL08=","layer_level":1},{"id":"9f1b3695-d545-4923-baac-47827243ec01","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"AI集成示例","description":"ai-integration-examples","prompt":"深入解析AI相关功能示例,包括OCR文字识别(银行卡、通用文本)、文本处理(古诗拼音标注)、网页内容提取与电子书生成、数据可视化(词云生成)等智能应用。说明如何调用百度AIP、腾讯云等第三方API,处理认证、配额和响应解析。提供预处理和后处理技巧以提升识别准确率,并展示如何将AI能力嵌入到常规办公流程中,如自动提取发票信息或生成报告摘要。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","order":6,"progress_status":"completed","dependent_files":"examples/poocr/识别银行卡.py,examples/poocr/通用文字识别.py,examples/pohang/1、给古诗配拼音.py,examples/pydatav/数据可视化-文章转图云.py,examples/pospider/网页转电子书.py","gmt_create":"2025-11-26T20:51:26.2362933+08:00","gmt_modified":"2025-11-26T21:08:49.5760347+08:00","raw_data":"WikiEncrypted:cziBIEQqiXGL3msY0Wwrln1iV2YT4qrXfrF4Y1+CSPrtxZbt6wyieLpSIih6HM3Uv6NsTQjIOcM5f4f/DEi2MSUJVsW6kpWAqfaVs8JNf3gNrrGPVQIbY7CS5BEiLvcs7uasn7xFzqK56/dGtrFY30VUd89sm5JK/19eWcBR5D8pedm1ZXSqEMewrtKQGPhYVGvxBxJpiMEm87Et4ou5HjtG0Lx9Di82Pi+lkoDNwKW/3nhk6jzxZW+8NGdZanynwF+2GRqYUQx8GrwMHkrGHE7Baq0NT4R8NeUekf9BbhglsKYjWrtnXzi3EMoTwpP8m8Fp/hB9CzJfpi9ifX2Lsp5CMRzuKH0x0qIVhCDqCdIeirqGwAVebjvkss/U+kmE7+/r6dsMsxv6bzMeRytCkSR/40+4I+dilsDfMkKIyOW+EIsX9izMqagxJ5k6qfn+df6/R/7IglRXkb+rQf2pbkVE5icU+PYP6CbI/kmjnaGozZqlMSO1EoUO7xn0ejA8ePiP0ShS+SqhlmseTPWNUjTfNZ4O7H78lR1ZhaqxFsrDB/NdYkTeKZrgalk3MF7WmrkmBaL5aAY8qo505jT3EuV7khNatSuX2GaZ+bl67+iRDAp9TeR4lLFSxP/ySDg2Ou4JVRKVUkwGKPkOP7m1C808HYW9IGCe57OnEMqYxU+nJe6+Fv0YAJjLwaDsj98+N+ZGzQxUGw+LvWBZN/+/rXDFVDbP+Bj6aV6J1aYy0+iey5ucnUu6w1sIB5XXeHr2ajL6HYY5MPhT/mL0rAr2WPLOUJRk027NvRtuxCmHH0JheMey0xBATXGTlCOs8nWVB3f4Nrw9k6CyRdoDs4ZP6DM/1E0vPnD1H8CKiB3OpWcWjjXbvM+AdybAZdpJVtwDEJbDBiAH2+w/uRemytFFOXZ8RqlcWEox8w/wiXY4STkAKwXpLbeG03qhqCe3TezlZgs4Ep/cuFHotFxmyhbgIAGoroUkLwZpTIO3CDe3VXi/NyNX/DVgWTqyXQ/vpqlyjbJSjq5IKSk1aWb5uhhqBS8pGouixdYCEzSN2bMLGAWBokL6srkXZcsaKgHsAHAIADu2t7BR8uglb0BiV4c2lhB95MHgr/aXUA5ybuqsCFPrzdxop/iUi1tEdvpPGm+nrguI63T3fyBgB9zmsOTBvlMDvYopBrwNQH5ItzQBaQayoWEMH9v88tRQQAPqOUDVbYbrBHWtqVNRIh5OxoIUIRD+MlCOLvFVsfoXjIouaZuR3WJhFZOp9IgeJDFvG0JDWcQn6+UbJX1pZd21dGGmdQ==","layer_level":1},{"id":"4485e258-4ad2-4a6a-9db5-63ddb137abb0","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"智能聊天机器人","description":"wechat-intelligent-chat","prompt":"全面介绍chat_robot函数与AI模型(如ChatGPT)的集成方式,说明如何将用户输入转发至AI服务并返回智能化回复。结合'chat_chatgpt.py'和'智能聊天.py'示例,搭建端到端的对话机器人系统。分析自然语言理解、上下文保持、响应延迟等关键技术挑战。提供API密钥安全管理、对话历史存储、敏感词过滤等生产环境部署建议。","parent_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","order":6,"progress_status":"completed","dependent_files":"office/api/wechat.py,examples/PyOfficeRobot/011-chat_chatgpt.py,examples/PyOfficeRobot/012、智能聊天.py","gmt_create":"2025-11-26T20:53:29.3912168+08:00","gmt_modified":"2025-11-26T21:45:03.8704908+08:00","raw_data":"WikiEncrypted:uYF7bOP7L/BtP5gchzW/tJD4rP7x4pSsfJnb2FbG/UqwQI/pq4zHvz0DNPYoYHaAz+5J1tWihjXM14q8PZsyN3N4BjQKm1hpt6Mck5HypuZhXw22X/UUbsYcJftLnmTvtgYopeV9T6nkR1sjywAMV6QerXKQG8Hnccp8OYqqsSTBwtVm//alnaSVbkpPBkgySGzBgTkeCdgSlmltug1DXT2tdxUg5VCBZDxY+FlLbgudhfsVJSgaUrlCQiBSdQjTzfQvi8XMWgONSiJE3NYUXKu/QlsYeshuhzeL08lbc8U2PtaaIIDQvP7gTbKGAVAiMDFzKdHl04v5l49DHZR7ZweTpxprh7uNXjD+tP6m/9E6VWfAiFyBVOqnoaXRPxm8kDsh3Hvlfn1ADneS1CWzE7tCutQPytnUtwNFDTdvQrDC4RSIVrhMX4r20PTK+9NLwDjwFDfm6Qs6V/92tfL+GfA3gUhtbudACnYC99fUld+GTUhWD8EqdugTJe05CCL3S0MlUtbIlQdhZ4L4gnyH9AY5EmtObf+nNPTrr6Cg2mmR98Gb2DckGaBiw+2pgs+48c45suIwYXu4T5nuDZVFZ26SGQgaqfKL8lI8YQiLIYzh5HK1iheWWBRO11r6PQeehqq1TGWfJsgDHJscE17uKW0dKi+vjC8INTUpnZ/auNqZGB4FClTxW/fz1rrF71V76BK48BTAajlb/P2YgzPEXEO2/dP8p+A7oxSglKxFRzPDuFYIE+hHZcFYnrTRuEWXvFSsIGsHfKLuc8VPXm5SdCm0XNy74b0dp7YTyIpDsL7Fo6NeUW6S7k7NDGLpbzxl5JgrIPCPHO1FeFet2Z54WxBdZvHHqiBsXPzCPiHtLaUQn8eH0lTAHgXoFEtQqJSH2+5mzSEc0s6Jo/mtSA+uBRKEFtKI/X4U2OxUGIAhdwvXM+tT+dUx7f/tKbHJGUcn8AwVbOkyTwsq1GMqBovjJ4U8MUtKR+aiEx+0lBYt1fftaHN56X9zHRkdmynYxDnEBbsejLjQfsBuFVOyyyMs+w==","layer_level":3},{"id":"db86b095-d70d-4d05-856a-7ea1236da44f","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"贡献指南","description":"contribution-guide","prompt":"撰写详细的贡献者指南,鼓励社区参与并规范代码贡献流程。基于README.md中的'添砖加瓦'章节,明确说明贡献政策:所有贡献者必须在contributors/目录下以自己的GitHub用户名创建独立文件夹,并将代码提交至此,严禁修改他人代码或核心模块。解释这种设计的意图——保护主干代码稳定性的同时,鼓励创新和实验。提供从fork仓库、创建分支、提交PR到最终合并的完整步骤。说明如何报告bug(通过atomgit、Gitee、GitHub的issue系统)和提出新功能建议。强调社区行为准则和代码质量期望,确保贡献过程顺畅高效。","order":7,"progress_status":"completed","dependent_files":"README.md,contributors/","gmt_create":"2025-11-26T20:50:26.6722773+08:00","gmt_modified":"2025-11-26T20:57:48.1593411+08:00","raw_data":"WikiEncrypted:BxDZrTl5aGXx1MaECOB3Neyk0qJpNGfyo5P4oy8YSOOJ7KO8Krt0w/QnZtYrQ6ghjcjAIq8HmCLW4xESwmQJYiw+u+TDgL1tzX4ib62RUcU3wR9l9f1nAYynTxbp9AY8Uk7SxMPjvoAWWXZXje3Bd8SVHLZi4v6jO7Ygacetc3vkWd+OZxP586jGWKazfyb9tkTnvxFLRA0F3AkhIoa1Hdb9hL/Hy5saGPJ1YkMes26QYZD4Z75FK+7CpL5rKVF3qjwHUZeRcbBUvYVQujankVHGvAPe5WEJ7/M8jS49KQw4llTYpXGH9szcKBEATstFFFQ/n5p9B34hm47xIVWWZsdQ9OyooTFnC98QZTNW2vSGblvbslqcGlMr3YY57uuFKBJzhfVzgcxczcT9HPej8M9L3pTA1uAzbcwvCfFURRxSCny6FDL8gU3CfpATkp5LWiwvzuwyqcvkEBdfdAy6P+/CICU9+yWmu+E0FowYNbnKzPn1UWgrJ4xYt/Zq0abVGe2coiORyNydgsNdFrXKPvlVQgqN7o9QzDt7UDbBhGIif9PVGNn9v7AAH87SB6BvuHNb5x7kPwaR3/9q6zhuQdFxzB0Mmb2owUicAtfBOtIqH8k1+wNUice9jl2vePtdE0c08s+IoeI+CjpxMOfDazW0IsWpGR4jbYVYOyQ5i5KemcQ/H6B8gKqX+gDCqjdmz8j1wRZA72RYZC3bSAajCf0XspzQv0uCDdFxa1fZo4o5LnT2X3U1Oyog07KFXqmZLTYIDrBMPaJIc0a82tbEYJRfSSdf2YHfUNSvpnwLeqyr5jwHRxwfwKtF+AdQGRGZ5Hsv4bGncOwVwDw7o2YkEBBCOoBT6BME3TRiJcfbz82xW48S9eIjXaLRmdjqCyJy27Rh0I7OcBElOZpqnkNGe1d/TCK1TKdtr1I/7Q87B4mgL1MPOaJxuLF+umJgqyyU8Fz+gy40V4kogE2RSn7nZSL2ExolM6lcVloSJqBqzzK5Z/C4E3BIJJiF3/Bg4CfJqiBnQfRqCCOvlXgzE/YfHmsfX2t0b1qULcdctO9MDhPAE0NBTosMMbq453wwL8tuVqKJ1xmjR6ZHYoDbQxgoaOz48xqT1vewTV5ohe8Nw3v0zRqIMl5QrhnxgDyCDs7iEQ402/797luKuRBh60iDkZPIWxNGApNBlFPIyOC0xx7NKf8NuvgK5dHu1i1c0e9TNo34XSRIlR9YA47or0tfDTbucgKRDeVyDIUUMiF4fIcude9pDtLvmVT1L6RjaLWleWtym3m66PX9H1gbWNlnIEl+bXijMraoodEG2k4yxLnlaQY/JqfsFGB0K78atUa6cgBgfBEO2/Yax3awDsSKf6loLREHyGhr3zQIMNF6Pgc="},{"id":"c82bae8a-62cc-4cb7-aeeb-aeec7b7871eb","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PDF处理API","description":"api-reference-pdf","prompt":"开发详尽的PDF处理API文档,涵盖office.api.pdf模块的全部功能。详细说明add_watermark、encrypt、decrypt、merge、convert_to_pdf、convert_to_word、convert_to_images、txt_to_pdf等函数。解释参数如pdf_file、watermark_file、password、output_file、page_range等。提供PDF加水印、加密解密、合并文件、转换为Word/图片/TXT等操作的实用示例。阐述内部使用的PyPDF2、pdfplumber等库的工作机制。对于转换功能,说明格式兼容性和可能的样式丢失。确保文档清晰地展示`office.pdf`作为PDF操作中心的集成路径。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":7,"progress_status":"completed","dependent_files":"office/api/pdf.py","gmt_create":"2025-11-26T20:51:18.1860161+08:00","gmt_modified":"2025-11-26T21:09:05.7577205+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSgxS5CjhPqqtvx2HuqVvtW67yrfL15LHV+C1Zvvjzco++kSckZ/5oqbgHADmUg9PFF1YU1H19VjME34s5V/sWGWvRqqA0C9JQmkyYl2Wv2YdUFod2aGgfhmarSznsnAEhRfsobbfDRXQV6pD3tk87qOJ3vajbbhSR0MnjEjyjRIZSvS6+mHho+7L+CBdICKi8EwsBILwRCkB2CJeZya28mMjOrVCNH83M21nIgzABHE3WkWpFRVigGPjgIYIGAAwemmz3jHWwoxoPGuzvE3wCgEBDFeLr6B0ldGr03tgwCje59xUhD/ebMdkCXuPh5UXlyJelyeOcdO9xJ4q9PvFAC+LryKfvXQnWqXWbrefY7TMTHYPE2xrn8Vu2l6mQEoS4DPH5qwZfq9n58p9JTcQhSRCz6P4Qj8teNJKvd38MikBivowJhCTZHHvBtOLsfSRVyXb5tN5uFs9LXEhm58HJLtgPFvMCHkW4nwJF1RRjxMh6IXfWapiXbqziWzMVbBa08P/1ekNgWcT3EYAQUiYsNEgkZNnIA0I0vAlck2XkaBcXfoVpfu6WnuAi498SP3rf6+Ob5rVQL461N2UsWGUKEwL4ZLvrtmpHZWLru//wGfyvkkym+Ix422a3tH3QNnw/smja6XtUzzm4wFHI7Er4CmglNQRydGXMwlztDCsyzGLL3YP85wRlXuTpvUpHv+/55vXm9yqF+1x2eOOr0wJV0/zgubu4+H9PYuCemtOtHgAzDat8mTDXxjm2J+hEiMuOb46E7XlbqlCGhzwXL2z7NAHeICmjYFkc4/bZAGXIof12FhbBBtxtub/LFHt7Dx22nnk+h8CaotUkjiQPbPrpfn07m5/smu3mJZ6QE5E5DnWGY+VEaQaJVlvhi6hsysVjCL0Nuoi0MnIwZWrnTG1BC6yNKMiXFTS53AhxF7MHQnIF2DeriJWPznaJhlD5MeClxqbVH8NC5kLVd1I8zUayVhl1+JRSLyehRznH5Ehk4e0JEiC04iK3AHYQU7dhhDLghmQ8BaHAbGFSbYa+nRROUJWas5KCoWESLtvJBOPxRUoTF1IoMM9lf9sRUAHb3X43jTD5dXN0Pn487/7/oUbgYimA0dVQQjlslWMI8ue2g59ccUllBbjMq4CIWc7NGPlE3qzQQfkssi16E0FMy/jHcVUsqUJ2xZlyOiAchyhkomZ5","layer_level":1},{"id":"cfcef6c2-c01b-4433-b4f2-7dd7f9f0c339","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"其他工具示例","description":"other-tools-examples","prompt":"汇总并介绍其余未归类的实用工具示例,涵盖PPT处理(合并、转图片/PDF)、金融计算、进度条显示、机器人对话、视频标注、Markdown转换等多样化功能。为每个工具提供简明的功能说明和使用场景,如‘mark2video’可用于视频内容标记分析,‘Excel转Markdown’适用于文档生成。说明这些工具如何通过模块化设计实现即插即用,并指导用户如何扩展功能。","parent_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","order":7,"progress_status":"completed","dependent_files":"examples/pofinance/1、单次做T.py,examples/poprogress/simple.py,examples/porobot/chat.py,examples/poruiming/测试API功能演示.py,examples/potools/工具类功能演示.py,examples/povideo/mark2video.py,examples/pomarkdown/Excel转Markdown.py,examples/poppt/merge4ppt.py,examples/poppt/ppt2img.py,examples/poppt/ppt2pdf.py","gmt_create":"2025-11-26T20:51:26.2368073+08:00","gmt_modified":"2025-11-26T21:09:28.060952+08:00","raw_data":"WikiEncrypted:lbwfWS16jAQJFGo91lrzpTwHcZsv+7NeIkhufldZb7/se3X+q6Sg9IHu9CV6bXnjfJ776dJoZsx8DWRWG+OyFnZL/d3msBHtUOJlRAScLPmBOK4CVBegBPlVn6HBKTWKw3tudb5PhoAUesm+vCubeFd5452qoHOspaJ8FjMRVPaYWfD/AkT2CEK/qpFRLDrN2HI0E7HzqA39QgN2o3B1FY2EFhc+MSoM+qK7jcGz47kk0LRbLwhNsH9ywi/QfzSv8ughHZeXLtg6qJ2RdNcikFrU/+9sUqfqNA2NXXE1uw26WyaM1cWqSZBsZU4bdo6HFL+gzFVtCxgNuGxxaPnnhZrerTNgfMsp76C61+jAk6eSjbVZn7Q3UQfgMcWb2EuHFwginpyEHnKtCTIAtIQp9Abhcn+n26vjv+nAdBzvg/dPNW1XI9HZKsZeYjm2ha3AQBCs/WD9en2RXOeUQwIImkCV15U2rCYaOd0x+pViMC1UKyH53ZVHOCpmiZ27DEvxFoyDlqXDfI0uexJy1bAtqfRZbXrXl/p5FFatQ4IwhK67PfUVGtMHGR8WwlQiIQum/L5BGBmGL+cS3qcSM34jMQb6pZl7OnHGhGQAEt2BCrPwzJ34SbuYCx9noMH0MZaV+MR7LYP6THK37Wu1ri9rtf8ANVtKN3goE9pe137C2gZjffZDKNJlTldGNhoqgIPn6W+FLrlOO5Tm7Dd6kA0Txi3oPxlCeF/AfEwTIlMkVsSgsuQrQ1SdLvztaB5IPPpNU0OR9Uy915SwDX2hKxnjF7mrDxiP41/MEbjFW5I68jYEchUK3eKKpN70oI0PSM8RpadJSrlodx6Dm8TJaWE+aHT5RxN4Ck2bGhZtSV3pLWaepJIPfCTfaRtt/FwSrnOBm/HRkWr1d4LlBlmuczyQqcc0yv2EQo9TTFsLW1zu6SRGCtTW1yFwR4goGMhUtd13Cf2qw7/IcEvLi4pBiqNvDiSyvxELu/QoZqrIt6Z6oO6de7iZvgVeprWR/pOmqWL1raQhWlsNc0pAfUWdRqrb+aNiVtRCX5I9BH9jNE6FqzCA37iBenpurgYmsjwLKOIayALDeVrU9I6CUGttt9xm6Jz39/AqtrG//RBA7rxNIMt1OiDV+nv3/KUN27ujCOa3SJ2K/pe2SXygUHCITMZ2HkAruTK658+15sD1lSOC67ysFTvOjkAKqckYyPQXBd3r6d8tXjpndzoHkI+ZYqzmsMQHNsKEhB/u/BhRfnfMdTcX6CHadLSgn8xNMqy1X1gFzqZ1Go5lfVGyP9WJizRIlT++3ar5EBPK0lgNIC0kWCk144eoK/9BkJjYPlMky3rQlYWTcOwYogLp9axyg5jH0Qu/PbOLne/qJL+ti/wJShd7Gv2yuqaOMVXi09n+nYth","layer_level":1},{"id":"e5fce0a4-780a-46e7-b1f2-59ac1978ad41","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"常见问题与故障排除","description":"troubleshooting","prompt":"编制一份实用的故障排除指南,解决用户在使用python-office时最常见的问题。收集并解答典型问题,如安装失败(依赖缺失、网络错误)、功能调用报错(模块未找到、参数错误)、微信自动化登录问题、OCR识别失败等。利用tests/目录中的测试用例作为诊断参考,解释如何通过运行测试来验证安装完整性。深入探讨compatibility.py的作用,说明它如何检查Python环境兼容性,并指导用户如何解读和解决兼容性警告。提供调试技巧,如启用详细日志、检查文件路径权限等。此文档应作为用户遇到问题时的首要求助资源。","order":8,"progress_status":"completed","dependent_files":"README.md,tests/,office/compatibility.py","gmt_create":"2025-11-26T20:50:26.6735025+08:00","gmt_modified":"2025-11-26T20:58:50.7088856+08:00","raw_data":"WikiEncrypted:CaKOW8OSSWs4aEYk06Hu0hGGy7zXJE5t3XZJK+9x87XSsdx+86RSzwy2mMCxHMv30lsaPhYExcsSnTaf2hDXf3lKEMl+nXbib9lVkNykOA26RQOQKozMvk3N7b6EP2nsvUIp6i7d8ZHAQCehFeTydOtVbzH2I4VDkmkoAyqHdQelUSV0a502DZ7ZOoNuFDtahLhChWasul7oRalz+2FqGNeayuWI1ULpGYqubSKxLoapfby7Fsl0K3irbedlcIPOV0+vwltQSYKxKj1PPx6riLJMX6qcbRYps79JFzLOYMspRzPW7D9DGZv5H5ZR0LMoksWEmdA5VauGd5rVGYx+91RmGWC0NKCU14Z+YLeMzte04j+M3svdrrF8O1E84YPj83B0Q87W9nH58jDn4y4lgFk612gU78QM8S9h9y+j8k5Ei74DUDmaZT/8glnIV17//sHOifQQAbIF+gP2q5R/Zqy1pK41KPYkkBelKOOAava5q4ESvuiIRdmkBvPB2CTNrhgeQRs0NgPGrMWGB0LrxQEdIMFeJB9hyjsm0vIEgy5vbHPW7VH+FdwdvuCuM3IbCLdO3RLpiFo/LqrkVqzclnMg2NK3S3L4H5nzR1sap0WNy+rVbu2RVxxSzS0ZUrMWb1pupBDlTuiSaldwq5mdaWCLsAX/X8BgDfxdJI6AkHVQVm9Jb1ak6ZaaGslHWXDilEZq1xvwWGyCyIc9Kb4PRVn46fWzCshTpCgh24ute8hRuz5DpGjmnjXPhJuI2i7E5iDxk1B5UAI56GkE9Iva/PB/1AcEwqdJCWyGT7fHh92lNGTczE74rJThWvrqz/ErLB9uZq6u3gAiDn3oQA6ffb4dc2JLh3kXxTFhHW0g1AuWCItVvz7S7ahXCa2pR8TxhjEzEvthyafYr0v1ZEUTfTOOLx+jNp8Pet//TbrtW/yU48EzKw5KOi82WnZ3JeocWQv6CA7Od2X+D9cOgkYOoPFT1QpfyEIs9ujnCV4KOGYgCuX5/CTYgBSp2/G/JSqhbEix4U0pRpmdyI21Abk4VoGe5kATILLiHwconCKX7x6jvmlGRRtgV38p59XX65KzTzT1Rh3BCOkhofcCw3zgzmcPhSAJRpDwXal18iqrrv7grDHxUBBnQ9wr3o7x0I4V8iLonxpz2ADxiXPBEr1jxsv6TRo4hB/k1EM4ExkWnCllVPOdrmXn7HM8g0JG83ThUnbWFj6+lO5eo2R48Dc9o3wN2MIC62pi3MrAEJbDqOmgBI4Ps5k++bKyWrZE4uu+9ZTNWmpy9+3Vmwyip7Vn7bOQhRcz7T9qYF91lPISonxW5Jv8/pZWT1KZBjY6406S4KSDzyoZpibMZR9lUPZpAtWNHlX3bgglbVAYJt02oBX9uiecCZjV/z+TfT/G7Bt8uKAgWpfZ3Zp3aanWKhmAh+ElkCnLMUHlV9xqCnYhRBqLxFC0V6wPxHdOHfiDb9Eh"},{"id":"04c5be2b-9968-4157-a7ad-56d42d9f196b","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"PPT处理API","description":"api-reference-ppt","prompt":"编写PPT处理API文档,针对office.api.ppt模块。详细描述merge_ppt、convert_to_pdf、convert_to_images等函数。解释参数如input_files、output_file、resolution等。提供合并多个PPT文件、将PPT转换为PDF或图片序列的代码示例。说明内部如何利用python-pptx或其他库进行操作。讨论转换过程中的格式保持和图像质量设置。指导用户如何处理不同版本的PPT文件。明确该API如何通过`office.__init__.py`集成,形成`office.ppt`的调用接口。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":8,"progress_status":"completed","dependent_files":"office/api/ppt.py","gmt_create":"2025-11-26T20:51:18.1865848+08:00","gmt_modified":"2025-11-26T21:10:12.6776655+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSgwNNNdF+Qp4mUQT9GDyDfgLrC19SBmbYeXbWcdCW7s3coMxfizpXns33Jae6OGvUn9bI2CoEr+8wpeXoXXrtcnj/vAxINjJpG/IFG8GISXx3DcxG7wRDd33GyU05FtzXdXxwqqHxuFlmjVcdNGOLY4FSQNSbokWWl14H0UafgHoExuY7RP28RbJToArIqgBIa3DKVmo6iifEXkTjeNpEOBLUhZ2KVghQaDUAjSx/aLy0rv4noEkfh8H0jg3REs7IIAjlGUtaoiEs03Z+VWCsDa4Du83LvIzeBWfmUi5GDvZefo+g7+i5PXTAgZb+PhTJWtCUoZq/2lY4MGOewIWpO8MyK6kGeUhuCxhF8cDicow+vqabmmsUza6wotoRzm2qgcSPcv1VdU5W4YVL9FLC7oS8tjyaIpeCyoB6mrekPSvoEmmqNnHw9sJBwlcNURy2vZMJm5b0sqceRE/BSB+GEgasUnRoN64M3N82uRuxf5sJpwf89ge0Saz5GM4M4uDhfVG5ysjdUG+JiuP8fwfNxH8yWKZPGffsXS8p40ZJngt4zN906vv0c/+QlFy3W3M05iFOST6VZOLj2eEilUVC5Sw8RDuV7nRIhBr0UZYgAwnF9GwpV0iz6TnVn4aDBJEkr7mITapVR07mnqJFXRMX+tCwgekSpGL/qlDzAWPFNv9+H7Q3fsI6xWUmjo93vSVS9tnbG9a8s5yD6vlBidIu7zfUUi2goQobY8ELPKAaf8KSF0FvZFQz99q9WxkrxGC7ipH9IPGRsmMSav9IqQIpYaCLscuTuksKnAwCUaoLssGerN8wEwz5ZIxWAodEkA8u0tntIorl62yibsX8XG+jxMBQA/x4l/Fpr6/bdW9wuIQXPxwCVyY4oLlZr4pLf1FE9h4u3F6QWZQg2pBKSXHejak8GFZcRQfypI/zXE+PDFSCuSxGV2T0NHQNyr9yfWeNltSkQESi7j/456TTB1d6Z3nNFXuMWDG4bRbFgDNav3hGhIw/2bv6/qzRouHTCwvzKQ==","layer_level":1},{"id":"db0e7859-1b0a-4dc6-a982-6fe61233c98a","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"工具类API","description":"api-reference-tools","prompt":"创建工具类API文档,涵盖office.api.tools模块提供的各种实用功能。详细说明generate_wifi_qrcode、get_weather、lottery_draw等函数。解释参数如ssid、password、city、count等。提供生成WiFi连接二维码、查询城市天气、执行随机抽奖的调用示例。解释每个工具函数的实现逻辑和外部依赖(如天气API)。说明这些便捷工具如何被聚合到`office.tools`命名空间下,体现库的实用性和扩展性。确保文档内容准确反映源码实现。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":9,"progress_status":"completed","dependent_files":"office/api/tools.py","gmt_create":"2025-11-26T20:51:18.1865848+08:00","gmt_modified":"2025-11-26T21:10:15.2663528+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg7Hd+xqPvY29dX6gv0KZWZte/JIt0Yei45tgmtuZGmRKkQKSypja2v4hneq67ZO2C0Ri0yJbYdyecYbxH+XvOW4H1QDBPO9fCYja6hAojVASIBnUPkunjPvFjwwwfqj2uw4CXPh+EZL8cCrMvVPnNKDcxXcwgOJztmPyfyIiTaA+HJ02bZdQ0z863u3kz2X/w+2POJXAQxKgqKlbv7We0FkrjDJqCaxDBXP2tV2Vy7nNPSCIbWu24t07Uhqpb9rdgVjNSAQQe7GY9j8K32oEgICaWVUQbCv0on/4ZDat/4HAvD/WKuJ14YZus4BNgFWuQ5RhgIZMy/HsRxaf4A1P/HfoPPVEu9au65amMdEn3GdxpeTdT74zCcQcfMZ1bjMs0ReSGwMwp8CYlwyEVIenc0LzCg3bedDVmm5ozK/4e7PisNwPmR3I/r+SXR5YfJ/p+ZmIZvkf4N+egN89Ccalpr0rh195UpWjssph1+zb4hQLGFcq+OjbLgx8bX/12pKVfSIGN5rbSXvDicNWl2O2pZJaUeku2rQ+zPYcuX1gOKDkd6K2JHhmtpwpcnAlOOHpkEAjULsOjNC5AMMWl6GWMK99zUKjskaWwq5ozvp2nq8+ttEYDO5aeHKg4MaPc1gd1pumLagZCrvlrxyoDxgoLx+Jqo7rZGxDwVe56AqVeUBnpOYFJpZV51MwCHqvLriMsIluPW4qhpBkzPl2IdYjBewA/MEfyR8blLXM2PcsEHDz7LETUfTCZbOvTmRQbpu6yxDXsorq2z933QcrtcoV6XgwpYydHv6/Oj+XnGXBTfp9qo23OODIs0Fh4UlmUUYk/KhuGyinWUujLU/avyL9nWGdZxw5o0wOY/vDHvs7M7avzcIbK75J53jW9PEITLR4m6cS9KdqblWMsFydU3ZN031R9gKDrph9e6oHRMpdWviy3jVVvVThpvfQb79NeG3ppyIU17PuUUbt1KVS9ni9w9XCfBgsTm95VtQsiGunpsLuPLgV5U7hEx9GoK+wnt8lQS/MKERvK1Xou3/bZQQjJpHxVNXWqGvbLCp/CX+Qq1kV","layer_level":1},{"id":"a17e5f32-89eb-4810-bda0-aa771a039370","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"视频处理API","description":"api-reference-video","prompt":"开发视频处理API文档,针对office.api.video模块。详细说明mark_video、get_video_duration等函数的功能。解释参数如input_video、output_video、mark_text、position、font、size、color等。提供为视频添加文字水印和获取视频时长的完整示例。说明内部使用的视频处理库(如moviepy或opencv-python)和处理流程。讨论水印的动态效果和性能影响。指导用户如何调整水印的显示时长和位置。确保文档清晰地展示`office.video`功能的集成方式和使用场景。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":10,"progress_status":"completed","dependent_files":"office/api/video.py","gmt_create":"2025-11-26T20:51:18.1871238+08:00","gmt_modified":"2025-11-26T21:10:46.772101+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg/40D+1Ic1/5Q/SfghWjyJW6Zef/trxQtP1pn7K0X0gYPJZeq7UFcDhIxoTD80LLEhD3JiYxF7HCaymBBTdfYBq9Z476JoUbBiuIG5MRQjjBxsNnB32Datx4H6M6rHVYcHV7wM+ksEGItihUZb+dzwYp/vpEpDzTUxZIe+U/zMEQkbfwVA9WJKfY5YOvVQ73ME4maH5aVI+v+Z2jjzpD0mj6bgu2ZeGOkxWh7koztKi4Tv19VW6D3TTNt9PTU0Tu0xA6spSOUhuahddHDPzMxGMobIkKrTOITPwq7I0WZfVUV07D/Kf5+26nlo8mBl4G/5wzR+/K104YHDSayB+c4Ba4GDgRs2WgcCxeJxnp0p5tHlNQ0g3XGWVSIjWw73Up6YbgOo+5OO62I3IkZCZ3Jm1qKUuGzhLlg6TaU6EdbNvdTFqCxCzoHYBNAkH5qYHW73KW2i/tx75wGmaCGbT5cIfuGHAO3uR5s5TJZzQRMgxn0FEsWQI0vIrDAFiNk9w8Jca8lMLmPne/Y0k/GCdzkixEGSjwBMDwB7WwpOm8memAy84OSm+DkZ0c2e71nkACyCEvI20gzsf4tFWsoIHGXuo1GC0aQ/XioHOBCkhQ2EFzr9Jz+GpFbAeKr0Eke3FjQylLu5X8n4/h5g1Wxa4gD8W+P4ixhc3FCjCv6XKs8yBE5Gm2lSWzVPaIwxpTdnRVZAAb4BjMM71riHYHce0CvWK2pK6+zw58q46GkOHo7pkaC46p0piWWdlLIp1b73lDt6H623QNVVlVJjYG1sv3/HQ/e1as1ZlefpGVvuQD//UcW/0c3ghkqxsSCsnLqT5hR7tqe23dYkwb+cEiGZhesQPoYVyWP9tdTrT7IUFv0hVBOdgXFqD2G76WFIBudAQZKvdT7t4+AgQiCmkQzZGU0V3ksLYuZWSVBUQVQiODZrq0pfKGn0/U/eARnFgmdriPAMhYOWHF9lIufYlWWhHjc8Qe4SY+dmrQ2pIF8VrscRAtxlhrqRCTFFGJQg4BpKCPQBFkPIm5qvhnllcyPn4Da0OU3w9QI+2aeBMd8rPes9/5","layer_level":1},{"id":"19e30cd0-3bb9-49d5-8a0c-1b8556e67cb4","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"网页交互API","description":"api-reference-web","prompt":"编写网页交互API文档,聚焦于office.api.web模块。详细描述web_spider、convert_webpage_to_ebook等函数。解释参数如url、output_file、format、headers等。提供爬取网页内容并将其转换为电子书(如EPUB、PDF)的调用示例。说明网络请求的处理、内容解析和格式转换的流程。讨论反爬虫策略的应对和用户代理设置。强调合法合规地使用网络爬虫。说明该功能如何通过`office.web`暴露给用户,支持自动化信息收集场景。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":11,"progress_status":"completed","dependent_files":"office/api/web.py","gmt_create":"2025-11-26T20:51:18.1871238+08:00","gmt_modified":"2025-11-26T21:11:24.4581217+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg3ty5QqpxmpcQLvU5mifMVglyI7JuAaX+wMZuGGOe0nZo9Fjl+Lzrrn7e/7qBvmiSHUQvS+Ht/I1+Ul1wTgBjYmxTltbMtldeTYR3f+85yfLfXEBzBjboUcZtagZO4LUQIjqETvAGyr5GiFq51mgnn21xv0WH2z5v1Az5mPu7+6K8x0HXUY1y5yE/esI8f6zAgUXpM/MMgIS4FS9jxSWsHfJaKFeB80QJFac5tQ5X/hM/dPuqEsiVINTtHA1yjZSU+w82M89nCZnyR3Z8hCW1x5PA1AnCtmHCgQ5i2XJOFv26rMRHBiqjQCZywLxjJir1G2Buoo3WfPVFzXAwM2umVzUNhYtUxyVu+w9S7q3JqSpViisaZFl35Bey0Gvi4IfP0eS1Kmj5hBLAxkuoBVhvfRlZ4mrEoEMFVUvMd2zAAd2Lcdfk1oNciTbUFl9cNx/hQ3SvEqg26jwD5r4vw4YBgRbg+qYRhCg4VmhtQpElWZjGLTMSq8s5ak2ILp8xHF7avsUeQb4lMoNPzeiria//NrINaqHSfyOrNxDOX+Lhk+RZbGiFcS032W3j+QgsDKk0bZZXfgukIszYOVDec6spCc3nyar/xHlhtW4JiAw02rU4Nbp/QqEsUdoZUeWtCUaCxnJKOFtZBJynmSBEVSilx9hQg+KRcuGqSahWqvF6LcsvOgM1KZFlA1Ic/0MBmAs1yZieuifslmmLJ6OUi8p1723lTKwGyuha9WKRl/yW7zwT75CmoigyGO0yCy1EytnN8pRhFk8L/TqfDIst8z5HHtAbpnLZCCnx2936m88mwwV9J5DT8dGbxolLUBXrqHM83wr1x/5nL9n8MAD1KJOhttXoZXaZfn6X7+6pySSYV22iO5z2/4eQJ8XSG1icQ1s/N9K0Eh5Bxz/heRtk6RN3bEUL0yF3KE37wJ9ey1/BIlNZ1Yezj8NFImq6Q9xWbzPc7C2qWaY9IL7JyTfbQKnIm+c6RVFMLsoT0BJpoKhPmdYjayg3ERkij7YMxsfcTLick3qlP8LYgrlKtPlxVLPCTw=","layer_level":1},{"id":"4fecf486-4899-4338-aa49-52ef0550acb1","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"微信机器人API","description":"api-reference-wechat","prompt":"创建微信机器人API的深度文档,涵盖office.api.wechat模块。详细说明send_message、send_file、receive_message、auto_reply、add_friends、send_timed_message等核心函数。解释参数如to_user、message、file_path、keyword、reply、time等。提供自动发送消息/文件、基于关键词回复、定时群发、批量加好友等高级功能的完整代码示例。阐述底层如何通过itchat或类似库与微信Web协议交互。讨论登录机制(二维码扫描)、会话管理和消息监听的实现。明确`office.wechat`作为自动化入口的集成方式,并提醒用户注意微信的使用条款和账号安全。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":12,"progress_status":"completed","dependent_files":"office/api/wechat.py","gmt_create":"2025-11-26T20:51:18.1882341+08:00","gmt_modified":"2025-11-26T21:11:19.1792815+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSg2DLWdFvl1IdxmmkMnOzXfohnutZcYOZKs3eTnGougIaL9k70j2UnSQYwYT01GEPKEz8pJKhvPNiCpd2/RfjbC3hrnjbFZ7PTu6bjXvTf2GPyMLojRw45H6rIqacRgX3oX06/RJbNBUU5cVScISzikWCKmyuTa02FsR5fVOzdZDuWj0smSwN1D/QYGZhnka5ehlA1mDGBp2fZePe9jGAK5gpwKAogHu2vPMMDuoDQT2N/3OCu3dpVvfL0LISdcMPcNabwc/+HivvMO5Wkh61LyKX+xB+30X7Q9Sf9sdfTUed/ltwidOVZJOX3RucjW1xK62WmndHr6W3nSXS8NNhElzwgiRXob8y9+spPpi20azNBJpNpLVWSNhCXVsCafIobP3nLRW5ifyrlpnTHbyFEGDQ1CDD7qnLXPBSfxZR/b3Sbh5RBMpwP+cr7fRGGjE5/WArVbFJA4ogeGcqSTdNvkx3CK4fq2GYXVCJmNrH8/En7OEb3HORUcla9s5PPtN7DLoWC/IGTh7561S4yPIcLrAc2AlHx1sCeDfCH4le/HTOwtoM98OtDVA/k0z5Bybrg8g1Wz/NPfs5c1SF8F9PjcWDKgdqJHMHRS/uDFBgpLJLuJUG42HmMHzklZ3DhdIXCd7vc4FNI9hWBluSO1iB8OTe8jlrGC4CCxI572zwwf83K5vcAPhF+0jF42IaagpBcM9Eu7hCrFeNjfFVDo29XcKOGyc4MtmgRm5jO80+dwVNfz5nFOnXNCgnwW4O+mg0+vXKxuF5Iv7ppfakObuCxZ0ulMvLOLkRLsfwuk2vAQE5ANznqG4kCGFYomcdlm+VPvBNBhzYnPoiGF+NOv9Seyk390nvFjyl/3IGOdypdZ7Xfk8y6do///w4Fp/4huKO5l0aMYSz+AIE7e7ZMzu5fnUZZkECMJxZfxbRvk9faKmyIg0CDlGIrgpKuJVsisbaKHpuKwr2dZbZnaze8/CCO8/GIH3Y5z4OrqMJxfXrkYdzFLj3uP4e8nhSO1c+CjExU+OrQWuJXSYMSmPVZM0k/WWUb9p5trpi+6udJG2Kl7L8mQAnKPnvrO/EdHyJvzA8HVFSADTrgy/nD/OrjV+OVg4Em8PoJPZGKOW642bSmEdun+8dtEl1Dp9UurXQvfr97G73Ho8mfmN0s4RgX5uJvA9Rg3JoVLPjAqvOckIbDet4cwgI2+n6sSRAAMsCQ8QuxSxZnwqtbEUqhjCheahCr1LvjExq+4I+MVin2qIOZbnO11QnpO0oW4BwFoO+un7SpoiF3GTAv5jubuabiiPQ5rJF9jy94ptlh46VWtGZ56xP","layer_level":1},{"id":"2f6f8827-9d6f-4d6a-8724-c2e34e6c1eb5","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"Word处理API","description":"api-reference-word","prompt":"开发Word处理API的全面文档,针对office.api.word模块。详细记录add_pinyin、convert_to_pdf、merge、replace_text等函数。解释参数如docx_file、output_file、text_to_replace、replacement、pinyin_font等。提供为Word文档添加汉字拼音、转换为PDF、合并多个文档以及批量替换文本的实用示例。说明内部如何利用python-docx进行文档操作和样式管理。对于拼音功能,解释其在教育场景的应用。确保文档准确反映`office.word`功能的实现细节和集成路径。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":13,"progress_status":"completed","dependent_files":"office/api/word.py","gmt_create":"2025-11-26T20:51:18.1882341+08:00","gmt_modified":"2025-11-26T21:11:58.1990779+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSgzG16YWBiHd7MDPnUBqd7+c7Fy/WsKHpNUab4lVCEpQCquKI4yhgyXxgZNRJCcTpWtjClfj+gJcdBzeL9ECmiUEk9b6KGopmjM79ujqPA/qzqFSI4cJmgmvdM/4nUp2dsH18tyJqtRpw11GZEy/e3OoAeqN9UrBjGdBLZ7ry/iANY3smJCkhiajvYkSH4Ofc1kxkDwQGwi4NMDfOWuiIz6XpnLKrx/fztMuPqhjiZmjUa4dXU4H3pjIDDqbbnY7BfY8D4GuMKtBBRFZTw6I23ZsfBxdm61o8ZtJRu06EPqqRby9mS+T+zeLVnp+CNoUdx07CwAcIymzKmnDZb+O9YaKcd55vda4ELi0u7u9PjchK7JgPozLtoqOxZb48FTSdWVpomPHDpcDDaQe+dEK79skJ4/e2TD92y2ag9ireUk1XhcgG/Tj06ro162Vv3pVMq62SGLAWDtXkFQo7h7m7zDYdgKX8TR5y9BpjdSE4tm/H9o/T1/Z4bxapc0s1AjdTVJAir83/S/3kNwaYgI/Pd+Mku3fJ2FA4TTlPqeBP6BuuuMcI4ICohbOTICE5f2GPwg6+YrrGZpe2ZUExB42CLCJjt6O1AWm+1v8HCVFtG7Z0Dx30Rzk9dlcKxGnhSLvCy7K0HswrGMhHosJOZPiKL7CAEXrDKeIVUNpPN/IEwOkHK+mUvJ7+yTa5mgFfspcS9VFMUFrjwBAH65Tx825mJeYWbM5r8gy7Zla3soM8yMUwIy2zSPlZfeG/VUh1lP+582dwEkSya9nwBIKEU1Ur2nqe1QGsywVmqYNV/7OxPbGSlCfwVMBkXPENrg4XJaUB9h2DQn9jHAZ/6d8gJii78WtQsDJmckbx6zh13Jlo9cn69Zkc24yHYKEO5yY+lIQvRRgRcTZTN5Kbx4PfyJmBemy7DCJWTKudx6gk7ZuL3UUaHxl/fHzXJMoWUUk6PaGmaXqunJkR09oeTyPf0J9wXalq6O0jKmPE2WWS3+njB3lZsUaH1daXt450sHdvIzKr9kbkTHvQ7fZSw0sQi34A/nUBQyxD7ITmNnPAHxXQ63nV","layer_level":1},{"id":"137f485c-c959-468d-9603-f47b3b6673f3","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"测试API (试验性)","description":"api-reference-test-api","prompt":"编写测试API的文档,专门针对office.api.testApi.ruiming模块。明确标注此为试验性(beta)功能,可能不稳定或在未来版本中变更。详细说明模块中提供的测试函数或类,解释其设计目的(如用于内部测试、新功能原型)。提供调用示例,并强调不建议在生产环境中使用。说明该模块的路径`office.api.testApi`未被常规`office/__init__.py`导出,用户需通过特殊方式导入,以此区分稳定API和开发中API。记录其与核心功能的潜在关联或测试用例。","parent_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","order":14,"progress_status":"completed","dependent_files":"office/api/testApi/ruiming.py","gmt_create":"2025-11-26T20:51:18.1882341+08:00","gmt_modified":"2025-11-26T21:12:58.7711064+08:00","raw_data":"WikiEncrypted:C34GewOyK1SlumqKiPsSgxpLdkLxAfFlC9KxSEaOS/mDTvEGlD2GHM6Tjk46xyZrOXlgPMj57nicxx+eMShucbK8n7AiseW87xpLA0n1CRtlktUjR15hubPqCq12EEg6Wh4THcFs3nEMvFcnThC1TfFpA/TEKOB5L7WClG7yOR9kz+9R4QtMs8N1mU1mZIx8QR2FL4wRi40M0wC6CH1jCbveKxPtzUUqCK3h/lfa3UX8m8ZzdfExVxBrHpYtHWo8TWe2KSUoniTjR4QB/v/dIGED+zyIAXcnn0YBrwtwMz5Ihzyd6EeMuqtdAGEn1oHePlmiCgDDHnmwCj7bkGDlcqU4cTpIiUM0wtRTbASvzEQMOj3+1ZbTgTAzfurJMnnd389Zm9FPGRR93mELj3Q88T8P6e6R/T9ypGw8NqBae9192HyTETyMFTkJBKAjP0g1Rl1mIHKa3/CScoqfI7GPRybPjXrbOAkHIGNwnF1NsEMrkQSDJaNIuJNNdUunkGJfIyqmwkf1xuKz1dderTcb2iNcOx54VQ5v4oVtKGbX2cbX2OeMhVpoogXu9izCfUbBU8n6l3mcsRIfr6yP4OYVyXeP/Dr2/IJApEV9tTrCOhKVIYSAWCH0QHDczXk7qMSCoEhW/2yDbFUylccbAaARIGihd9MFiwPMcNzo3sqW/kG3g1MeuHOgl5zC8Bl0Z4wLLlUjHWJjtUh6dtElNT6KCrzXZ5O3Eda9OXM/OKTff6gVqiwW6AVa3epbAMukj9/1zY72hSoieCMTCiWEpjknf+k9EYKNxwDJiZxjb4DuADqTnBdHjX0QyiLep+0Sj0t82vShz4GFOGnskJahf5vXJdDYYudEMh/y/v7oFhwIC/7wufyOXjhFhAKbxAvbM83ykNmFPFiWe2q0BBcc7dZqLfhUKvWzt0oQRN7Nl1M3ml3FimYfHGn7aNyQlr0y2gcEP28FjnnhBo0uAmmT7rDs8RMbqG3FAsXPFJJ83jXjlAaikL7U44Npj1ZKB1mYk6K1InYx9fa445My7BRQFy7aKu+7unvzCVnRPW3oRaCina2O08Pn5WPRi1sHe+7rNMNSxxXxY/1qNdO7aeUxnn6d3q+hH2cNY1l4CTgfOktuETXhMxW7XOH44rqVvhnmrDMs","layer_level":1}],"wiki_items":[{"catalog_id":"c9fc6984-6a2e-409b-94fd-559d9f7bf4a0","title":"安装指南","description":"installation-guide","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"ba3d12e1-1f43-4131-a6e0-1aa58263235b","gmt_create":"2025-11-26T20:55:08.3686603+08:00","gmt_modified":"2025-11-26T20:55:08.3737138+08:00"},{"catalog_id":"75cd0a91-bb97-4811-9083-3684c7ae4636","title":"快速开始","description":"getting-started","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"078d2335-50dc-406d-9f5b-f867bd9d4594","gmt_create":"2025-11-26T20:55:17.1148432+08:00","gmt_modified":"2025-11-26T20:55:17.1185826+08:00"},{"catalog_id":"0860412a-4350-4bf1-ba2b-fc95740fb0bd","title":"项目概述","description":"project-overview","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"7a67dcef-7c52-4457-a680-34698ebb7abf","gmt_create":"2025-11-26T20:55:20.400832+08:00","gmt_modified":"2025-11-26T20:55:20.4052106+08:00"},{"catalog_id":"e3ee7e3f-41d7-41df-9ab7-22a3acf7bf4b","title":"核心功能","description":"core-features","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"1d8d82c2-01e7-4ba2-b939-d15e625944e1","gmt_create":"2025-11-26T20:56:29.7220515+08:00","gmt_modified":"2025-11-26T20:56:29.7257271+08:00"},{"catalog_id":"bf12cfdb-30f2-4b0d-bc87-c1bd097570ef","title":"图形用户界面","description":"gui-interface","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"56f91293-f6b9-4d28-b5f8-49debe410087","gmt_create":"2025-11-26T20:56:41.9683474+08:00","gmt_modified":"2025-11-26T20:56:41.9715501+08:00"},{"catalog_id":"151c52bf-b028-4ce4-8b2c-7c4141670d6d","title":"示例大全","description":"examples-gallery","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"f735a428-9c4f-4cf5-89d6-a3d0bd795632","gmt_create":"2025-11-26T20:57:31.1572306+08:00","gmt_modified":"2025-11-26T20:57:31.1641373+08:00"},{"catalog_id":"b7ec58c6-6a83-4326-950a-519fc7a3c432","title":"API参考","description":"api-reference","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c659096c-e870-4a30-aedb-91afaa51e219","gmt_create":"2025-11-26T20:57:46.405483+08:00","gmt_modified":"2025-11-26T20:57:46.4098368+08:00"},{"catalog_id":"db86b095-d70d-4d05-856a-7ea1236da44f","title":"贡献指南","description":"contribution-guide","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"1861ba02-1b86-436b-85aa-8ebf7c42688c","gmt_create":"2025-11-26T20:57:48.1560487+08:00","gmt_modified":"2025-11-26T20:57:48.1593411+08:00"},{"catalog_id":"e5fce0a4-780a-46e7-b1f2-59ac1978ad41","title":"常见问题与故障排除","description":"troubleshooting","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"e7c4737c-fd44-463e-9cca-1db51e7e6487","gmt_create":"2025-11-26T20:58:50.7052145+08:00","gmt_modified":"2025-11-26T20:58:50.7088856+08:00"},{"catalog_id":"f7bcfd40-cf6d-413a-b3fa-59f8cc0f5a06","title":"文档处理","description":"document-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"74ddfab0-572c-46b6-af92-3ef1d9c5573c","gmt_create":"2025-11-26T20:59:01.7105265+08:00","gmt_modified":"2025-11-26T20:59:01.7148554+08:00"},{"catalog_id":"b38da97e-0ae0-4dc5-8bdd-d53a1218c22a","title":"GUI版本概览","description":"gui-version-overview","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c7ca23a2-0844-488a-8661-2977fcbce4e0","gmt_create":"2025-11-26T20:59:25.71678+08:00","gmt_modified":"2025-11-26T20:59:25.723623+08:00"},{"catalog_id":"e957a9d9-adcd-48e2-a36e-b2b4beae2ddf","title":"邮件API","description":"api-reference-email","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"542a7d48-66f9-4805-b91a-519eb600f3c8","gmt_create":"2025-11-26T20:59:49.9210459+08:00","gmt_modified":"2025-11-26T20:59:49.9259025+08:00"},{"catalog_id":"25cbcf29-42d4-410d-b72e-2c345cf71be5","title":"微信自动化示例","description":"wechat-automation-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"dd9929a8-8e29-4c3e-8088-a60a1af13615","gmt_create":"2025-11-26T21:00:33.4409922+08:00","gmt_modified":"2025-11-26T21:00:33.4437774+08:00"},{"catalog_id":"efdcccf6-6375-4180-abf1-f90510945ed1","title":"核心组件架构","description":"gui-core-components","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c81359c0-6bff-4c28-94fe-e050557bc920","gmt_create":"2025-11-26T21:00:46.8307345+08:00","gmt_modified":"2025-11-26T21:00:46.8352221+08:00"},{"catalog_id":"cc0f1364-c170-4040-8c52-4b79072b64f1","title":"文件管理","description":"file-management","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"349c0d56-94da-4bb1-bba8-8615086bcfd3","gmt_create":"2025-11-26T21:01:01.3009689+08:00","gmt_modified":"2025-11-26T21:01:01.304732+08:00"},{"catalog_id":"77600606-641d-45ee-b403-76dc1f223258","title":"Excel API","description":"api-reference-excel","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"9ffcbc81-fcf6-4b7b-a8ca-cc42395e2be3","gmt_create":"2025-11-26T21:01:52.4509365+08:00","gmt_modified":"2025-11-26T21:01:52.4546856+08:00"},{"catalog_id":"3aff6fd1-b9c7-4eff-b8f5-26462a3f14a1","title":"Excel处理示例","description":"excel-processing-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"f227d1b6-572f-48e9-b229-f0c199a7a12b","gmt_create":"2025-11-26T21:02:04.2855593+08:00","gmt_modified":"2025-11-26T21:02:04.29043+08:00"},{"catalog_id":"3babe136-8c6b-43de-8ea6-36bf688cc629","title":"国际化支持","description":"gui-internationalization","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"f624fe10-99a5-4b5d-af4b-ab7830b4c10f","gmt_create":"2025-11-26T21:02:30.9546732+08:00","gmt_modified":"2025-11-26T21:02:30.9603456+08:00"},{"catalog_id":"d2ac020f-81e6-411f-a866-ab1d3e411da2","title":"自动化通信","description":"automation-communication","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"a77af545-9341-4685-ae85-964d0ba1e2bc","gmt_create":"2025-11-26T21:02:40.5140008+08:00","gmt_modified":"2025-11-26T21:02:40.5175772+08:00"},{"catalog_id":"64c00342-40b1-4002-a280-6393d621ab4d","title":"文件管理API","description":"api-reference-file","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"b9479976-43d9-4248-8aa2-baea7fe52ebd","gmt_create":"2025-11-26T21:03:27.8542773+08:00","gmt_modified":"2025-11-26T21:03:27.8570005+08:00"},{"catalog_id":"5235253b-7037-4298-b76a-147a71088bbf","title":"PDF操作示例","description":"pdf-operations-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c489fee6-73c4-4e7d-92a3-9b9ff7d8f832","gmt_create":"2025-11-26T21:04:20.6336646+08:00","gmt_modified":"2025-11-26T21:04:20.6399176+08:00"},{"catalog_id":"e2f3c078-2962-4624-ac55-a7ae4ab1ba48","title":"功能映射与集成","description":"gui-feature-mapping","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"bdb13c92-a348-4dfa-8972-300c876e554a","gmt_create":"2025-11-26T21:04:23.2555078+08:00","gmt_modified":"2025-11-26T21:04:23.2581723+08:00"},{"catalog_id":"a025ee06-1178-42c6-ab66-3f654ebd24af","title":"智能识别","description":"intelligent-recognition","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"3dfa68b0-7f30-4b73-81f8-ffd6d9dd04ce","gmt_create":"2025-11-26T21:04:54.2836215+08:00","gmt_modified":"2025-11-26T21:04:54.2873853+08:00"},{"catalog_id":"290a21fb-37e8-4dec-a611-cefcb38f4e22","title":"金融工具API","description":"api-reference-finance","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"cff11294-3efc-4dbf-8833-0f1dd156a57e","gmt_create":"2025-11-26T21:05:22.1002126+08:00","gmt_modified":"2025-11-26T21:05:22.1051862+08:00"},{"catalog_id":"f058e3f9-1f62-4a61-b147-f6a1d7e86abf","title":"文件管理示例","description":"file-management-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"ecddb2e4-0daa-4608-90da-10a79e0feb62","gmt_create":"2025-11-26T21:05:36.9088907+08:00","gmt_modified":"2025-11-26T21:05:36.9178111+08:00"},{"catalog_id":"d70f8411-b612-43e4-9d1b-04300c977a54","title":"运行指南与依赖管理","description":"gui-runtime-guide","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"08df5fec-89a7-4a0f-83ae-3bec3ef20c3c","gmt_create":"2025-11-26T21:05:49.4631267+08:00","gmt_modified":"2025-11-26T21:05:49.4673412+08:00"},{"catalog_id":"f14f8d32-b1d1-4726-84ea-35edbe9520a3","title":"多媒体处理","description":"multimedia-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"4c71b51f-c6ab-41d4-8f35-0a15cb0a939e","gmt_create":"2025-11-26T21:06:41.3220753+08:00","gmt_modified":"2025-11-26T21:06:41.3267687+08:00"},{"catalog_id":"d4ea9cc2-c7ca-48d5-b39c-37c2b44830a9","title":"图像处理API","description":"api-reference-image","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"da354123-1637-4f00-a866-81d93caa95ce","gmt_create":"2025-11-26T21:06:50.0944154+08:00","gmt_modified":"2025-11-26T21:06:50.0977624+08:00"},{"catalog_id":"e11e3a92-fe01-4716-8371-3f718d2870ee","title":"图像处理示例","description":"image-processing-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"284c4a0a-1d3c-43ec-92f2-e9bb19659fd1","gmt_create":"2025-11-26T21:06:53.3961865+08:00","gmt_modified":"2025-11-26T21:06:53.4138014+08:00"},{"catalog_id":"67a694bf-f5d8-4fa9-bdf0-3b334e207470","title":"AI集成","description":"ai-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"fa7ca8f7-cd27-4744-9e3f-49126e86dba7","gmt_create":"2025-11-26T21:07:33.4559178+08:00","gmt_modified":"2025-11-26T21:07:33.4593279+08:00"},{"catalog_id":"bcb8ef1b-e3de-448c-8982-1cbfff71fea0","title":"Markdown处理API","description":"api-reference-markdown","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"40155efe-3b03-47ba-a8f9-198b3e17d5b1","gmt_create":"2025-11-26T21:07:40.2599589+08:00","gmt_modified":"2025-11-26T21:07:40.2654246+08:00"},{"catalog_id":"ce5c236b-6e80-4e88-9851-f74b758bea43","title":"邮件自动化示例","description":"email-automation-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"e6fbcc68-971a-411c-afd8-679daa6dc933","gmt_create":"2025-11-26T21:07:53.1291349+08:00","gmt_modified":"2025-11-26T21:07:53.1375895+08:00"},{"catalog_id":"9f1b3695-d545-4923-baac-47827243ec01","title":"AI集成示例","description":"ai-integration-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"ad5d0e45-2bf6-483a-933f-b63cb790ce04","gmt_create":"2025-11-26T21:08:49.5725721+08:00","gmt_modified":"2025-11-26T21:08:49.5760347+08:00"},{"catalog_id":"4d76ddd6-c314-4f7b-b09a-50112a6fe67e","title":"OCR识别API","description":"api-reference-ocr","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"2c59b87f-ecef-4e59-b37a-ca9c4feb3279","gmt_create":"2025-11-26T21:09:03.3380195+08:00","gmt_modified":"2025-11-26T21:09:03.3413442+08:00"},{"catalog_id":"c82bae8a-62cc-4cb7-aeeb-aeec7b7871eb","title":"PDF处理API","description":"api-reference-pdf","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"cc722f8f-49c2-4a6f-be4d-253f9086e8ca","gmt_create":"2025-11-26T21:09:05.7527577+08:00","gmt_modified":"2025-11-26T21:09:05.7583815+08:00"},{"catalog_id":"cfcef6c2-c01b-4433-b4f2-7dd7f9f0c339","title":"其他工具示例","description":"other-tools-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"ad28dff9-75e2-49cb-ac4c-56f70245f922","gmt_create":"2025-11-26T21:09:28.0559274+08:00","gmt_modified":"2025-11-26T21:09:28.060952+08:00"},{"catalog_id":"04c5be2b-9968-4157-a7ad-56d42d9f196b","title":"PPT处理API","description":"api-reference-ppt","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"9dcfe98e-31e4-4f55-8900-901703d569d7","gmt_create":"2025-11-26T21:10:12.6710386+08:00","gmt_modified":"2025-11-26T21:10:12.6776655+08:00"},{"catalog_id":"db0e7859-1b0a-4dc6-a982-6fe61233c98a","title":"工具类API","description":"api-reference-tools","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"4c0924af-6db3-4bef-b62e-7957fa59a8fb","gmt_create":"2025-11-26T21:10:15.2624949+08:00","gmt_modified":"2025-11-26T21:10:15.2670146+08:00"},{"catalog_id":"a17e5f32-89eb-4810-bda0-aa771a039370","title":"视频处理API","description":"api-reference-video","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"99b0e33a-3526-4eac-9dbe-fabb07369596","gmt_create":"2025-11-26T21:10:46.7670904+08:00","gmt_modified":"2025-11-26T21:10:46.772101+08:00"},{"catalog_id":"4fecf486-4899-4338-aa49-52ef0550acb1","title":"微信机器人API","description":"api-reference-wechat","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"2a37ce53-23f7-4418-aaa9-db3f44030062","gmt_create":"2025-11-26T21:11:19.1743337+08:00","gmt_modified":"2025-11-26T21:11:19.1792815+08:00"},{"catalog_id":"19e30cd0-3bb9-49d5-8a0c-1b8556e67cb4","title":"网页交互API","description":"api-reference-web","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"127e41c8-f873-4404-a905-7c8254dcd90f","gmt_create":"2025-11-26T21:11:24.45487+08:00","gmt_modified":"2025-11-26T21:11:24.4586416+08:00"},{"catalog_id":"2f6f8827-9d6f-4d6a-8724-c2e34e6c1eb5","title":"Word处理API","description":"api-reference-word","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"3c93628f-739b-4d72-8697-ad459115df79","gmt_create":"2025-11-26T21:11:58.1964326+08:00","gmt_modified":"2025-11-26T21:11:58.1990779+08:00"},{"catalog_id":"63a5de97-9650-489d-b2e8-36c46be6fccb","title":"主窗口架构","description":"gui-main-window","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"41647d8f-357d-4645-b667-d1651f365121","gmt_create":"2025-11-26T21:12:57.7434848+08:00","gmt_modified":"2025-11-26T21:12:57.7477109+08:00"},{"catalog_id":"137f485c-c959-468d-9603-f47b3b6673f3","title":"测试API (试验性)","description":"api-reference-test-api","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"daf94220-6f57-484d-867b-8387db839510","gmt_create":"2025-11-26T21:12:58.7660575+08:00","gmt_modified":"2025-11-26T21:12:58.7711064+08:00"},{"catalog_id":"e751e9d9-3ee0-40ee-b1dd-bc751c843370","title":"Version1 概述","description":"gui-version1-overview","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"1dfe4121-5d3e-44c3-8285-cfcb956ef9ef","gmt_create":"2025-11-26T21:13:11.6966361+08:00","gmt_modified":"2025-11-26T21:13:11.700266+08:00"},{"catalog_id":"d4a17f74-f33f-4367-8cdc-fc17c2168564","title":"邮件自动化","description":"email-automation","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"51e9c2f2-3dea-4422-9909-f7ffbc855032","gmt_create":"2025-11-26T21:14:11.5794904+08:00","gmt_modified":"2025-11-26T21:14:11.5935452+08:00"},{"catalog_id":"cc27c795-85ae-4b83-8279-5c1fd1f80186","title":"Excel处理","description":"excel-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c2821340-8601-49c1-8361-e9b96efa63a6","gmt_create":"2025-11-26T21:14:14.122574+08:00","gmt_modified":"2025-11-26T21:14:14.1265221+08:00"},{"catalog_id":"a4bd1c46-ef48-4bbc-80c4-8708947bde3f","title":"文档处理功能集成","description":"gui-doc-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"7202cd78-0156-4e66-b07e-19173c989ca2","gmt_create":"2025-11-26T21:14:24.5963906+08:00","gmt_modified":"2025-11-26T21:14:24.602039+08:00"},{"catalog_id":"ee1472df-2281-48d2-82ec-971b66d7dfc5","title":"基础通信功能","description":"wechat-basic-communication","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"85ca43c5-dabf-466b-a687-3518c9caacba","gmt_create":"2025-11-26T21:15:16.9617409+08:00","gmt_modified":"2025-11-26T21:15:16.9649424+08:00"},{"catalog_id":"2add2cae-512d-4dec-acf0-6cd787932142","title":"图片处理","description":"image-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"a18ba16b-48e8-4beb-88d4-666167c3d5ae","gmt_create":"2025-11-26T21:15:41.4417922+08:00","gmt_modified":"2025-11-26T21:15:41.445126+08:00"},{"catalog_id":"27d62374-4a28-4795-8159-b990f56abf80","title":"创建Excel文件","description":"excel-creation","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"aaa46704-cc2f-4250-b2a8-b97ea772c518","gmt_create":"2025-11-26T21:16:10.433456+08:00","gmt_modified":"2025-11-26T21:16:10.439055+08:00"},{"catalog_id":"a4a97fbe-2696-40c2-afcb-ee7387132362","title":"PDF安全操作","description":"pdf-security-operations","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"2910f084-d37e-467a-8290-43ad6bb67a81","gmt_create":"2025-11-26T21:16:55.0749246+08:00","gmt_modified":"2025-11-26T21:16:55.080625+08:00"},{"catalog_id":"f2cbffed-9820-4f3a-9dd6-9c0fa4f28246","title":"图片下载","description":"image-download","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"6769c917-c2ce-4da6-9ce4-08b0412eaf3c","gmt_create":"2025-11-26T21:17:10.8583514+08:00","gmt_modified":"2025-11-26T21:17:10.8627587+08:00"},{"catalog_id":"8b90388e-177e-4c76-bcf9-934b0d151316","title":"OCR文字识别示例","description":"ocr-integration-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"edd09072-fa8b-447b-b71f-f5280c94be46","gmt_create":"2025-11-26T21:17:54.2364992+08:00","gmt_modified":"2025-11-26T21:17:54.2436383+08:00"},{"catalog_id":"297b3b64-8aab-4cbd-86d3-cdd99356c838","title":"公共模块详解","description":"gui-common-modules","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"1d6a15c4-c2f7-48b1-9432-f71d03a1fe8e","gmt_create":"2025-11-26T21:18:13.4481013+08:00","gmt_modified":"2025-11-26T21:18:13.4546536+08:00"},{"catalog_id":"fb4b14d8-a3c9-4f17-8f24-10e8bfdb747b","title":"Version2 概述","description":"gui-version2-overview","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"a4570c89-1501-4477-b851-8661b4220a82","gmt_create":"2025-11-26T21:18:21.4882995+08:00","gmt_modified":"2025-11-26T21:18:21.4938714+08:00"},{"catalog_id":"724e5fc2-74d6-4fa7-9905-2ea39addce28","title":"微信自动化","description":"wechat-automation","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"d4781a43-4527-4e01-90f7-20dec2901739","gmt_create":"2025-11-26T21:19:07.2800646+08:00","gmt_modified":"2025-11-26T21:19:07.2856881+08:00"},{"catalog_id":"1be2325d-d01c-45e1-9320-c2bf7aead663","title":"通信自动化功能集成","description":"gui-communication-automation","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"9a53bdb2-8e7f-46c8-9141-6bee7bc191f9","gmt_create":"2025-11-26T21:19:11.1333935+08:00","gmt_modified":"2025-11-26T21:19:11.1371068+08:00"},{"catalog_id":"857acbc8-0151-46af-89f8-37b311535d41","title":"Word处理","description":"word-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"b9eb55c9-fc40-44c4-8be7-2786f07c7f54","gmt_create":"2025-11-26T21:19:36.322363+08:00","gmt_modified":"2025-11-26T21:19:36.3257366+08:00"},{"catalog_id":"0d3591e6-05eb-4c99-8c4b-77afedac49ea","title":"消息处理与自动化响应","description":"wechat-message-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"17415957-366b-4688-957a-62f158818037","gmt_create":"2025-11-26T21:20:34.7547292+08:00","gmt_modified":"2025-11-26T21:20:34.7590699+08:00"},{"catalog_id":"f29fecfb-0072-4d50-bdc8-ecac5b1e0631","title":"视频处理","description":"video-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c85a941b-03d4-478f-ba4d-3eef6d640041","gmt_create":"2025-11-26T21:20:41.2231106+08:00","gmt_modified":"2025-11-26T21:20:41.2282376+08:00"},{"catalog_id":"2bea2dfa-9a57-4c02-9f82-5f8267fb5caf","title":"合并Excel文件","description":"excel-merge","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"d936a8e9-d2c4-429c-8b61-bb009a7264c6","gmt_create":"2025-11-26T21:20:45.6874225+08:00","gmt_modified":"2025-11-26T21:20:45.6901284+08:00"},{"catalog_id":"be0c69a6-6c67-4442-958b-7c6fb66891ca","title":"PDF格式转换","description":"pdf-format-conversion","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"10e09463-ae87-4160-a549-c41b043be8c9","gmt_create":"2025-11-26T21:21:53.1696952+08:00","gmt_modified":"2025-11-26T21:21:53.1748199+08:00"},{"catalog_id":"e07dcb60-1d19-472e-a815-14f3bb5ab9ad","title":"文本智能处理示例","description":"text-processing-ai-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"ca0244f3-0cff-4615-b150-2195b52dda45","gmt_create":"2025-11-26T21:21:59.3698837+08:00","gmt_modified":"2025-11-26T21:21:59.3748679+08:00"},{"catalog_id":"8be26775-97fe-4545-a6c0-9c0f979e08ac","title":"图片加水印","description":"image-watermark","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"3a81a86a-5c40-481b-99fb-288522713b05","gmt_create":"2025-11-26T21:22:02.7633505+08:00","gmt_modified":"2025-11-26T21:22:02.7695784+08:00"},{"catalog_id":"ad656284-e5b6-4784-af1d-b7c75a25975f","title":"Version3 概述","description":"gui-version3-overview","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"03a391b7-8863-44aa-84df-c270a407f459","gmt_create":"2025-11-26T21:22:51.0936492+08:00","gmt_modified":"2025-11-26T21:22:51.0957713+08:00"},{"catalog_id":"fe6367d1-81a3-4b95-a92e-cf12e5d7db5a","title":"自定义UI组件","description":"gui-ui-components","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"b818d801-231f-45d2-8598-103204f34bcc","gmt_create":"2025-11-26T21:22:54.5315247+08:00","gmt_modified":"2025-11-26T21:22:54.5360428+08:00"},{"catalog_id":"c8b75962-2412-4786-a59b-a3d2969e09c0","title":"多媒体处理功能集成","description":"gui-multimedia-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"a7bdc95a-cab8-45cc-b6e7-bb58959459cb","gmt_create":"2025-11-26T21:22:58.3200436+08:00","gmt_modified":"2025-11-26T21:22:58.3232991+08:00"},{"catalog_id":"08b54a2f-374e-422a-a35d-6a4838aadbfa","title":"PDF处理","description":"pdf-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"ca6668ef-402d-47a3-8877-8415bb3d3bae","gmt_create":"2025-11-26T21:23:50.6917621+08:00","gmt_modified":"2025-11-26T21:23:50.6952381+08:00"},{"catalog_id":"faeb2733-9b92-4fc8-83ad-70bb5688ee30","title":"拆分Excel文件","description":"excel-split","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"dc9ef5a7-c78b-4995-b72f-027c9713d195","gmt_create":"2025-11-26T21:24:15.9320993+08:00","gmt_modified":"2025-11-26T21:24:15.9348433+08:00"},{"catalog_id":"f766024a-5940-4054-b625-2043d2445d05","title":"AI集成与智能对话","description":"wechat-ai-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"a3fb88da-78ec-479f-b655-720ec594a982","gmt_create":"2025-11-26T21:24:26.3087229+08:00","gmt_modified":"2025-11-26T21:24:26.3125375+08:00"},{"catalog_id":"86b479ca-7855-49ab-9a1d-8eeb9844f72b","title":"PDF内容合并","description":"pdf-content-merging","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"e85972e1-0a2b-4105-8d30-2caec7de162a","gmt_create":"2025-11-26T21:24:57.7635293+08:00","gmt_modified":"2025-11-26T21:24:57.7670313+08:00"},{"catalog_id":"6a7c9b66-24cc-4cb9-b37a-80d03a83fe7d","title":"图片去水印","description":"image-dewatermark","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"3cd2e237-4eb0-41b8-8efe-1a3abd8ac6af","gmt_create":"2025-11-26T21:25:32.6166916+08:00","gmt_modified":"2025-11-26T21:25:32.6223889+08:00"},{"catalog_id":"2d0da31e-c761-42b0-9fb5-252a2a748db2","title":"网页内容提取与电子书生成","description":"web-content-extraction-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"01d96125-9660-42f9-af4a-61f61a18ca04","gmt_create":"2025-11-26T21:26:00.9537012+08:00","gmt_modified":"2025-11-26T21:26:00.9576824+08:00"},{"catalog_id":"1ccc4ca2-b247-4dd8-8223-49ab2b96a9bc","title":"独立使用模式","description":"wechat-standalone-mode","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"3a56b7b2-ed16-4467-9c6a-7d0fe923c790","gmt_create":"2025-11-26T21:26:43.5369525+08:00","gmt_modified":"2025-11-26T21:26:43.5419556+08:00"},{"catalog_id":"ca6067ef-5206-4e99-9e65-628a084a2c9b","title":"数据工具功能集成","description":"gui-data-tools","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c79f9e2c-4db3-4bd0-945c-cbb2f2e16692","gmt_create":"2025-11-26T21:27:12.0074363+08:00","gmt_modified":"2025-11-26T21:27:12.0116837+08:00"},{"catalog_id":"1fb1ad18-3015-45d1-81f9-e7ddb59352e8","title":"PPT处理","description":"ppt-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"bd5aacea-8d7e-4cc5-8758-c7129fc1390d","gmt_create":"2025-11-26T21:27:37.7253637+08:00","gmt_modified":"2025-11-26T21:27:37.7341596+08:00"},{"catalog_id":"2c1a44fe-6eb7-4a84-b4ce-dce23410b236","title":"查询Excel数据","description":"excel-query","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"9eb45266-5d6f-488e-acff-ef37fc792cba","gmt_create":"2025-11-26T21:28:12.6337163+08:00","gmt_modified":"2025-11-26T21:28:12.6381146+08:00"},{"catalog_id":"c0055399-8433-4f3b-9bce-4ef76edd683a","title":"PDF加水印","description":"pdf-watermarking","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"322050f2-17da-4288-bde0-32add9481bfa","gmt_create":"2025-11-26T21:28:20.1561444+08:00","gmt_modified":"2025-11-26T21:28:20.1588745+08:00"},{"catalog_id":"e2290a1b-b483-4662-8951-f98c14a0196d","title":"数据可视化与词云生成","description":"data-visualization-examples","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"1a271850-e715-4316-922b-941c8fd51f9f","gmt_create":"2025-11-26T21:29:04.0155632+08:00","gmt_modified":"2025-11-26T21:29:04.0180806+08:00"},{"catalog_id":"1a3c6951-ba4b-48ae-b80e-a32db8baef31","title":"图片压缩","description":"image-compression","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c37ab3d7-a842-4e37-86c1-ae799ecaafa8","gmt_create":"2025-11-26T21:29:05.1542943+08:00","gmt_modified":"2025-11-26T21:29:05.1594684+08:00"},{"catalog_id":"f8fcb270-61ea-4ccf-b0f5-92f482a19e16","title":"Excel格式转换","description":"excel-conversion","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"cb08505a-d31d-46cd-b836-a93d18a464b1","gmt_create":"2025-11-26T21:30:06.9241219+08:00","gmt_modified":"2025-11-26T21:30:06.9291112+08:00"},{"catalog_id":"3b746c52-edb9-45be-99b3-389c0e49005f","title":"文本转词云","description":"text-to-wordcloud","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"97f8451f-ca79-464f-a26d-0926992586e3","gmt_create":"2025-11-26T21:30:14.531118+08:00","gmt_modified":"2025-11-26T21:30:14.5349726+08:00"},{"catalog_id":"796fb214-7e2f-46b1-a370-80dfa4c07b1b","title":"Version2 架构设计","description":"gui-version2-architecture","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"36093fae-b1c9-41c6-8ca8-dc09b2336df4","gmt_create":"2025-11-26T21:30:50.5550694+08:00","gmt_modified":"2025-11-26T21:30:50.5605508+08:00"},{"catalog_id":"e1a64950-db92-468f-b420-ac15fd32fea3","title":"邮件发送功能集成","description":"gui-email-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"77a18b2a-2c18-4a70-814e-048c21e5ed5e","gmt_create":"2025-11-26T21:31:10.040681+08:00","gmt_modified":"2025-11-26T21:31:10.0434512+08:00"},{"catalog_id":"0a6c6324-68ec-4624-a4ee-dcf99fc9eec1","title":"Excel功能集成","description":"gui-excel-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"3e54013b-34cc-4b99-892a-4dc18f5a2798","gmt_create":"2025-11-26T21:31:21.2212198+08:00","gmt_modified":"2025-11-26T21:31:21.2233298+08:00"},{"catalog_id":"5e77d3d6-2f94-4e74-a774-25e3af8f9260","title":"图片处理功能集成","description":"gui-image-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"74f4d03f-01f4-4ba9-9c89-758a5f7caa13","gmt_create":"2025-11-26T21:32:00.7997191+08:00","gmt_modified":"2025-11-26T21:32:00.8035793+08:00"},{"catalog_id":"102e2f7a-71e5-468a-ad01-f1b2cc2c4519","title":"发送消息","description":"wechat-send-message","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"d68488d0-413b-449f-8659-d4f7fa2281f5","gmt_create":"2025-11-26T21:32:14.4976677+08:00","gmt_modified":"2025-11-26T21:32:14.5024131+08:00"},{"catalog_id":"3da53eee-fce6-448b-824b-8bb3baf2a723","title":"财务计算功能集成","description":"gui-finance-tools","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"96c5e080-e224-4793-a8ba-f89e86a69e6c","gmt_create":"2025-11-26T21:32:40.8443285+08:00","gmt_modified":"2025-11-26T21:32:40.8469317+08:00"},{"catalog_id":"d681de07-c2c4-4428-adae-1524ba8f2379","title":"核心图像操作","description":"core-image-operations","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"beed0ade-0995-419a-800f-79bb27c10f00","gmt_create":"2025-11-26T21:33:26.2053987+08:00","gmt_modified":"2025-11-26T21:33:26.2115505+08:00"},{"catalog_id":"255c772e-d376-48c7-9a2d-7577fed76ad0","title":"关键词自动回复","description":"keyword-based-reply","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"4a6a1d4f-4733-4a3e-885d-541e6ba2d528","gmt_create":"2025-11-26T21:33:51.8461834+08:00","gmt_modified":"2025-11-26T21:33:51.850633+08:00"},{"catalog_id":"c44e2b9e-7e7a-47b7-95ac-ecff8b8c3873","title":"合并到不同Sheet","description":"merge2excel-function","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"7eb2ae79-9ebf-40d6-b8e2-c88170d6b076","gmt_create":"2025-11-26T21:33:54.8811464+08:00","gmt_modified":"2025-11-26T21:33:54.8856472+08:00"},{"catalog_id":"d640bbc9-b47b-4a12-910f-3dddb8b96cc4","title":"按工作表拆分","description":"split-by-sheet","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"128f3492-ff56-46fa-bea4-a3aed45201e6","gmt_create":"2025-11-26T21:34:42.983772+08:00","gmt_modified":"2025-11-26T21:34:42.9885528+08:00"},{"catalog_id":"ef89d5c6-745f-4ddd-80f8-d518915fd224","title":"核心UI组件详解","description":"gui-version2-core-components","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"f45d5fa7-09ff-47a5-8766-2e361145755a","gmt_create":"2025-11-26T21:35:09.9498702+08:00","gmt_modified":"2025-11-26T21:35:09.9558628+08:00"},{"catalog_id":"356d68f9-38fa-4840-a820-b88367331c99","title":"TXT转PDF","description":"txt-to-pdf","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"90eb969b-89e6-4606-8ce3-57f55f3ff20c","gmt_create":"2025-11-26T21:35:22.6365364+08:00","gmt_modified":"2025-11-26T21:35:22.6410418+08:00"},{"catalog_id":"236bd51a-06c1-4890-9a45-b5805fcbb5df","title":"Word功能集成","description":"gui-word-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"885d983d-b21b-46e2-8226-15a7ab20608c","gmt_create":"2025-11-26T21:36:00.7376879+08:00","gmt_modified":"2025-11-26T21:36:00.7404615+08:00"},{"catalog_id":"aaa92e67-19fb-4b7e-a758-85749ac94e68","title":"微信机器人功能集成","description":"gui-wechat-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"7942c084-7600-4863-8db1-1ceea9483817","gmt_create":"2025-11-26T21:36:21.3293548+08:00","gmt_modified":"2025-11-26T21:36:21.3326072+08:00"},{"catalog_id":"eb7f762e-5efe-48cc-b280-f68e363cbcc8","title":"视频处理功能集成","description":"gui-video-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"609fd0ae-6729-47fa-848f-9a8ef77ac374","gmt_create":"2025-11-26T21:36:22.46766+08:00","gmt_modified":"2025-11-26T21:36:22.4711037+08:00"},{"catalog_id":"ede0e1ab-84de-4436-9bd3-7fbc92a72f78","title":"高级图像处理","description":"advanced-image-processing","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"36d5887d-5c74-411f-b858-f25fe448afb0","gmt_create":"2025-11-26T21:37:14.569913+08:00","gmt_modified":"2025-11-26T21:37:14.5733167+08:00"},{"catalog_id":"19390422-54c4-43e3-9595-68c4d6b0bb5b","title":"定时发送消息","description":"wechat-scheduled-send","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"538de21d-090d-4cea-81c1-42d310d5d543","gmt_create":"2025-11-26T21:37:23.0176936+08:00","gmt_modified":"2025-11-26T21:37:23.025712+08:00"},{"catalog_id":"84bb86a4-20ca-408e-bb74-69510b09619c","title":"工具集功能集成","description":"gui-utility-tools","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"41b0ecc1-6db5-4c08-809f-bc4186acbc2b","gmt_create":"2025-11-26T21:37:37.8157962+08:00","gmt_modified":"2025-11-26T21:37:37.8188005+08:00"},{"catalog_id":"f02f61d4-07cd-4a91-9a71-b0578eb120e8","title":"定时消息发送","description":"scheduled-messaging","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"3a7c7ed0-842c-4596-9361-bb7178780087","gmt_create":"2025-11-26T21:38:28.1106605+08:00","gmt_modified":"2025-11-26T21:38:28.1139593+08:00"},{"catalog_id":"5da29eb1-dd1f-48a6-94c8-1f2ad1420f35","title":"合并到同一Sheet","description":"merge2sheet-function","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"e2792a3e-a166-41bd-8caf-e81122ac0ab9","gmt_create":"2025-11-26T21:38:30.1931276+08:00","gmt_modified":"2025-11-26T21:38:30.195149+08:00"},{"catalog_id":"d5efff4b-8c76-47e0-acf0-ac47de7204bb","title":"按列值拆分","description":"split-by-column","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"0bd844e5-f677-4a06-a354-27e6b9c7f051","gmt_create":"2025-11-26T21:38:40.4974001+08:00","gmt_modified":"2025-11-26T21:38:40.5036367+08:00"},{"catalog_id":"23418a2f-b6aa-40be-baaf-d47cf88a827f","title":"PDF功能集成","description":"gui-pdf-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"b476dd40-cb2b-40db-bc7a-32826c3af6a2","gmt_create":"2025-11-26T21:39:40.6745553+08:00","gmt_modified":"2025-11-26T21:39:40.6772164+08:00"},{"catalog_id":"ff7a478b-63bc-4b53-a079-cfc3326c82fe","title":"PDF转Word","description":"pdf-to-word","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"c462672b-5122-4d41-8955-9ac0a6e83766","gmt_create":"2025-11-26T21:39:45.7731442+08:00","gmt_modified":"2025-11-26T21:39:45.776285+08:00"},{"catalog_id":"fb2f4f78-8161-46e5-a06f-b3ac24af8bed","title":"主题与样式系统","description":"gui-version2-theme-style","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"9042f44e-bbec-4f68-9de2-5d854a2ce824","gmt_create":"2025-11-26T21:40:22.3346494+08:00","gmt_modified":"2025-11-26T21:40:22.3402744+08:00"},{"catalog_id":"1ce34ed0-d01f-48ed-b4ce-8328bad18fbf","title":"OCR识别功能集成","description":"gui-ocr-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"b0583f04-a370-484e-b6cc-6ce4ab1cf3c2","gmt_create":"2025-11-26T21:40:41.6469078+08:00","gmt_modified":"2025-11-26T21:40:41.6554052+08:00"},{"catalog_id":"d02be4f7-6a6b-469d-b867-25eca75059de","title":"Markdown处理功能集成","description":"gui-markdown-tools","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"5d154d33-563c-4faa-8cfb-f9a39e2049f6","gmt_create":"2025-11-26T21:41:22.7671321+08:00","gmt_modified":"2025-11-26T21:41:22.76928+08:00"},{"catalog_id":"2fbb3686-4ee9-4dae-a206-e2e93050fefa","title":"群组与好友管理","description":"group-friend-management","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"2623150f-3ec1-4728-b010-a8dd733c231c","gmt_create":"2025-11-26T21:41:37.6637964+08:00","gmt_modified":"2025-11-26T21:41:37.6665884+08:00"},{"catalog_id":"a31786aa-e457-493f-b2c7-a9e14fc864e5","title":"关键词自动回复","description":"wechat-keyword-response","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"bed8df5a-dca4-423f-8d96-c77e3d66734b","gmt_create":"2025-11-26T21:41:37.7894658+08:00","gmt_modified":"2025-11-26T21:41:37.7934525+08:00"},{"catalog_id":"a27305ea-b9f9-465c-9837-0a0f78f91e95","title":"PDF转图片","description":"pdf-to-images","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"fc25ad4c-a5fa-4302-801f-872afeb1ebba","gmt_create":"2025-11-26T21:42:34.7064843+08:00","gmt_modified":"2025-11-26T21:42:34.709096+08:00"},{"catalog_id":"d164713d-2f96-4208-8d06-d124cc50ab2f","title":"PPT功能集成","description":"gui-ppt-integration","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"ec3f17a6-41a7-4b4c-8c59-b2946b52c731","gmt_create":"2025-11-26T21:42:36.3186003+08:00","gmt_modified":"2025-11-26T21:42:36.3213674+08:00"},{"catalog_id":"15df4f0e-7ca4-4c9a-b335-86551e26b2d7","title":"多语言支持机制","description":"gui-version2-i18n","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"92fdb66a-658d-467c-b39b-ba25c1ec7463","gmt_create":"2025-11-26T21:43:35.0259118+08:00","gmt_modified":"2025-11-26T21:43:35.0288797+08:00"},{"catalog_id":"ad170c9d-4638-40af-883f-06492e44ff38","title":"群发消息","description":"wechat-group-messaging","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"775dd4d2-4bc0-464d-9d51-c076de51e905","gmt_create":"2025-11-26T21:44:10.7305454+08:00","gmt_modified":"2025-11-26T21:44:10.7337782+08:00"},{"catalog_id":"736aca01-df8a-4e1f-876b-eb8f8556c0f7","title":"文件传输","description":"wechat-file-transfer","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"d83bad12-fbbe-4a47-bd9b-77a98bb1a972","gmt_create":"2025-11-26T21:44:29.1772841+08:00","gmt_modified":"2025-11-26T21:44:29.1809539+08:00"},{"catalog_id":"322e3ca5-edc6-4ffe-b09a-323c82be022f","title":"消息接收","description":"wechat-message-reception","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"851254d3-f877-41fd-9cb0-0f1fa3a4794a","gmt_create":"2025-11-26T21:44:40.5324451+08:00","gmt_modified":"2025-11-26T21:44:40.5363018+08:00"},{"catalog_id":"4485e258-4ad2-4a6a-9db5-63ddb137abb0","title":"智能聊天机器人","description":"wechat-intelligent-chat","extend":"{}","progress_status":"completed","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","id":"26d01094-d27a-4af8-93a6-5baeaaaf60d5","gmt_create":"2025-11-26T21:45:03.8651472+08:00","gmt_modified":"2025-11-26T21:45:03.8704908+08:00"}],"wiki_overview":{"content":"\u003cblog\u003e\n# python-office 项目综合分析\n\n## 1. 项目介绍\n\n### 项目目的\npython-office 是一个专注于自动化办公场景的 Python 第三方库,旨在通过极简的编程方式解决日常办公中的重复性任务。该项目强调“一行代码完成一个功能”,极大降低了非专业开发者(如职场小白)使用自动化工具的门槛。\n\n### 核心目标\n- 提供开箱即用的办公自动化解决方案\n- 集成多种常用办公操作(文档处理、邮件发送、AI交互等)\n- 支持模块化引入,用户可根据需求选择性使用子功能\n- 持续更新功能以贴合实际职场需求\n\n### 目标用户\n- 办公室文员、行政人员等需要频繁处理文档的非技术人员\n- 希望提升工作效率的初级程序员或数据分析师\n- 自动化流程开发者作为基础工具库使用\n\n## 2. 技术架构\n\n### 组件分解\n项目采用模块化设计,核心功能分布在 `office/api/` 目录下,每个模块对应一类办公操作:\n- **poexcel**: Excel 文件处理\n- **poword**: Word 文档操作\n- **popdf**: PDF 文件转换与编辑\n- **poemail**: 自动发送邮件\n- **PyOfficeRobot**: 微信机器人自动化\n- **poocr**: 光学字符识别(OCR)\n- **porobot**: AI 聊天机器人集成\n\n此外,`examples/` 目录提供了大量可直接运行的示例脚本,帮助用户快速上手。\n\n### 设计模式\n项目采用了**门面模式(Facade Pattern)** 和 **模块化组织结构**:\n- `office/__init__.py` 作为统一入口,封装了所有子模块的导入逻辑,实现“一键引入全部功能”\n- 各子模块独立开发维护,降低耦合度\n- 使用 `compatibility.py` 进行运行环境兼容性检查,确保跨平台稳定性\n\n### 系统关系与数据流\n\n```mermaid\nflowchart TD\n A[用户脚本] --\u003e B[office.__init__]\n B --\u003e C[compatibility.check_compatibility]\n B --\u003e D[office.api.email]\n B --\u003e E[office.api.excel]\n B --\u003e F[office.api.word]\n B --\u003e G[office.api.pdf]\n B --\u003e H[office.api.wechat]\n B --\u003e I[office.api.ocr]\n D --\u003e J[(SMTP服务器)]\n E --\u003e K[(Excel文件)]\n F --\u003e L[(Word文档)]\n G --\u003e M[(PDF文件)]\n H --\u003e N[(微信客户端)]\n I --\u003e O[(OCR API)]\n```\n\n该图展示了从用户调用到具体功能执行的数据流向。主入口首先进行兼容性检查,然后根据需求调用相应 API 模块,最终与外部文件或服务交互。\n\n## 3. 关键实现\n\n### 主要入口点\n- `office/__init__.py`: 库的主入口,负责初始化和模块导入\n- `setup.py`: 包管理配置文件,用于 `pip install` 安装支持\n- `examples/` 目录下的各类 `.py` 示例文件:功能演示和使用模板\n\n### 核心模块\n- `office/api/email.py`: 邮件发送功能\n- `office/api/excel.py`: Excel 数据读写与处理\n- `office/api/pdf.py`: PDF 文件生成、加密、合并等\n- `office/api/wechat.py`: 微信自动化控制\n- `office/api/ocr.py`: 文字识别接口封装\n\n### 配置方式\n项目主要通过代码内建配置和外部依赖管理实现功能控制:\n- `settings.py` 中存在 Scrapy 框架配置片段(疑似遗留代码),但未在主项目中使用\n- 实际配置多以内置常量或函数参数形式存在,符合“极简使用”理念\n- 依赖管理通过 `setup.py` 定义(尽管当前内容为空)\n\n### 外部依赖\n虽然 `setup.py` 内容为空,但从模块功能可推断其依赖以下主流库:\n- `python-docx` / `openpyxl` / `pandas`:文档处理\n- `PyPDF2` / `pdfplumber` / `reportlab`:PDF 操作\n- `smtplib` / `email`:邮件发送\n- `wechatsogou` / `itchat` 类库:微信自动化\n- `baidu-aip` / `tencentcloud-sdk-python`:OCR 服务\n\n### 集成点\n- 第三方 API 接口(如百度翻译、OCR 服务)\n- 操作系统文件系统(批量文件处理)\n- 微信客户端(通过自动化技术控制)\n- 浏览器/网页内容抓取(spider 相关配置暗示存在网页转电子书等功能)\n\n### 组件关系图\n\n```mermaid\ngraph LR\n UserScript[用户脚本] --\u003e MainInit[office/__init__.py]\n MainInit --\u003e Compatibility[compatibility.py]\n MainInit --\u003e EmailAPI[api/email.py]\n MainInit --\u003e ExcelAPI[api/excel.py]\n MainInit --\u003e WordAPI[api/word.py]\n MainInit --\u003e PdfAPI[api/pdf.py]\n MainInit --\u003e WeChatAPI[api/wechat.py]\n MainInit --\u003e OcrAPI[api/ocr.py]\n \n EmailAPI --\u003e SMTP[(SMTP服务)]\n ExcelAPI --\u003e File[(Excel文件)]\n WordAPI --\u003e File\n PdfAPI --\u003e File\n WeChatAPI --\u003e WeChatClient[(微信客户端)]\n OcrAPI --\u003e BaiduAPI[(百度OCR接口)]\n \n Examples[examples/] --\u003e Demonstrate[功能示例]\n Demonstrate --\u003e EmailAPI\n Demonstrate --\u003e ExcelAPI\n Demonstrate --\u003e WeChatAPI\n```\n\n## 4. 关键功能\n\n### 功能概览\npython-office 提供了覆盖办公全场景的功能集:\n- **文档格式转换**:doc↔docx, xls↔xlsx, pdf↔word, ppt↔pdf 等\n- **批量文件处理**:重命名、分类、搜索、合并\n- **自动化通信**:自动发邮件、微信机器人、定时消息\n- **智能识别**:银行卡识别、通用文字 OCR\n- **数据处理**:Excel 数据查询、拆分、汇总\n- **多媒体处理**:图片加水印、去水印、词云生成、视频标注\n- **AI 集成**:ChatGPT 对话、网页转电子书\n\n### 实现亮点\n- **极简调用接口**:每个功能尽量做到“一行代码调用”\n- **模块独立可选**:支持按需安装使用特定子模块\n- **GUI 支持**:`gui/qtpy/` 提供图形界面版本,降低使用门槛\n- **贡献者友好**:`contributors/` 目录允许社区开发者提交个人工具而不影响主干代码\n\n### 功能架构状态图\n\n```mermaid\nstateDiagram-v2\n [*] --\u003e Idle\n Idle --\u003e FileConvert: 调用转换函数\n Idle --\u003e AutoSend: 调用发送函数\n Idle --\u003e ProcessData: 调用数据处理函数\n Idle --\u003e RecognizeText: 调用OCR函数\n \n FileConvert --\u003e Success: 转换完成\n AutoSend --\u003e Success: 发送成功\n ProcessData --\u003e Success: 处理完成\n RecognizeText --\u003e Success: 识别完成\n \n FileConvert --\u003e Error: 格式错误\n AutoSend --\u003e Error: 网络失败\n ProcessData --\u003e Error: 数据异常\n RecognizeText --\u003e Error: 图像模糊\n \n Success --\u003e Idle: 完成\n Error --\u003e Idle: 失败重置\n```\n\n此状态图描述了典型功能的执行流程:从空闲状态接收调用请求,进入处理阶段,最终返回成功或失败结果并重置。\n\nSources:\n- [README.md](README.md#L47-L150)\n- [setup.py](setup.py#L1-L14)\n- [settings.py](settings.py#L1-L161)\n- [office/__init__.py](office/__init__.py#L1-L30)\n- [office/api/__init__.py](office/api/__init__.py#L1-L2)\n\u003c/blog\u003e","gmt_create":"2025-11-26T20:49:02.4591635+08:00","gmt_modified":"2025-11-26T20:49:02.4591635+08:00","id":"23f11c79-6d17-4725-8b45-60bd201e4abc","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c"},"wiki_readme":{"content":"No readme file","gmt_create":"2025-11-26T20:48:03.619563+08:00","gmt_modified":"2025-11-26T20:48:03.619563+08:00","id":"0d5477c0-1458-4025-8976-37b026c53850","repo_id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c"},"wiki_repo":{"id":"3d0a4b27-3f51-45ac-a5c9-a216301bbc7c","name":"python-office","progress_status":"completed","wiki_present_status":"COMPLETED","optimized_catalog":"\".\\n├── contributors\\\\\\n│ ├── CatchDr\\\\\\n│ │ ├── Baidu_Text_transAPI.py\\n│ │ ├── doc2docx.py\\n│ │ ├── docx2doc.py\\n│ │ ├── ppt2pptx.py\\n│ │ ├── pptx2ppt.py\\n│ │ ├── video_time_statistics.py\\n│ │ ├── xls2xlsx.py\\n│ │ └── xlsx2xls.py\\n│ ├── bulabean\\\\\\n│ │ ├── SearchExcel.py\\n│ │ └── SplitExcel.py\\n│ ├── demo\\\\\\n│ │ └── WordType.py\\n│ ├── heyi\\\\\\n│ │ └── About_hy.md\\n│ ├── marvel2120\\\\\\n│ │ └── WordType.py\\n│ ├── old_from_gitee\\\\\\n│ │ ├── CHENJie666666\\\\\\n│ │ │ └── eliminate_background.py\\n│ │ ├── CNSeniorious000\\\\\\n│ │ │ └── pdf.py\\n│ │ ├── CoderWanFeng\\\\\\n│ │ │ └── add.py\\n│ │ ├── FileToExcel\\\\\\n│ │ │ └── FileToExcel.py\\n│ │ ├── bob-zhao\\\\\\n│ │ │ ├── pdf2imgs.py\\n│ │ │ ├── requirements.txt\\n│ │ │ └── test.py\\n│ │ ├── demo\\\\\\n│ │ │ └── demo.py\\n│ │ ├── han_ying_feng\\\\office\\\\\\n│ │ │ ├── excel.py\\n│ │ │ └── word.py\\n│ │ └── sustnf\\\\\\n│ │ ├── file.py\\n│ │ └── md5_verify.py\\n│ ├── sustnf\\\\\\n│ │ ├── file.py\\n│ │ └── md5_verify.py\\n│ ├── wangpeng\\\\\\n│ │ └── pinyin_gui.py\\n│ └── yinzeyuan\\\\\\n│ ├── Rename-AddSomething.py\\n│ ├── SearchSpecifyTypeFile.py\\n│ ├── check_local_dir_image_link_markdown.py\\n│ ├── markdown_link_image_to_base64.py\\n│ ├── output_file_list_to_excel.py\\n│ └── screen_unmarked_image.py\\n├── examples\\\\\\n│ ├── PyOfficeRobot\\\\\\n│ │ ├── 010-定时群发的资料\\\\\\n│ │ │ └── content.txt\\n│ │ ├── 001-发一条信息.py\\n│ │ ├── 002-发文件.py\\n│ │ ├── 003-根据关键词回复.py\\n│ │ ├── 004-定时发送.py\\n│ │ ├── 005-自定义功能.py\\n│ │ ├── 006-独立版本.py\\n│ │ ├── 007-收集群消息.py\\n│ │ ├── 008-发消息换行.py\\n│ │ ├── 009-批量加好友.py\\n│ │ ├── 010-定时群发.py\\n│ │ ├── 011-chat_chatgpt.py\\n│ │ ├── 012、智能聊天.py\\n│ │ └── @AutomationLog.txt\\n│ ├── poemail\\\\\\n│ │ └── 发送邮件.py\\n│ ├── poexcel\\\\\\n│ │ ├── Excel转PDF.py\\n│ │ ├── 创建Excel文件.py\\n│ │ ├── 合并2个Excel的内容到一个sheet中.py\\n│ │ ├── 合并多个Excel到一个Excel的不同sheet中.py\\n│ │ ├── 同一个excel里的不同sheet,拆分为不同的excel文件.py\\n│ │ ├── 批量模拟数据.py\\n│ │ ├── 把100个Excel中符合条件的数据,汇总到1个Excel里.py\\n│ │ ├── 根据内容,查询Excel.py\\n│ │ ├── 根据指定的列,拆分excel.py\\n│ │ └── 统计Excel打印出来有多少页.py\\n│ ├── pofile\\\\\\n│ │ ├── test_files\\\\replace4filename\\\\\\n│ │ │ ├── 程序员晚枫-B站.txt\\n│ │ │ └── 程序员晚枫-小红书.txt\\n│ │ ├── 批量获取文件列表.py\\n│ │ ├── 批量重命名.py\\n│ │ ├── 新建文件夹.py\\n│ │ ├── 根据内容,查找文件.py\\n│ │ ├── 检查后缀名.py\\n│ │ └── 自动整理文件夹.py\\n│ ├── pofinance\\\\\\n│ │ └── 1、单次做T.py\\n│ ├── pohan\\\\\\n│ │ └── 1、给古诗配拼音.py\\n│ ├── poimage\\\\\\n│ │ ├── 下载图片.py\\n│ │ ├── 图片加水印.py\\n│ │ ├── 图片去水印.py\\n│ │ └── 文本转词云.py\\n│ ├── poimage_demo\\\\\\n│ │ └── compress_image.py\\n│ ├── pomarkdown\\\\\\n│ │ └── Excel转Markdown.py\\n│ ├── poocr\\\\\\n│ │ ├── 识别银行卡.py\\n│ │ └── 通用文字识别.py\\n│ ├── popdf\\\\\\n│ │ ├── test_files\\\\txt2pdf\\\\\\n│ │ │ └── 程序员晚枫.txt\\n│ │ ├── PDF加密.py\\n│ │ ├── PDF加水印.py\\n│ │ ├── PDF解密.py\\n│ │ ├── TXT转PDF.py\\n│ │ ├── pdf_demo.py\\n│ │ ├── pdf转word.py\\n│ │ ├── pdf转图片.py\\n│ │ └── 合并PDF.py\\n│ ├── poppt\\\\\\n│ │ ├── merge4ppt.py\\n│ │ ├── ppt2img.py\\n│ │ └── ppt2pdf.py\\n│ ├── poprogress\\\\\\n│ │ └── simple.py\\n│ ├── porobot\\\\\\n│ │ └── chat.py\\n│ ├── poruiming\\\\\\n│ │ └── 测试API功能演示.py\\n│ ├── pospider\\\\\\n│ │ └── 网页转电子书.py\\n│ ├── potools\\\\\\n│ │ └── 工具类功能演示.py\\n│ ├── povideo\\\\\\n│ │ └── mark2video.py\\n│ ├── poword\\\\\\n│ │ ├── doc和docx互转.py\\n│ │ ├── word转PDF.py\\n│ │ └── 合并word.py\\n│ ├── pydatav\\\\\\n│ │ ├── txt2wordcloud\\\\\\n│ │ │ └── test.txt\\n│ │ └── 数据可视化-文章转图云.py\\n│ └── readme.md\\n├── gui\\\\qtpy\\\\\\n│ ├── version1\\\\\\n│ │ ├── customizeWindowPyfile\\\\\\n│ │ │ ├── ui\\\\\\n│ │ │ │ └── ui_Widget.py\\n│ │ │ └── FinalWidget.py\\n│ │ ├── main.py\\n│ │ └── requirements.txt\\n│ ├── version2\\\\\\n│ │ ├── gallery\\\\\\n│ │ │ ├── app\\\\\\n│ │ │ │ ├── common\\\\\\n│ │ │ │ │ ├── config.py\\n│ │ │ │ │ ├── icon.py\\n│ │ │ │ │ ├── signal_bus.py\\n│ │ │ │ │ ├── style_sheet.py\\n│ │ │ │ │ ├── translator.py\\n│ │ │ │ │ └── trie.py\\n│ │ │ │ ├── components\\\\\\n│ │ │ │ │ ├── avatar_widget.py\\n│ │ │ │ │ ├── link_card.py\\n│ │ │ │ │ └── sample_card.py\\n│ │ │ │ ├── config\\\\\\n│ │ │ │ │ └── config.json\\n│ │ │ │ ├── resource\\\\i18n\\\\\\n│ │ │ │ │ ├── gallery_hk.ts\\n│ │ │ │ │ ├── gallery_zh.ts\\n│ │ │ │ │ ├── qfluentwidgets_hk.ts\\n│ │ │ │ │ └── qfluentwidgets_zh.ts\\n│ │ │ │ └── view\\\\\\n│ │ │ │ ├── basic_input_interface.py\\n│ │ │ │ ├── date_time_interface.py\\n│ │ │ │ ├── dialog_interface.py\\n│ │ │ │ ├── gallery_interface.py\\n│ │ │ │ ├── home_interface.py\\n│ │ │ │ ├── icon_interface.py\\n│ │ │ │ ├── layout_interface.py\\n│ │ │ │ ├── main_window.py\\n│ │ │ │ ├── material_interface.py\\n│ │ │ │ ├── menu_interface.py\\n│ │ │ │ ├── scroll_interface.py\\n│ │ │ │ ├── setting_interface.py\\n│ │ │ │ ├── status_info_interface.py\\n│ │ │ │ ├── text_interface.py\\n│ │ │ │ ├── title_bar.py\\n│ │ │ │ └── view_interface.py\\n│ │ │ └── demo.py\\n│ │ └── requirements.txt\\n│ └── version3\\\\\\n│ └── main.py\\n├── office\\\\\\n│ ├── api\\\\\\n│ │ ├── testApi\\\\\\n│ │ │ └── ruiming.py\\n│ │ ├── __init__.py\\n│ │ ├── email.py\\n│ │ ├── excel.py\\n│ │ ├── file.py\\n│ │ ├── finance.py\\n│ │ ├── image.py\\n│ │ ├── markdown.py\\n│ │ ├── ocr.py\\n│ │ ├── pdf.py\\n│ │ ├── ppt.py\\n│ │ ├── tools.py\\n│ │ ├── video.py\\n│ │ ├── web.py\\n│ │ ├── wechat.py\\n│ │ └── word.py\\n│ ├── core\\\\TestTypes\\\\\\n│ │ └── RuimingType.py\\n│ ├── lib\\\\\\n│ │ ├── conf\\\\\\n│ │ │ └── CONST.py\\n│ │ ├── decorator_utils\\\\\\n│ │ │ └── instruction_url.py\\n│ │ ├── excel\\\\\\n│ │ │ └── SplitExcel.py\\n│ │ ├── image\\\\\\n│ │ │ ├── add_watermark_service.py\\n│ │ │ └── eliminate_background.py\\n│ │ ├── pdf\\\\\\n│ │ │ └── add_watermark_service.py\\n│ │ ├── ppt\\\\\\n│ │ │ └── ppt2pdf_service.py\\n│ │ ├── tools\\\\\\n│ │ │ ├── lottery8ticket.py\\n│ │ │ ├── pwd4wifi_service.py\\n│ │ │ ├── qoute_dict_create_article.py\\n│ │ │ ├── weather_city_code.py\\n│ │ │ └── weather_service.py\\n│ │ └── utils\\\\\\n│ │ ├── except_utils.py\\n│ │ ├── pandas_mem.py\\n│ │ └── time_utils.py\\n│ ├── __init__.py\\n│ └── compatibility.py\\n├── tests\\\\\\n│ ├── assets\\\\\\n│ │ └── style.css\\n│ ├── test_code\\\\\\n│ │ ├── test_tools\\\\\\n│ │ │ └── test_trans.py\\n│ │ ├── test_dev.py\\n│ │ ├── test_excel.py\\n│ │ ├── test_file.py\\n│ │ ├── test_image.py\\n│ │ ├── test_markdown.py\\n│ │ ├── test_ocr.py\\n│ │ ├── test_pdf.py\\n│ │ ├── test_ppt.py\\n│ │ ├── test_ruiming.py\\n│ │ ├── test_search_by_content.py\\n│ │ ├── test_tools.py\\n│ │ ├── test_video.py\\n│ │ ├── test_web.py\\n│ │ ├── test_wechat.py\\n│ │ └── test_word.py\\n│ ├── test_files\\\\\\n│ │ ├── markdown\\\\\\n│ │ │ └── test.md\\n│ │ ├── md\\\\\\n│ │ │ └── test.txt\\n│ │ └── ruiming\\\\\\n│ │ ├── change_label_in_xml\\\\\\n│ │ │ ├── testfile.xml\\n│ │ │ └── testfile1.xml\\n│ │ └── screen_without_label_json_file\\\\\\n│ │ └── 1.json\\n│ ├── test_utils\\\\\\n│ │ ├── comm_utils.py\\n│ │ └── test_input.py\\n│ ├── __init__.py\\n│ ├── report.html\\n│ └── test_main.py\\n├── README-EN.md\\n├── README.md\\n├── settings.py\\n├── setup.cfg\\n├── setup.py\\n└── test_compatibility.py\\n\"","current_document_structure":"WikiEncrypted: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","catalogue_think_content":"WikiEncrypted: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","recovery_checkpoint":"wiki_generation_completed","last_commit_id":"505aa2e6be2d993ba60afa06458d33fcbf1cfdf2","last_commit_update":"2025-11-26T20:30:17+08:00","gmt_create":"2025-11-26T20:48:00.5496302+08:00","gmt_modified":"2025-11-26T21:45:03.9720406+08:00","extend_info":"{\"language\":\"zh\",\"active\":true,\"branch\":\"develop\",\"shareStatus\":\"\",\"server_error_code\":\"\",\"cosy_version\":\"\"}"}} \ No newline at end of file diff --git a/.qoder/rules/commentStyle.md b/.qoder/rules/commentStyle.md deleted file mode 100644 index c4a19a61..00000000 --- a/.qoder/rules/commentStyle.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -trigger: always_on -alwaysApply: true ---- - -# Python函数注释风格规范 - -本规范适用于项目中所有Python文件的函数注释。 - -## 注释风格 -所有Python函数必须使用Google风格的docstring注释,采用**中英文双语**格式。 - -## 格式要求 - -### 基本格式(中英文双语) -def function_name(param1, param2): - """Brief description of the function in English. - - 函数的简短中文描述。 - - Detailed description of the function (optional, if more explanation is needed). - Can be divided into multiple paragraphs to describe the function's features and usage. - - 函数的详细中文描述(可选,如果需要更多说明)。 - 可以分多段描述函数的功能、用途等。 - - Args: - param1 (type): description of parameter 1 / 参数1的描述 - param2 (type): description of parameter 2 / 参数2的描述 - - Returns: - type: description of return value / 返回值的描述 - - Raises: - ExceptionType: description of exception condition / 异常情况的描述(如果有) - - Examples: - >>> function_name(value1, value2) - expected_result - """ - pass - -### 具体规则(双语注释标准) - -1. **简短描述**: - - 第一行为英文简短描述,以句号结尾 - - 第二行空行 - - 第三行为对应的中文简短描述,以句号结尾 - -2. **详细描述**: - - 如需要,先写英文详细描述 - - 空一行后添加中文详细描述 - - 保持中英文内容对应 - -3. **Args(参数)**: - - 使用 `Args:` 标题 - - 格式:`参数名 (类型): English description / 中文描述` - - 每个参数独立一行 - - 中英文描述用 ` / ` 分隔 - -4. **Returns(返回值)**: - - 使用 `Returns:` 标题 - - 格式:`类型: English description / 中文描述` - -5. **Raises(异常)**: - - 使用 `Raises:` 标题 - - 格式:`异常类型: English description / 中文描述` - -6. **Examples(示例)**: - - 使用 `Examples:` 标题 - - 使用 `>>>` 表示代码示例 - - 示例代码无需双语 - -### 示例(双语格式) - -def add_numbers(a, b): - """Calculate the sum of two numbers. - - 计算两个数字的和。 - - Args: - a (int|float): the first number / 第一个数字 - b (int|float): the second number / 第二个数字 - - Returns: - int|float: sum of the two numbers / 两个数字的和 - - Examples: - >>> add_numbers(1, 2) - 3 - >>> add_numbers(1.5, 2.5) - 4.0 - """ - return a + b - -## 注意事项 - -- 所有公共函数和方法都必须添加双语docstring -- 私有函数(以`_`开头)可以使用简化的注释,但仍建议遵循此规范 -- 类的`__init__`方法也应该添加docstring,说明类的初始化参数 -- 保持中英文注释内容准确、简洁、有用 -- 中英文描述应保持语义一致 -- 对于模块级docstring,也应采用双语格式,英文在前,中文在后 diff --git a/PR-154-review.md b/PR-154-review.md new file mode 100644 index 00000000..73c7bfa0 --- /dev/null +++ b/PR-154-review.md @@ -0,0 +1,113 @@ +# PR #154 代码审查报告 — feat(word): 支持隐藏 doc2docx 转换进度条 + +> 审查方式:基于 PR diff 静态分析 + 本地仓库 `develop` 分支(HEAD `c8f263d`)交叉核对 +> 注:`gh` CLI 未登录 GitHub,本报告未发布为 PR 评论。如需发布,请先 `gh auth login`。 + +## 一、PR 元数据 + +| 项 | 内容 | +|----|------| +| **标题** | feat(word): 支持隐藏 doc2docx 转换进度条 | +| **作者** | [@forever-ivy](https://github.com/forever-ivy) | +| **源分支** | `forever-ivy:feat/doc2docx-progress-toggle` | +| **目标分支** | `CoderWanFeng:develop` | +| **变更文件** | 3 个(`office/api/word.py`、`skills/word/doc2docx/SKILL.md`、`tests/test_code/test_word_api_parameters.py`) | +| **提交数** | 1(67 additions, 3 deletions) | +| **修复 Issue** | #139 | +| **底层依赖** | `CoderWanFeng/poword#3`(**当前状态:OPEN,未合并**) | + +## 二、提交列表 + +- `feat(word): 支持隐藏 doc2docx 转换进度条`(1 commit) + +## 三、变更概览 + +| 文件 | 类型 | 关键改动 | +|------|------|----------| +| `office/api/word.py` | 修改 | `doc2docx` 新增 `show_progress: bool = True`;`show_progress=False` 时向 `poword.doc2docx` 转发 `show_progress=False`,否则不传该键保持兼容 | +| `skills/word/doc2docx/SKILL.md` | 修改 | 示例与参数表补充 `show_progress` | +| `tests/test_code/test_word_api_parameters.py` | 新增 | mock `poword`,验证默认调用与显式隐藏两种参数转发 | + +## 四、自动化发现 + +### 🟠 BLOCKER — PR 基于过时 develop,合入将冲突并覆盖 #157 的改进 +**文件**:`office/api/word.py`(`doc2docx`) + +本地 `develop` 当前 HEAD(`c8f263d`)历史包含提交 `5e8318b Support full output path in doc2docx (#157)`,该提交已为 `doc2docx` 带来两处关键改动,**而 PR #154 的 diff 上下文里完全没有这些**: + +1. `output_name` 自动解析(#157 引入): + ```python + if output_name is None and Path(output_path).suffix.lower() == ".docx": + output_file = Path(output_path) + output_path = str(output_file.parent) + output_name = output_file.name + ``` +2. 全模块已改为 `_load_poword()` **延迟加载**(仅在调用时 `import poword`),避免 Windows 专用依赖在 `import office` 时触发 `ModuleNotFoundError`: + ```python + poword = _load_poword() + poword.doc2docx(input_path=input_path, output_path=output_path, output_name=output_name) + ``` + +PR #154 的改动却是直接把调用替换为 `poword.doc2docx(**kwargs)`(无 `_load_poword()`、无 `output_name` 解析)。 + +**后果(若直接合入)**: +- ❌ 丢失 #157 的 `output_name` 自动解析能力; +- ❌ 把延迟加载退回为直接调用 `poword`,**回归「非 Windows 环境 `import office` 因缺 poword 而崩溃」的已知风险**(这正是之前引入 `_load_poword` 要修的)。 + +**要求**:**rebase 到最新 `develop` 后再合入**,将 `show_progress` 逻辑叠加在现有 `doc2docdocx`(含 `_load_poword()` + `output_name` 解析)之上,例如: +```python +def doc2docx(input_path, output_path=r'./', output_name=None, show_progress=True): + if output_name is None and Path(output_path).suffix.lower() == ".docx": + ... + poword = _load_poword() + kwargs = {'input_path': input_path, 'output_path': output_path, 'output_name': output_name} + if not show_progress: + kwargs['show_progress'] = False + poword.doc2docx(**kwargs) +``` + +### 🟠 BLOCKER — 底层依赖 `poword#3` 未合并发布 +**依赖链**:`office.word.doc2docx(show_progress=False)` → `poword.doc2docx(show_progress=False)`(需 poword#3 提供) + +- 经核查,poword#3 页面仍为 `wants to merge ... into main` 措辞,**表明其处于 OPEN 状态、尚未合并到 `poword/main`,更未发布到 PyPI**。 +- `setup.cfg` 对 poword 的约束为 `poword;platform_system=='Windows'`,**无版本下限**。 +- **后果**:当前用户装到的 poword(旧版)`doc2docx` 大概率**不接受 `show_progress` 关键字**。本 PR 仅在 `show_progress=False` 时转发该键,因此: + - 默认调用(`show_progress=True`,不转发该键)✅ 仍兼容所有版本; + - 显式 `show_progress=False` ⚠️ 在旧版 poword 上极可能抛 `TypeError: unexpected keyword argument 'show_progress'`(除非旧版用 `**kwargs` 吞参,未验证)。 +- **要求**:至少满足其一再合入:(a) 等待 poword#3 合并并发布,且在 `setup.cfg` 提高 poword 版本下限(如 `poword>=x.y.z;platform_system=='Windows'`);或 (b) 在 `word.py` 内对 `show_progress=False` 做防御性转发(如先探测 poword 是否支持该参数,或对 `TypeError` 降级)。 + +### 🔵 实现质量(正面) +- `show_progress` 转发逻辑正确:默认不传键(兼容旧调用),仅 `False` 时传 `show_progress=False`。✅ +- 用 `kwargs` 构建参数,清晰且易维护。✅ +- `docstring` 与 `skills/word/doc2docx/SKILL.md` 同步更新(参数表 + 示例),文档一致性好。✅ + +### 📊 测试覆盖 +**新增** `tests/test_code/test_word_api_parameters.py`:`load_word_api()` 动态加载 `word.py` 并 mock `poword`,验证: +- 默认调用 → `poword.doc2docx(input_path, output_path, output_name)`(不含 `show_progress`)✅ +- `show_progress=False` → 含 `show_progress=False` ✅ + +覆盖到位,但**有缺口**: +- 测试基于 PR 改动后的 `doc2docx` 签名,未涉及 `output_name` 解析 + `show_progress` 的组合(rebase 到含 #157 的 develop 后建议补充,防止回归 #157 行为); +- 白盒加载方式依赖 `word.py` 顶部无顶层 `import poword`(当前满足),rebase 后若引入新顶层 import 需同步调整 mock。 + +### 安全与高危调用 +- 无硬编码凭据 / 密钥泄露 ✅ +- 无 `panic()` / `os._exit()` 等高危调用 ✅ +- 测试内 `print` 仅出现在 `if __name__ == "__main__":`,非生产路径 ✅ + +## 五、整体裁决 + +### 🟡 NEEDS ATTENTION(含两个 BLOCKER,合入前必须处理) + +**合入前置条件(缺一不可)**: +1. **Rebase 到最新 `develop`**:解决与 #157 的冲突,保留 `output_name` 解析与 `_load_poword()` 延迟加载,将 `show_progress` 叠加其上(否则会覆盖已有功能并回归 import 崩溃)。 +2. **落实底层依赖**:等待 `poword#3` 合并发布,并在 `setup.cfg` 设 poword 版本下限;或在 `word.py` 内做 `show_progress=False` 的防御性转发。 + +**次要建议**: +- 补充 `output_name` + `show_progress` 组合的单测; +- PR 描述已声明依赖 poword#3,建议在描述中标注其当前 OPEN 状态与预计合入节奏,便于维护者排期。 + +**优先级**:① rebase(阻断性,最高)→ ② 底层依赖落地 / 防御性转发 → ③ 测试补充。 + +--- +*生成时间:2026-08-04 | 审查人:PR 代码审查专家(本地静态分析,未发布 GitHub 评论)* diff --git a/PR-162-review.md b/PR-162-review.md new file mode 100644 index 00000000..9e510a24 --- /dev/null +++ b/PR-162-review.md @@ -0,0 +1,105 @@ +# PR #162 代码审查报告 — Fix compatibility check import side effects + +> 审查方式:基于 PR diff 静态分析(仓库本地已克隆,已核对引用关系) +> 注:`gh` CLI 未登录 GitHub,本报告未发布为 PR 评论。如需发布,请先 `gh auth login`。 + +## 一、PR 元数据 + +| 项 | 内容 | +|----|------| +| **标题** | Fix compatibility check import side effects | +| **作者** | [@echo-wee](https://github.com/echo-wee) | +| **源分支** | `echo-wee:fix-compatibility-mark-file-import` | +| **目标分支** | `CoderWanFeng:develop` | +| **变更文件** | 2 个(`office/compatibility.py`、`tests/test_code/test_optional_imports.py`) | +| **提交数** | 1 | +| **摘要** | ① 保护首次运行标记文件写入,避免 HOME 不可写时 import 崩溃;② 移除模块级兼容性检查以消除 import-time 副作用;③ 新增不可写场景的回归测试 | + +## 二、提交列表 + +- `fix compatibility check import side effects`(1 commit,含 `compatibility.py` + 测试 2 文件改动) + +## 三、变更文件概览 + +| 文件 | 类型 | 关键改动 | +|------|------|----------| +| `office/compatibility.py` | 修改 | `_check_first_run()` 包 try/except OSError;删除模块级 `compatibility_checker = check_compatibility()`;补文件结尾换行 | +| `tests/test_code/test_optional_imports.py` | 修改 | 新增 `test_compatibility_check_does_not_fail_when_mark_file_cannot_be_written` | + +## 四、自动化发现 + +### 🟡 错误处理 — `_check_first_run` 保护(有效,符合目标①) +**文件**:`office/compatibility.py`(方法 `_check_first_run`,约 24–38 行) + +改动将 `mkdir` / `write_text` 包进 `try/except OSError`: +```python +try: + self.mark_file.parent.mkdir(exist_ok=True) + if not self.mark_file.exists(): + self.mark_file.write_text(f"First run on {platform.system()} at {platform.platform()}") + return True +except OSError: + # 兼容性提示不应影响主包导入;HOME 只读或不可写时跳过首次运行提示。 + return False +return False +``` +- `PermissionError` 是 `OSError` 子类,捕获范围正确;降级返回 `False`(当作非首次运行,静默跳过警告),不会阻断 `import office`。 +- **评价**:核心修复有效。因为真实调用路径是 `office/__init__.py:5` → `check_compatibility()` → `CrossPlatformCompatibility().__init__` → `_check_first_run()`,此保护对 `import office` 同样生效。 + +### 🟠 风险 — PR 描述与实际范围有偏差(建议澄清/进一步改进) +**文件**:`office/__init__.py:5` + `office/compatibility.py:239` + +PR 摘要称 *"Remove module-level compatibility checking to avoid import-time side effects"*,但本地核对发现: +- `office/__init__.py:5` **仍然存在** `compatibility_checker = check_compatibility()`。 +- `check_compatibility()`(compatibility.py:227)会:`CrossPlatformCompatibility()`(写标记文件)+ `display_warning()`(非 Windows 首次运行时打印 rich 表格)。 + +因此本次删除的只是 `compatibility.py` 自身的重复模块级调用(即 `ISSUES_AUDIT.md:221` 记录的"双重 rich 表格输出" bug 的第二次触发),**`import office` 的 import-time 副作用(写 `~/.python-office/first_run_mark` + 显示警告)在 `__init__.py:5` 仍保留**。 + +**影响**: +- 若目标仅是"修复 import 崩溃 + 去重",本 PR 已达成。 +- 若目标是"让 `import office` 完全无副作用",则未达成——`__init__.py:5` 仍在 import 时写文件并可能打印。 + +**建议**: +1. 在 PR 描述中澄清实际范围(消除 `compatibility.py` 的重复模块级检查,而非完全移除 import 副作用);或 +2. 若确实要彻底无副作用,应同时移除 `office/__init__.py:5` 的 `compatibility_checker = check_compatibility()`,改为延迟/按需调用(例如首次调用具体 API 时再检查)。 + +### 🔵 风格 / 小建议 +- **`compatibility.py` 结尾换行**:diff 补了缺失的 `\n`(`\ No newline at end of file` → 加换行),符合 POSIX 文本规范,👍。 +- **`build/lib/` 构建产物**:仓库中存在 `build/lib/office/compatibility.py` 与 `build/lib/office/__init__.py` 旧版副本(仍含模块级调用),属 setuptools 构建遗留物,不应纳入版本库。建议加入 `.gitignore` 或清理,避免与源码混淆。 + +### 📝 TODO(仓库卫生,非阻塞) +- `ISSUES_AUDIT.md:221` 记录了"双重 rich 表格输出"bug,本 PR 已修复该重复触发,建议在该审计文档中标注"已修复(PR #162)",避免后续复测重复扣分。 + +### 📊 测试覆盖 +**新增测试**:`test_compatibility_check_does_not_fail_when_mark_file_cannot_be_written` +```python +def test_compatibility_check_does_not_fail_when_mark_file_cannot_be_written(self): + with self._optional_import_test_environment(): + compatibility = importlib.import_module("office.compatibility") + with mock.patch.object(compatibility.Path, "mkdir", side_effect=PermissionError("readonly")): + checker = compatibility.CrossPlatformCompatibility() + self.assertFalse(checker.is_first_run) +``` +- 验证了 `mkdir` 抛 `PermissionError` 时实例化不崩溃且 `is_first_run == False`,命中 `except OSError` 分支。✅ +- **覆盖缺口**:测试直接 `import office.compatibility` 并实例化 `CrossPlatformCompatibility`,未覆盖真实的 `import office` 端到端路径(即 `__init__.py:5` → `check_compatibility()` → `display_warning()`)。由于逻辑等价(都走 `_check_first_run`),风险低,但建议补充一条 `import office` 在不可写场景下的冒烟测试,以锁住回归。 + +## 五、安全与高危调用检查 +- 无硬编码凭据 / 密钥泄露 ✅ +- 无 `panic()` / `os._exit()` / `process.exit()` 等高危调用 ✅ +- `print()` 仅出现在 `if __name__ == "__main__":` 测试块(compatibility.py:244-250),非生产路径 ✅ + +## 六、整体裁决 + +### 🟡 NEEDS ATTENTION + +**理由**:改动方向正确、核心修复(`_check_first_run` 的 OSError 保护)真实有效且安全,回归测试到位;但 PR 描述与实际生效范围存在偏差——真正的 import-time 副作用入口 `office/__init__.py:5` 未被触及。建议合入前: + +1. **澄清/对齐描述**:将"remove module-level compatibility checking to avoid import-time side effects"修正为"移除 `compatibility.py` 的重复模块级检查(消除双重提示),并保护标记文件写入"; +2. **(可选)彻底去副作用**:若项目确实要求 `import office` 零副作用,进一步移除 `office/__init__.py:5` 并改为延迟调用; +3. **补充** `import office` 端到端不可写冒烟测试; +4. **仓库卫生**:清理 `build/lib/` 构建产物、更新 `ISSUES_AUDIT.md` 标注。 + +**优先级排序**:① 描述澄清(必须,避免误解)→ ② 端到端测试(建议)→ ③ 彻底去副作用 / 仓库卫生(可选,后续跟进)。 + +--- +*生成时间:2026-08-04 | 审查人:PR 代码审查专家(本地静态分析,未发布 GitHub 评论)* diff --git a/README-CN.md b/README-CN.md index 75bf9af6..9a69b46e 100644 --- a/README-CN.md +++ b/README-CN.md @@ -63,7 +63,7 @@ import office # 一行导入,所有功能立刻可用 | 🤖 **AI 友好** | 每个 Skill 都有 `SKILL.md` + YAML 描述,Codex/Claude/Cursor 可直接识别 | | 🌏 **中文优先** | 全中文文档、视频教程、微信答疑群 | | 🪶 **轻量灵活** | 不需要的功能可以不安装:`pip install popdf` / `poimage` / `poword` | -| 🔄 **持续更新** | 2020 起持续维护,73+ 功能仍在迭代 | +| 🔄 **持续更新** | 持续维护中,73+ 功能仍在迭代 | | 📦 **一次安装** | `import office` 即引入全部能力;不想要也可单独 import | | 🛡️ **稳定可靠** | 已被数千个项目使用,MIT 开源 | diff --git a/README.md b/README.md index e75c367e..ecf3e398 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ import office # one import, all features available | 🤖 **AI-friendly** | Each Skill ships `SKILL.md` + YAML, recognizable by Codex / Claude / Cursor | | 🌏 **Beginner-friendly** | Full tutorials, video guides, and an active WeChat community | | 🪶 **Lightweight** | `pip install popdf / poimage / poword` for sub-libraries — no bloat | -| 🔄 **Continuously updated** | Maintained since 2020, 73+ features still evolving | +| 🔄 **Continuously updated** | Actively maintained, with 73+ features still evolving | | 📦 **One import** | `import office` brings everything; or import individually | | 🛡️ **Stable** | Used by thousands of projects, MIT licensed | diff --git a/contributors/77x2 b/contributors/77x2 new file mode 100644 index 00000000..5b9fd2b8 --- /dev/null +++ b/contributors/77x2 @@ -0,0 +1 @@ +qinandenixiangnwom diff --git a/contributors/NWTNaldo/merge_docx_fix.py b/contributors/NWTNaldo/merge_docx_fix.py new file mode 100644 index 00000000..94884739 --- /dev/null +++ b/contributors/NWTNaldo/merge_docx_fix.py @@ -0,0 +1,63 @@ +import os +import re +from docx import Document +from docxcomposer import Composer + +def merge4docx(input_path: str, output_path: str, new_word_name: str = "merged.docx") -> str: + """ + 合并指定文件夹下的所有 .docx 文件 + + :param input_path: 输入 Word 文件的文件夹路径 + :param output_path: 合并后 Word 文件的输出文件夹路径 + :param new_word_name: 合并后的新文件名(如 "111.docx") + :return: 合并后文件的完整输出路径 + """ + # 1. 自动处理目录路径与创建 + if not os.path.exists(output_path): + os.makedirs(output_path, exist_ok=True) + + # 2. 规范化文件名(防止重复拼接 .docx 后缀) + if not new_word_name.lower().endswith('.docx'): + new_word_name = f"{new_word_name}.docx" + + final_output_file = os.path.join(output_path, new_word_name) + + # 3. 过滤临时文件(以 ~$ 开头)并仅保留 .docx 格式文件 + all_files = [ + f for f in os.listdir(input_path) + if f.lower().endswith('.docx') and not f.startswith('~$') + ] + + # 4. 自然排序算法(确保 1.docx, 2.docx, 10.docx 按常规数字顺序合并) + def natural_sort_key(filename: str): + return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', filename)] + + all_files.sort(key=natural_sort_key) + + if not all_files: + raise FileNotFoundError(f"在路径 '{input_path}' 下未找到有效的 .docx 文件") + + # 5. 排除输出文件本身(防止同目录合并时递归循环) + files_to_merge = [] + for file in all_files: + full_path = os.path.abspath(os.path.join(input_path, file)) + if full_path == os.path.abspath(final_output_file): + continue + files_to_merge.append(full_path) + + if not files_to_merge: + raise ValueError("没有可用于合并的目标文件") + + # 6. 以第一个文件为主文档初始化 Composer + master_doc = Document(files_to_merge[0]) + composer = Composer(master_doc) + + # 7. 依次合并后续文件并添加分页符 + for file_path in files_to_merge[1:]: + doc_to_append = Document(file_path) + master_doc.add_page_break() # 在文档末尾追加分页 + composer.append(doc_to_append) + + # 8. 保存合并后的文档 + composer.save(final_output_file) + return final_output_file diff --git a/contributors/rs1973/process_img1.py b/contributors/rs1973/process_img1.py new file mode 100644 index 00000000..bfd7d970 --- /dev/null +++ b/contributors/rs1973/process_img1.py @@ -0,0 +1,139 @@ +"""" +Creator:rs1973 +E-mail:dingzheng_2023@qq.com/gunshi98@gmail.com +Description:支持输入一个目录或一张图片,修改它(或者整个目录里)的图片尺寸,色彩通道,并决定是否留下图像的 +alpha值,会自动筛选不是图片或不支持的格式 程序为多线程(多进程下使用笔记本测试时cpu过热),但gif合成 +暂时不支持多线程 + +ps:这是我的第一个项目,有很多做得不够好的地方,请多包容 +""" + +import os +import time +from concurrent.futures import ThreadPoolExecutor +from PIL import Image, ImageOps + +def get_img(srcpath=None, sinfile=None): + """筛选目录中的非图片文件,只筛选一层,不读取子目录里的文件""" + + img_lst = [] + not_img = '' + if srcpath: + for dirpath, dirname, filenames in os.walk(srcpath): + if filenames: + for img in filenames: + img = os.path.join(dirpath, img) + if os.path.isfile(img): + if os.path.splitext(img)[1].lower() in {".jpg", ".jpeg", ".png", ".bmp", ".tiff", '.webp'}: + img_lst.append(img) + else: + not_img += f'{img}\n' + else: + print(f'注意: 目录 {dirpath} 中没有图片') + return [] + + if not_img: + print(f'提示: 以下文件/目录不是图片:\n{not_img}') + return img_lst + + if sinfile: + if os.path.splitext(sinfile)[1].lower() in {".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff", '.webp'}: + return [sinfile] + else: + print(f'错误: 文件 {sinfile} 不是图片') + return [] + + +def normal_img(im, input_info: tuple, outpath: str, kind: str, img: str, alpha: bool): + """图像的缩放处理,每一个格式都会用到""" + if input_info: + x, y = input_info + if round(int(x) / im.size[0], 2) == round(int(y) / im.size[1], 2): + real_tuple = (int(x), int(y)) + im = im.resize(real_tuple) + else: + if not alpha: + pad_im = ImageOps.pad(im, (int(x), int(y)), color='#FFFFFF') + else: + pad_im = ImageOps.pad(im, (int(x), int(y)), + color=(0, 0, 0, 0), centering=(0.5, 0.5)) + + im = pad_im + + base_name = os.path.basename(img) + name_only = os.path.splitext(base_name)[0] + save_path = os.path.join(outpath, name_only + kind) + im.save(save_path, format=kind[1:].upper()) + im.close() + + +def gif(filenames=None, outpath=None, duration=300, name='index'): + """合成gif""" + try: + img_lst = [Image.open(i).copy().convert('RGB') for i in filenames] + img_lst[0].save( + os.path.join(outpath, f'{name}.gif'), + append_images=img_lst[1:], + duration=duration, + loop=0, + optimize=True + ) + except ValueError as e: + print(f'错误: 序列中图片大小不一致, {e}') + + +def process_img(outpath=None, input_info=None, kind=None, alpha=None, img=None): + """修改图片中的alpha""" + if kind in ('.png', '.webp', '.bmp'): + with Image.open(img) as im: + im = im.convert('RGBA') + if not alpha: + new_im = im.copy() + new_im.convert('RGB') + alpha_pixel = im.getdata() + write_pixel = [] + for item in alpha_pixel: + r, g, b, a = item + if a == 0: + write_pixel.append((255, 255, 255)) + else: + write_pixel.append((r, g, b)) + new_im.putdata(write_pixel) + im = new_im + normal_img(im, input_info, outpath, kind, img, alpha) + else: + with Image.open(img) as im: + if im.mode == 'RGBA': + im = im.convert('RGB') + normal_img(im, input_info, outpath, kind, img, alpha) + + +def main(srcpath: str = None, outpath: str = None, sinfile: str = None, + img_size: tuple = None, kind: str = '.jpeg', alpha: bool = False, + duration: int = 300, process: int = int(os.cpu_count()//2), name='index'): + """主逻辑函数""" + print('开始处理图片……') + start = time.time() + + filenames = get_img(srcpath, sinfile) + if not filenames: + return + + if kind == '.gif': + print('注意:请确保图像列表中所有图片的大小都一样') + gif(filenames, outpath, duration, name) + else: + with ThreadPoolExecutor(process) as pool: + futures = [pool.submit(process_img, outpath, + img_size, kind, alpha, img) for img in filenames] + for fut in futures: + fut.result() + + end = time.time() + print(f'处理完成, 耗时: {end - start:.2f}s') + +# src = r"C:\Users\rollingstone\OneDrive\Desktop\001" +# out = r"C:\Users\rollingstone\OneDrive\Desktop\s\re" + +# if __name__ == '__main__': +# main(srcpath=src, outpath=out, alpha=False, kind='.gif', name='hello', duration=250) diff --git a/contributors/rs1973/readme.md b/contributors/rs1973/readme.md new file mode 100644 index 00000000..3521029e --- /dev/null +++ b/contributors/rs1973/readme.md @@ -0,0 +1,46 @@ +# 批量图片尺寸与通道处理工具 + +**Creator:** rs1973 +**E-mail:** dingzheng_2023@qq.com / gunshi98@gmail.com + +本工具支持对 **单张图片** 或 **整个目录的全部图片** 进行批量处理,包括: + +- 调整图片尺寸 +- 统一色彩通道(可选择去除或保留透明通道 alpha) +- 批量导出到指定目录 +- 支持 `.jpg / .jpeg / .png / .bmp / .tiff / .webp` 格式 +- 支持 GIF 合成(单线程) + +程序内部使用 **多线程** 加速大量图片处理,默认为5线程。 + +--- + +## 功能特点 + +| 功能 | 说明 | +|-----|----------------------------------------------------------------| +| 批量筛选图片 | 自动忽略非图片文件 | +| 多线程处理 | 提升处理速度,默认为5线程 | +| 支持保留 / 去除透明通道 | 当输出格式支持alpha,可以选择保留或丢弃,丢弃时会将原本的alpha像素替换成白色(后续会添加颜色选择选项) | +| 自适应缩放或填充模式 | 保证目标尺寸一致:当目标大小小于原图时,会缩放/拉伸原图,大于且长宽比例与目标大小相同时,则直接缩放,反之则会用白色填充图片 | +| GIF 合成 | 可根据延迟参数调节帧率,默认300ms/帧 | + +--- + +## 基本使用示例 + +```python +from contributors.rs1973.process_img1.py import main + +src = r"C:\path\to\input_dir" +out = r"C:\path\to\output_dir" +size = (1000, 1000) + +main( + srcpath=src, + outpath=out, + img_size=size, + alpha=False, # 是否保留透明通道 + kind='.png', # 输出格式 + duration=300 # GIF 合成时的帧间隔,仅在 kind='.gif' 时使用 +) \ No newline at end of file diff --git a/docs/architecture/python-office-architecture.gif b/docs/architecture/python-office-architecture.gif new file mode 100644 index 00000000..390173e8 Binary files /dev/null and b/docs/architecture/python-office-architecture.gif differ diff --git a/docs/architecture/python-office-architecture.html b/docs/architecture/python-office-architecture.html new file mode 100644 index 00000000..13708685 --- /dev/null +++ b/docs/architecture/python-office-architecture.html @@ -0,0 +1,528 @@ + + + + +python-office 架构图 — 手绘涂鸦风 + + + +
+ + + + + + + + + + + + + + + + + + +python-office +一库聚合 · 一行代码办一场公 + + +架构图 +v 1.0.6 · since 2020 + + +✦ 码要少,事儿要办好 ✦ + + + + + + 1 + 入口 · Entry 一行代码就上场 + + + + + $ pip install python-office + + + + + + + import office + + + + install + + + + office.excel.fake2excel() # 73 个开箱即用技能 + + + + + + + + + + + + 2 + 技能集合 · Skills 73 个独立 SKILL.md 可被 AI 直接识别 + + + + + + + + + + fake2excel + 模拟数据 / Excel + + + + + + merge4ppt + 合并 PPT / 演示 + + + + + + encrypt4pdf + PDF 加密 / 安全 + + + + + + add_watermark + 图片加水印 + + + + + + send_message + 微信群发 / Win + + + + + + doc2docx + Word 互转 / Win + + + + 67 more… + + + + +按需 +懒加载 + + + + +路由 + + + + + + + 3 + 接口层 · office.api.* 14 个 python 文件 = 14 个能力门 + + + + + + + + + E + excel.py + fake / merge / split + + + + + W + word.py + doc2docx / 合并 + + + + + P + ppt.py + ppt2pdf / 合并 + + + + + P + pdf.py + 加密 / 转换 + + + + + I + image.py + 去水印 / 词云 + + + + + W + wechat.py + 聊天 / 群发 + + + + + V + video.py + 视频处理 + + + + +委托 + + + + + + + 4 + 实现层 · office.lib/* 真正的活儿都在这里干 + + + + + + + + excel/ + SplitExcel + + + + image/ + add_watermark · 去背景 + + + + pdf/ + add_watermark_service + + + + ppt/ + ppt2pdf_service + + + + tools/ + weather · lottery · wifi + + + + utils/ + time · except · pandas_mem + + + + + + + + + + + + +调用 + + + + + + + 5 + 底层依赖 · po* 7 个跨平台 + 3 个仅 Windows + + + + + + + poexcel + + + popdf + + + poimage + + + poocr + + + poemail + + + povideo + + + Win: poppt/poword + + + + wftools + + pofile + + pomarkdown + + pofinance + + pocode + + you-get + + Python ≥ 3.6 + + + + + + + + + + + + + + + + +仅 Windows + + + + +跨平台 + + + + +人用 office + + + + + + + 6 + 运行环境 · 你在哪儿跑都行 + + + + + + + + Windows: Word · PPT · PyOfficeRobot + + + + macOS · Linux 都能吃饭 + + + + 工程师 · IDE · 教程视频 + + + + python4office.cn · QQ 909163033 + + + + + + v1.0.6 + 2020- + + + +
+ + + + + diff --git a/docs/skills-import-optimization-report.md b/docs/skills-import-optimization-report.md new file mode 100644 index 00000000..a0490cc2 --- /dev/null +++ b/docs/skills-import-optimization-report.md @@ -0,0 +1,219 @@ +# python-office Skills 导入优化对比报告 + +## 1. 对比基线 + +- 项目目录:`E:\项目\python-office` +- 分支基线:`develop` +- 原项目基线提交:`2b1996b557c76a233642e261ae62da92b5dfa73e` +- 基线提交说明:`fix: 修复拆分Excel缺少tqdm导入、废弃API及抠图颜色提取引发的程序崩溃问题 (#161)` +- 对比方式:优化分支与上述 Git 提交进行比较。 + +## 2. 原项目存在的问题 + +项目 README 推荐如下用法: + +```python +from skills.pdf import pdf2docx +from skills.image import compress_image +from skills.tools import qrcodetools +``` + +但各分类包的 `__init__.py` 实际引用了不存在的 `office.skills`: + +```python +from office.skills.pdf.pdf2docx import pdf2docx +``` + +仓库中没有 `office/skills` 包,因此按 README 操作会出现: + +```text +ModuleNotFoundError: No module named 'office.skills' +``` + +这会导致 Skills 功能虽然已经编写,但用户无法通过项目公开入口导入。 + +## 3. 本次优化内容 + +### 3.1 修复分类包导入方式 + +将分类入口由不存在的绝对路径改成包内相对导入。 + +修改前: + +```python +from office.skills.pdf.pdf2docx import pdf2docx +``` + +修改后: + +```python +from .pdf2docx import pdf2docx +``` + +这样分类入口会调用仓库中真实存在的 `skills/<分类>/<功能>/__init__.py`,再由功能入口连接到 `office.api`。 + +### 3.2 统一 Skills 文档 + +将 Skills 文档里的错误示例: + +```python +from office.skills.pdf import pdf2docx +``` + +统一改为项目真实可用的公开入口: + +```python +from skills.pdf import pdf2docx +``` + +### 3.3 新增回归测试 + +新增 `tests/test_code/test_skills_imports.py`,自动检查: + +- 13 个 Skills 分类都能导入; +- 每个分类都有公开导出列表 `__all__`; +- 73 个公开导出对象都存在且可以调用; +- 后续修改不会再次引入同类导入错误。 + +## 4. 修改文件统计 + +| 类型 | 数量 | 说明 | +|---|---:|---| +| 已修改 Python 文件 | 14 | Skills 根说明及 13 个分类入口 | +| 已修改 Markdown 文件 | 74 | Skills 总索引及 73 个功能文档 | +| 新增测试文件 | 1 | Skills 公共导入回归测试 | +| 新增报告文件 | 1 | 本优化对比报告 | +| 合计涉及文件 | 90 | 88 个已有文件加 2 个新文件 | + +已有文件的 Git 文本差异为 228 行新增、228 行删除,全部属于导入路径替换;另新增回归测试和本报告。 + +## 5. Python 代码文件清单 + +以下 14 个已有 Python 文件被修改: + +1. `skills/__init__.py`:修正文档字符串中的示例导入路径。 +2. `skills/excel/__init__.py`:Excel 分类改用相对导入。 +3. `skills/file/__init__.py`:文件处理分类改用相对导入。 +4. `skills/finance/__init__.py`:金融分类改用相对导入。 +5. `skills/image/__init__.py`:图片分类改用相对导入。 +6. `skills/markdown/__init__.py`:Markdown 分类改用相对导入。 +7. `skills/ocr/__init__.py`:OCR 分类改用相对导入。 +8. `skills/pdf/__init__.py`:PDF 分类改用相对导入。 +9. `skills/ppt/__init__.py`:PPT 分类改用相对导入。 +10. `skills/ruiming/__init__.py`:实验 API 分类改用相对导入。 +11. `skills/tools/__init__.py`:工具分类改用相对导入。 +12. `skills/video/__init__.py`:视频分类改用相对导入。 +13. `skills/wechat/__init__.py`:微信分类改用相对导入。 +14. `skills/word/__init__.py`:Word 分类改用相对导入。 + +新增文件: + +- `tests/test_code/test_skills_imports.py`:Skills 分类和 73 个公开导出的回归测试。 + +## 6. Markdown 文档文件清单 + +### 总索引 + +- `skills/README.md` + +### Excel(7 个) + +- `skills/excel/{excel2pdf,fake2excel,find_excel_data,merge2excel,merge2sheet,sheet2excel,split_excel_by_column}/SKILL.md` + +### 文件处理(9 个) + +- `skills/file/{add_line_by_type,file_name_add_postfix,file_name_add_prefix,file_name_insert_content,get_files,group_by_name,output_file_list_to_excel,replace4filename,search_specify_type_file}/SKILL.md` + +### 金融(1 个) + +- `skills/finance/t0/SKILL.md` + +### 图片(9 个) + +- `skills/image/{add_watermark,compress_image,decode_qrcode,del_watermark,down4img,image2gif,img2Cartoon,pencil4img,txt2wordcloud}/SKILL.md` + +### Markdown(1 个) + +- `skills/markdown/excel2markdown/SKILL.md` + +### OCR(1 个) + +- `skills/ocr/VatInvoiceOCR2Excel/SKILL.md` + +### PDF(13 个) + +- `skills/pdf/{add_img_water,add_mark,add_text_watermark,add_watermark,add_watermark_by_parameters,decrypt4pdf,del4pdf,encrypt4pdf,merge2pdf,pdf2docx,pdf2imgs,split4pdf,txt2pdf}/SKILL.md` + +### PPT(3 个) + +- `skills/ppt/{merge4ppt,ppt2img,ppt2pdf}/SKILL.md` + +### 实验 API(3 个) + +- `skills/ruiming/{change_label_in_xml,screen_unmarked_image,screen_without_label_json_file}/SKILL.md` + +### 工具(10 个) + +- `skills/tools/{course,create_article,lottery8ticket,net_speed_test,passwordtools,pwd4wifi,qrcodetools,transtools,url2ip,weather}/SKILL.md` + +### 视频(4 个) + +- `skills/video/{audio2txt,mark2video,txt2mp3,video2mp3}/SKILL.md` + +### 微信(7 个) + +- `skills/wechat/{chat_by_keywords,chat_robot,group_send,receive_message,send_file,send_message,send_message_by_time}/SKILL.md` + +### Word(5 个) + +- `skills/word/{doc2docx,docx2doc,docx2pdf,docx4imgs,merge4docx}/SKILL.md` + +## 7. 优化后的效果 + +以下公开调用方式现已可用: + +```python +from skills.pdf import pdf2docx +from skills.image import compress_image +from skills.tools import qrcodetools +from skills.excel import fake2excel +``` + +本次修复覆盖 13 个分类和 73 个公开功能,使 README、Skills 文档与实际包结构保持一致,也为未来桌面客户端通过统一入口发现和调用功能打下基础。 + +## 8. 验证结果 + +执行的专项测试: + +```powershell +.\venv\Scripts\python.exe -m unittest tests.test_code.test_skills_imports -v +``` + +结果: + +```text +Ran 1 test +OK +``` + +独立测试 Agent 还完成了以下复核: + +- 13 个分类全部导入成功; +- 73 个 `__all__` 导出全部存在且可调用; +- README 常用导入全部通过; +- `setuptools.find_packages()` 能发现顶层 `skills` 及其子包; +- `git diff --check` 通过; +- `skills` 目录中已无残留的 `office.skills` 错误路径; +- 建议保留优化,无需回滚。 + +## 9. 本次没有修改的内容 + +- 没有修改 `office/api` 业务实现; +- 没有修改 PDF、Excel、Word、图片等功能的处理逻辑; +- 没有制作或修改桌面客户端; +- 没有提交用户创建的 `demo.py` 和 `qrcode.png`; +- 没有逐个执行可能修改文件、发送微信或调用外部 API 的功能。 + +## 10. 已知提示 + +Git 在 Windows 上提示部分 Python 文件未来可能由 LF 转换为 CRLF。`git diff --check` 已通过,该提示不影响本次功能,但后续可通过统一 `.gitattributes` 作为单独优化项处理。 diff --git "a/examples/poexcel/\345\220\210\345\271\2662\344\270\252Excel\347\232\204\345\206\205\345\256\271\345\210\260\344\270\200\344\270\252sheet\344\270\255.py" "b/examples/poexcel/\345\220\210\345\271\2662\344\270\252Excel\347\232\204\345\206\205\345\256\271\345\210\260\344\270\200\344\270\252sheet\344\270\255.py" index 69ea97d7..588503b9 100644 --- "a/examples/poexcel/\345\220\210\345\271\2662\344\270\252Excel\347\232\204\345\206\205\345\256\271\345\210\260\344\270\200\344\270\252sheet\344\270\255.py" +++ "b/examples/poexcel/\345\220\210\345\271\2662\344\270\252Excel\347\232\204\345\206\205\345\256\271\345\210\260\344\270\200\344\270\252sheet\344\270\255.py" @@ -21,7 +21,17 @@ https://www.python-office.com """ +# 导入 poexcel 模块,该模块封装了对 Excel 文件的常用操作 import poexcel -poexcel.merge2sheet(dir_path=r'D:\workplace\code\github\python-office\tests\test_files\excel\merge2sheet', - output_sheet_name=r'platform', output_excel_name=r'./output/merge2sheet') +# 调用 poexcel 模块中的 merge2sheet 函数 +# 该函数的作用是将指定文件夹下的多个 Excel 文件合并到一个 Excel 文件的不同工作表中 +# 参数说明: +# - dir_path: 存放多个 Excel 文件的文件夹路径(原始字符串格式,避免转义问题) +# - output_sheet_name: 输出 Excel 中每个子表的命名规则或固定名称(例如根据文件名命名或统一命名) +# - output_excel_name: 合并后的输出 Excel 文件路径及文件名(原始字符串格式) +poexcel.merge2sheet( + dir_path=r'D:\workplace\code\github\python-office\tests\test_files\excel\merge2sheet', + output_sheet_name=r'platform', + output_excel_name=r'./output/merge2sheet' +) \ No newline at end of file diff --git "a/examples/poexcel/\345\220\210\345\271\266\345\244\232\344\270\252Excel\345\210\260\344\270\200\344\270\252Excel\347\232\204\344\270\215\345\220\214sheet\344\270\255.py" "b/examples/poexcel/\345\220\210\345\271\266\345\244\232\344\270\252Excel\345\210\260\344\270\200\344\270\252Excel\347\232\204\344\270\215\345\220\214sheet\344\270\255.py" index 73bcf673..e7e9b1ca 100644 --- "a/examples/poexcel/\345\220\210\345\271\266\345\244\232\344\270\252Excel\345\210\260\344\270\200\344\270\252Excel\347\232\204\344\270\215\345\220\214sheet\344\270\255.py" +++ "b/examples/poexcel/\345\220\210\345\271\266\345\244\232\344\270\252Excel\345\210\260\344\270\200\344\270\252Excel\347\232\204\344\270\215\345\220\214sheet\344\270\255.py" @@ -17,6 +17,17 @@ ... output_file='test_merge2excel.xlsx') """ +# 导入 office 模块,这是一个用于处理办公文档(如 Excel、Word、PPT)的 Python 工具库 import office -office.excel.merge2excel(dir_path=r'../../contributors/bulabean', output_file='test_merge2excel.xlsx', ) +# 调用 office 模块中的 excel 子模块下的 merge2excel 函数 +# 该函数的作用是将指定文件夹下的所有 Excel 文件(.xlsx / .xls)合并为一个 Excel 文件 +# 参数说明: +# - dir_path: 存放多个 Excel 文件的文件夹路径,支持相对路径或绝对路径 +# 此处使用的是相对路径 '../../contributors/bulabean' +# - output_file: 合并后输出的 Excel 文件名(字符串),例如 'test_merge2excel.xlsx' +# 输出路径默认为当前脚本所在目录,除非指定完整路径 +office.excel.merge2excel( + dir_path=r'../../contributors/bulabean', + output_file='test_merge2excel.xlsx' +) \ No newline at end of file diff --git "a/examples/poexcel/\346\240\271\346\215\256\346\214\207\345\256\232\347\232\204\345\210\227\357\274\214\346\213\206\345\210\206excel.py" "b/examples/poexcel/\346\240\271\346\215\256\346\214\207\345\256\232\347\232\204\345\210\227\357\274\214\346\213\206\345\210\206excel.py" index 0cb559c9..c4aea535 100644 --- "a/examples/poexcel/\346\240\271\346\215\256\346\214\207\345\256\232\347\232\204\345\210\227\357\274\214\346\213\206\345\210\206excel.py" +++ "b/examples/poexcel/\346\240\271\346\215\256\346\214\207\345\256\232\347\232\204\345\210\227\357\274\214\346\213\206\345\210\206excel.py" @@ -23,10 +23,17 @@ https://www.python-office.com """ +# 导入处理 Excel 的模块(poexcel 是一个用于操作 Excel 的 Python 工具库) import poexcel +# 调用 poexcel 模块中的函数:split_excel_by_column +# 该函数的作用是根据指定列的值,将一个 Excel 文件拆分成多个子文件 +# 参数说明: +# - filepath: 待拆分的原始 Excel 文件路径(必须为字符串,使用原始字符串 r'' 避免转义问题) +# - column: 根据哪一列进行拆分(索引从 0 开始,column=1 表示第二列) +# - worksheet_name: 指定要操作的工作表名称,默认为所有工作表,若指定则只处理该工作表 poexcel.split_excel_by_column( filepath=r'D:\workplace\code\github\python-office\demo\poexcel\excel\split_excel_by_column.xlsx', column=1, - worksheet_name='platform') - + worksheet_name='platform' +) diff --git a/office/__init__.py b/office/__init__.py index dfa1eec5..a52987e4 100644 --- a/office/__init__.py +++ b/office/__init__.py @@ -13,6 +13,7 @@ from office.api import ppt from office.api import tools from office.api import video +from office.api import web from office.api import wechat from office.api import word from office.api import markdown diff --git a/office/api/excel.py b/office/api/excel.py index 913dd7e5..126978b2 100644 --- a/office/api/excel.py +++ b/office/api/excel.py @@ -141,7 +141,11 @@ def split_excel_by_column(filepath: str, column: int, worksheet_name: str = None Returns: None """ - poexcel.split_excel_by_column(filepath=filepath, column=column, worksheet_name=worksheet_name) + split_excel = getattr(poexcel, "split_excel_by_column", None) + if split_excel is None: + from office.lib.excel.SplitExcel import split_excel_by_column as split_excel + + split_excel(filepath=filepath, column=column, worksheet_name=worksheet_name) def excel2pdf(excel_path, pdf_path, sheet_id: int = 0): diff --git a/office/api/video.py b/office/api/video.py index 5ca88774..3a5f8171 100644 --- a/office/api/video.py +++ b/office/api/video.py @@ -95,3 +95,16 @@ def txt2mp3(content='程序员晚枫', file=None, mp3=r'./程序员晚枫.mp3', None """ return povideo.txt2mp3(content=content, file=file, mp3=mp3, speak=speak) + + +from office.lib.video.video_edit_service import ( + _parse_time, + cut_video, + cut_audio, + crop_video, + concat_videos, + concat_audios, + add_audio_to_video, +) + + diff --git a/office/api/web.py b/office/api/web.py index f24d36a0..af6bc225 100644 --- a/office/api/web.py +++ b/office/api/web.py @@ -1,6 +1,23 @@ # -*- coding:utf-8 -*- -import pospider + +def _load_pospider(): + try: + import pospider + except ModuleNotFoundError as exc: + if exc.name != "pospider": + raise + raise ModuleNotFoundError( + "网页转电子书功能依赖 pospider,请先安装 pospider。" + ) from exc + try: + pospider.url.url2ebook + except AttributeError as exc: + raise ImportError( + "当前 pospider 版本不提供 url.url2ebook,请安装兼容版本。" + ) from exc + return pospider + def url2ebook(url, tile): """将指定的URL转换为电子书格式。 @@ -14,4 +31,5 @@ def url2ebook(url, tile): Returns: None,但会生成电子书文件 """ + pospider = _load_pospider() pospider.url.url2ebook(url=url, tile=tile) diff --git a/office/compatibility.py b/office/compatibility.py index 1a0c6ba6..c7375a61 100644 --- a/office/compatibility.py +++ b/office/compatibility.py @@ -27,14 +27,18 @@ def _check_first_run(self) -> bool: Returns: bool: 如果是首次运行返回True,否则返回False """ - # 创建标记目录 - self.mark_file.parent.mkdir(exist_ok=True) - - # 如果标记文件不存在,则是首次运行 - if not self.mark_file.exists(): - # 创建标记文件 - self.mark_file.write_text(f"First run on {platform.system()} at {platform.platform()}") - return True + try: + # 创建标记目录 + self.mark_file.parent.mkdir(exist_ok=True) + + # 如果标记文件不存在,则是首次运行 + if not self.mark_file.exists(): + # 创建标记文件 + self.mark_file.write_text(f"First run on {platform.system()} at {platform.platform()}") + return True + except OSError: + # 兼容性提示不应影响主包导入;HOME 只读或不可写时跳过首次运行提示。 + return False return False def get_compatibility_info(self) -> Dict[str, List[str]]: @@ -235,10 +239,6 @@ def check_compatibility(): return checker -# 在模块导入时自动检查兼容性 -compatibility_checker = check_compatibility() - - if __name__ == "__main__": # 测试代码 checker = CrossPlatformCompatibility() @@ -247,4 +247,4 @@ def check_compatibility(): print(f"标记文件: {checker.mark_file}") # 显示警告(仅在非Windows且首次运行时) - checker.display_warning() \ No newline at end of file + checker.display_warning() diff --git a/office/lib/decorator_utils/instruction_url.py b/office/lib/decorator_utils/instruction_url.py index 09785272..885aa69b 100644 --- a/office/lib/decorator_utils/instruction_url.py +++ b/office/lib/decorator_utils/instruction_url.py @@ -119,10 +119,11 @@ def instruction(func): @wraps(func) def instruction_wrapper(*args, **kwargs): func_filename = os.path.basename(func.__code__.co_filename) # 取出方法所在的文件名 + instruction_url = instruction_file_dict.get(func_filename, {}).get(func.__name__) # 如果有这个文件,并且已经配置了方法名对应的说明链接,则打印出来 - if func_filename in instruction_file_dict.keys() and instruction_file_dict[func_filename][func.__name__]: + if instruction_url: random_color_print( - f'正在运行:office.{os.path.basename(func_filename)[:-3]}.{func.__name__} , 这个方法的使用说明:{instruction_file_dict[func_filename][func.__name__]}') + f'正在运行:office.{os.path.basename(func_filename)[:-3]}.{func.__name__} , 这个方法的使用说明:{instruction_url}') random_color_print(SPLIT_LINE) instruction_res = func(*args, **kwargs) return instruction_res diff --git a/office/lib/pdf/add_watermark_service.py b/office/lib/pdf/add_watermark_service.py index 5ed5c7ce..4fcf0a8f 100644 --- a/office/lib/pdf/add_watermark_service.py +++ b/office/lib/pdf/add_watermark_service.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- import reportlab -from PyPDF2 import PdfFileWriter, PdfFileReader, PdfReader, PdfWriter +from PyPDF2 import PdfReader, PdfWriter from reportlab.pdfgen import canvas from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase.pdfmetrics import registerFont @@ -44,29 +44,42 @@ def pdf_add_watermark(pdf_file_in: str, pdf_file_mark: str, pdf_file_out: str) - """ # print(pdf_file_out) pdf_output = PdfWriter() - input_stream = open(pdf_file_in, 'rb') - pdf_input = PdfReader(input_stream, strict=False) - # 获取PDF文件的页数 - if pdf_input.is_encrypted: - print("文件已被加密") - PDF_Passwd = input("请输入PDF密码:") - # 尝试用空密码解密 - try: - pdf_input.decrypt(PDF_Passwd) - except Exception: - print(f"尝试用密码{PDF_Passwd}解密失败.") + input_stream = None + mark_stream = None + try: + input_stream = open(pdf_file_in, 'rb') + pdf_input = PdfReader(input_stream, strict=False) + # 获取PDF文件的页数 + if pdf_input.is_encrypted: + print("文件已被加密") + PDF_Passwd = input("请输入PDF密码:") + # 尝试用空密码解密 + try: + pdf_input.decrypt(PDF_Passwd) + except Exception: + print(f"尝试用密码{PDF_Passwd}解密失败.") + return False + pageNum = len(pdf_input.pages) + # 读入水印pdf文件 + # print(pdf_file_mark) + mark_stream = open(pdf_file_mark, mode='rb') + pdf_watermark = PdfReader(mark_stream, strict=False) + # 检查水印PDF是否有效(至少包含一页) + if len(pdf_watermark.pages) == 0: + print(f"水印文件不包含任何页面:{pdf_file_mark}") return False - pageNum = len(pdf_input.pages) - # 读入水印pdf文件 - # print(pdf_file_mark) - mark_stream = open(pdf_file_mark, mode='rb') - pdf_watermark = PdfReader(mark_stream, strict=False) - # 给每一页打水印 - for pageNumber in tqdm(range(pageNum)): - page = pdf_input.pages[pageNumber] - page.merge_page(pdf_watermark.pages[0]) - page.compress_content_streams() # 压缩内容 - pdf_output.add_page(page) - with open(pdf_file_out, 'wb') as pdf_file_out_f: - pdf_output.write(pdf_file_out_f) - return True + # 给每一页打水印 + for pageNumber in tqdm(range(pageNum)): + page = pdf_input.pages[pageNumber] + page.merge_page(pdf_watermark.pages[0]) + page.compress_content_streams() # 压缩内容 + pdf_output.add_page(page) + with open(pdf_file_out, 'wb') as pdf_file_out_f: + pdf_output.write(pdf_file_out_f) + return True + finally: + # 无论成功失败,都确保输入流和水印流被关闭,避免批量处理时文件句柄泄漏 + if input_stream is not None: + input_stream.close() + if mark_stream is not None: + mark_stream.close() diff --git a/office/lib/utils/pandas_mem.py b/office/lib/utils/pandas_mem.py index 3eb6661f..b6cf9243 100644 --- a/office/lib/utils/pandas_mem.py +++ b/office/lib/utils/pandas_mem.py @@ -29,7 +29,7 @@ def reduce_pandas_mem_usage(df) -> object: elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max: df[col] = df[col].astype(np.int64) else: - if 'date' in col: + if 'date' in str(col).lower(): pass else: df[col] = df[col].astype('category') diff --git a/office/lib/video/__init__.py b/office/lib/video/__init__.py new file mode 100644 index 00000000..2f74af27 --- /dev/null +++ b/office/lib/video/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +"""Video lib service package.""" diff --git a/office/lib/video/video_edit_service.py b/office/lib/video/video_edit_service.py new file mode 100644 index 00000000..b4485217 --- /dev/null +++ b/office/lib/video/video_edit_service.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +"""Video and Audio editing services. + +音视频剪辑服务模块(截取、画面裁剪、音视频拼接、合成/替换音频)。 +""" + +import os +from moviepy import VideoFileClip, AudioFileClip, concatenate_videoclips, concatenate_audioclips + + +def _parse_time(t): + if t is None: + return None + if isinstance(t, (int, float)): + return float(t) + if isinstance(t, str): + t = t.strip() + parts = t.split(':') + if len(parts) == 1: + return float(parts[0]) + elif len(parts) == 2: + return float(parts[0]) * 60 + float(parts[1]) + elif len(parts) == 3: + return float(parts[0]) * 3600 + float(parts[1]) * 60 + float(parts[2]) + return float(t) + + +def cut_video(video_path, start_time=0, end_time=None, output_path=r'./', output_name=None): + """Cut / trim a video file to specified time range. + + 剪辑/截取视频指定时间段。 + + Args: + video_path (str): video file path / 视频文件路径 + start_time (float|str, optional): start time in seconds or "HH:MM:SS" / 开始时间。Default / 默认: 0 + end_time (float|str, optional): end time in seconds or "HH:MM:SS" / 结束时间。Default / 默认: None + output_path (str, optional): output directory / 输出目录。Default / 默认: './' + output_name (str, optional): output filename / 输出文件名。Default / 默认: None + """ + os.makedirs(output_path, exist_ok=True) + if not output_name: + base_name = os.path.basename(video_path) + name, ext = os.path.splitext(base_name) + output_name = f"{name}_cut{ext if ext else '.mp4'}" + out_file = os.path.join(output_path, output_name) + + st = _parse_time(start_time) + et = _parse_time(end_time) + + clip = VideoFileClip(video_path) + try: + if hasattr(clip, 'subclipped'): + sub = clip.subclipped(st, et) + else: + sub = clip.subclip(st, et) + sub.write_videofile(out_file) + finally: + clip.close() + + +def cut_audio(audio_path, start_time=0, end_time=None, output_path=r'./', output_name=None): + """Cut / trim an audio file to specified time range. + + 剪辑/截取音频指定时间段。 + + Args: + audio_path (str): audio file path / 音频文件路径 + start_time (float|str, optional): start time in seconds or "HH:MM:SS" / 开始时间。Default / 默认: 0 + end_time (float|str, optional): end time in seconds or "HH:MM:SS" / 结束时间。Default / 默认: None + output_path (str, optional): output directory / 输出目录。Default / 默认: './' + output_name (str, optional): output filename / 输出文件名。Default / 默认: None + """ + os.makedirs(output_path, exist_ok=True) + if not output_name: + base_name = os.path.basename(audio_path) + name, ext = os.path.splitext(base_name) + output_name = f"{name}_cut{ext if ext else '.mp3'}" + out_file = os.path.join(output_path, output_name) + + st = _parse_time(start_time) + et = _parse_time(end_time) + + clip = AudioFileClip(audio_path) + try: + if hasattr(clip, 'subclipped'): + sub = clip.subclipped(st, et) + else: + sub = clip.subclip(st, et) + sub.write_audiofile(out_file) + finally: + clip.close() + + +def crop_video(video_path, x1=0, y1=0, x2=None, y2=None, width=None, height=None, output_path=r'./', output_name=None): + """Crop video screen region. + + 裁剪视频画面坐标和尺寸。 + + Args: + video_path (str): video file path / 视频文件路径 + x1 (int, optional): left x coordinate / 左上角 x 坐标。Default / 默认: 0 + y1 (int, optional): top y coordinate / 左上角 y 坐标。Default / 默认: 0 + x2 (int, optional): right x coordinate / 右下角 x 坐标。Default / 默认: None + y2 (int, optional): bottom y coordinate / 右下角 y 坐标。Default / 默认: None + width (int, optional): crop width / 裁剪宽度。Default / 默认: None + height (int, optional): crop height / 裁剪高度。Default / 默认: None + output_path (str, optional): output directory / 输出目录。Default / 默认: './' + output_name (str, optional): output filename / 输出文件名。Default / 默认: None + """ + os.makedirs(output_path, exist_ok=True) + if not output_name: + base_name = os.path.basename(video_path) + name, ext = os.path.splitext(base_name) + output_name = f"{name}_cropped{ext if ext else '.mp4'}" + out_file = os.path.join(output_path, output_name) + + clip = VideoFileClip(video_path) + try: + if hasattr(clip, 'cropped'): + cropped = clip.cropped(x1=x1, y1=y1, x2=x2, y2=y2, width=width, height=height) + elif hasattr(clip, 'crop'): + cropped = clip.crop(x1=x1, y1=y1, x2=x2, y2=y2, width=width, height=height) + else: + import moviepy.video.fx.all as vfx + cropped = vfx.crop(clip, x1=x1, y1=y1, x2=x2, y2=y2, width=width, height=height) + cropped.write_videofile(out_file) + finally: + clip.close() + + +def concat_videos(video_list, output_path=r'./', output_name=r'concat_video.mp4'): + """Concatenate multiple video files in sequence. + + 多个视频顺序拼接合并为一个视频文件。 + + Args: + video_list (list[str]): list of video file paths / 视频文件路径列表 + output_path (str, optional): output directory / 输出目录。Default / 默认: './' + output_name (str, optional): output filename / 输出文件名。Default / 默认: 'concat_video.mp4' + """ + os.makedirs(output_path, exist_ok=True) + out_file = os.path.join(output_path, output_name) + + clips = [VideoFileClip(v) for v in video_list] + try: + final_clip = concatenate_videoclips(clips) + final_clip.write_videofile(out_file) + finally: + for c in clips: + c.close() + + +def concat_audios(audio_list, output_path=r'./', output_name=r'concat_audio.mp3'): + """Concatenate multiple audio files in sequence. + + 多个音频顺序拼接合并为一个音频文件。 + + Args: + audio_list (list[str]): list of audio file paths / 音频文件路径列表 + output_path (str, optional): output directory / 输出目录。Default / 默认: './' + output_name (str, optional): output filename / 输出文件名。Default / 默认: 'concat_audio.mp3' + """ + os.makedirs(output_path, exist_ok=True) + out_file = os.path.join(output_path, output_name) + + clips = [AudioFileClip(a) for a in audio_list] + try: + final_clip = concatenate_audioclips(clips) + final_clip.write_audiofile(out_file) + finally: + for c in clips: + c.close() + + +def add_audio_to_video(video_path, audio_path, output_path=r'./', output_name=None): + """Add or replace audio track in a video file. + + 将音频合成/替换到视频文件中。 + + Args: + video_path (str): video file path / 视频文件路径 + audio_path (str): audio file path / 音频文件路径 + output_path (str, optional): output directory / 输出目录。Default / 默认: './' + output_name (str, optional): output filename / 输出文件名。Default / 默认: None + """ + os.makedirs(output_path, exist_ok=True) + if not output_name: + base_name = os.path.basename(video_path) + name, ext = os.path.splitext(base_name) + output_name = f"{name}_with_audio{ext if ext else '.mp4'}" + out_file = os.path.join(output_path, output_name) + + video_clip = VideoFileClip(video_path) + audio_clip = AudioFileClip(audio_path) + try: + if hasattr(video_clip, 'with_audio'): + final_clip = video_clip.with_audio(audio_clip) + else: + final_clip = video_clip.set_audio(audio_clip) + final_clip.write_videofile(out_file) + finally: + video_clip.close() + audio_clip.close() diff --git a/skills/README.md b/skills/README.md index af07cf11..c1f586c3 100644 --- a/skills/README.md +++ b/skills/README.md @@ -16,6 +16,7 @@ - [PPT 处理](#ppt-处理) - [Tools 工具](#tools-工具) - [Video 视频处理](#video-视频处理) +- [Web 网页处理](#web-网页处理) - [WeChat 微信](#wechat-微信) - [Word 文档处理](#word-文档处理) - [Ruiming 测试 API](#ruiming-测试-api) @@ -28,11 +29,11 @@ ```python # 方式 1:直接导入函数 -from office.skills.excel import fake2excel +from skills.excel import fake2excel fake2excel(rows=10) # 方式 2:导入子模块 -from office.skills.excel import fake2excel as fe +from skills.excel import fake2excel as fe fe(rows=10, columns=['name', 'phone']) ``` @@ -63,7 +64,7 @@ fe(rows=10, columns=['name', 'phone']) 调用示例: ```python -from office.skills.excel import fake2excel +from skills.excel import fake2excel fake2excel(columns=['name', 'phone'], rows=100, path='./test.xlsx') ``` @@ -85,7 +86,7 @@ fake2excel(columns=['name', 'phone'], rows=100, path='./test.xlsx') 调用示例: ```python -from office.skills.file import replace4filename +from skills.file import replace4filename replace4filename(path='./test_dir', del_content='old', replace_content='new') ``` @@ -99,7 +100,7 @@ replace4filename(path='./test_dir', del_content='old', replace_content='new') 调用示例: ```python -from office.skills.finance import t0 +from skills.finance import t0 profit = t0(buy_price=11.99, sale_price=12.26, shares=700) print(profit) ``` @@ -122,7 +123,7 @@ print(profit) 调用示例: ```python -from office.skills.image import add_watermark +from skills.image import add_watermark add_watermark(file='test.png', mark='python-office') ``` @@ -199,6 +200,23 @@ add_watermark(file='test.png', mark='python-office') | `audio2txt` | 音频提取文字 | `office/skills/video/audio2txt/` | | `mark2video` | 给视频添加水印 | `office/skills/video/mark2video/` | | `txt2mp3` | 文本转语音 | `office/skills/video/txt2mp3/` | +| `video_edit` | 音频与视频剪辑集合(截取、画面裁剪、音视频拼接、合成/替换音频) | `office/skills/video/video_edit/` | + + + +--- + +## Web 网页处理 + +| Skill | 功能 | 所在路径 | +|-------|------|----------| +| `url2ebook` | 将网页转换为电子书 | `office/skills/web/url2ebook/` | + +调用示例: +```python +from skills.web import url2ebook +url2ebook(url='https://www.python-office.com', tile='Python-Office自动化办公指南') +``` --- @@ -249,14 +267,14 @@ office/skills/// ``` - **细粒度**:每个方法对应一个独立 Skill -- **可单独调用**:每个 Skill 都可通过 `from office.skills. import ` 单独使用 +- **可单独调用**:每个 Skill 都可通过 `from skills. import ` 单独使用 - **文档齐全**:每个 Skill 都有对应的 `SKILL.md` 详细说明 --- ## 统计 -- 总计:**73 个 Skill**,涵盖 12 个分类 +- 总计:**74 个 Skill**,涵盖 14 个分类 - 各分类 Skill 数量: - Excel:7 - File:9 @@ -268,6 +286,7 @@ office/skills/// - PPT:3 - Tools:10 - Video:4 + - Web:1 - WeChat:7 - Word:5 - Ruiming:3 diff --git a/skills/__init__.py b/skills/__init__.py index f0007e1d..3851bc46 100644 --- a/skills/__init__.py +++ b/skills/__init__.py @@ -6,10 +6,10 @@ 每个 Skill 都是一个独立的子目录,可以单独调用。 使用方式: - from office.skills.excel import fake2excel + from skills.excel import fake2excel fake2excel(rows=10) - from office.skills.image import add_watermark + from skills.image import add_watermark add_watermark(file='test.png', mark='python-office') 详细功能列表见本目录下的 README.md。 diff --git a/skills/excel/__init__.py b/skills/excel/__init__.py index 495b3e53..30dbf826 100644 --- a/skills/excel/__init__.py +++ b/skills/excel/__init__.py @@ -1,12 +1,12 @@ # -*- coding: UTF-8 -*- """Excel Skills 包 - 统一暴露 Excel 处理相关的所有 Skills""" -from office.skills.excel.fake2excel import fake2excel -from office.skills.excel.merge2excel import merge2excel -from office.skills.excel.sheet2excel import sheet2excel -from office.skills.excel.merge2sheet import merge2sheet -from office.skills.excel.find_excel_data import find_excel_data -from office.skills.excel.split_excel_by_column import split_excel_by_column -from office.skills.excel.excel2pdf import excel2pdf +from .fake2excel import fake2excel +from .merge2excel import merge2excel +from .sheet2excel import sheet2excel +from .merge2sheet import merge2sheet +from .find_excel_data import find_excel_data +from .split_excel_by_column import split_excel_by_column +from .excel2pdf import excel2pdf __all__ = [ 'fake2excel', diff --git a/skills/excel/excel2pdf/SKILL.md b/skills/excel/excel2pdf/SKILL.md index 0f7b8050..9c4ee8dc 100644 --- a/skills/excel/excel2pdf/SKILL.md +++ b/skills/excel/excel2pdf/SKILL.md @@ -18,7 +18,7 @@ description: 将 Excel 文件的指定工作表转换为 PDF 格式。当用户 ## 调用方式 ```python -from office.skills.excel import excel2pdf +from skills.excel import excel2pdf excel2pdf( excel_path='./data.xlsx', @@ -42,7 +42,7 @@ excel2pdf( ## 使用示例 ```python -from office.skills.excel import excel2pdf +from skills.excel import excel2pdf excel2pdf(excel_path='./report.xlsx', pdf_path='./report.pdf', sheet_id=0) ``` diff --git a/skills/excel/fake2excel/SKILL.md b/skills/excel/fake2excel/SKILL.md index 3f55b8c5..a10d9fa4 100644 --- a/skills/excel/fake2excel/SKILL.md +++ b/skills/excel/fake2excel/SKILL.md @@ -18,7 +18,7 @@ description: 自动创建 Excel 并模拟数据。当用户提到生成测试数 ## 调用方式 ```python -from office.skills.excel import fake2excel +from skills.excel import fake2excel fake2excel( columns=['name', 'phone'], @@ -45,7 +45,7 @@ fake2excel( ```python # 示例 1:生成中文测试数据 -from office.skills.excel import fake2excel +from skills.excel import fake2excel fake2excel(columns=['name', 'phone', 'address'], rows=1000, path='./test_cn.xlsx') # 示例 2:生成英文测试数据 diff --git a/skills/excel/find_excel_data/SKILL.md b/skills/excel/find_excel_data/SKILL.md index 325f5bcc..6908ef44 100644 --- a/skills/excel/find_excel_data/SKILL.md +++ b/skills/excel/find_excel_data/SKILL.md @@ -18,7 +18,7 @@ description: 在 Excel 文件中搜索指定关键词并返回文件、行号、 ## 调用方式 ```python -from office.skills.excel import find_excel_data +from skills.excel import find_excel_data find_excel_data( search_key='python', @@ -40,7 +40,7 @@ find_excel_data( ## 使用示例 ```python -from office.skills.excel import find_excel_data +from skills.excel import find_excel_data find_excel_data(search_key='订单', target_dir='./订单数据') ``` diff --git a/skills/excel/merge2excel/SKILL.md b/skills/excel/merge2excel/SKILL.md index 9ce297f2..e96614ed 100644 --- a/skills/excel/merge2excel/SKILL.md +++ b/skills/excel/merge2excel/SKILL.md @@ -18,7 +18,7 @@ description: 将多个 Excel 文件合并到一个 Excel 的不同 sheet 中。 ## 调用方式 ```python -from office.skills.excel import merge2excel +from skills.excel import merge2excel merge2excel( dir_path='./excel_files', @@ -40,7 +40,7 @@ merge2excel( ## 使用示例 ```python -from office.skills.excel import merge2excel +from skills.excel import merge2excel merge2excel(dir_path='./excels', output_file='./all_in_one.xlsx') ``` diff --git a/skills/excel/merge2sheet/SKILL.md b/skills/excel/merge2sheet/SKILL.md index 0472a72e..8e565e4a 100644 --- a/skills/excel/merge2sheet/SKILL.md +++ b/skills/excel/merge2sheet/SKILL.md @@ -18,7 +18,7 @@ description: 将多个 Excel 文件的多个 sheet 合并到同一个 sheet。 ## 调用方式 ```python -from office.skills.excel import merge2sheet +from skills.excel import merge2sheet merge2sheet( dir_path='./excels', @@ -42,7 +42,7 @@ merge2sheet( ## 使用示例 ```python -from office.skills.excel import merge2sheet +from skills.excel import merge2sheet merge2sheet(dir_path='./my_excels', output_sheet_name='AllData', output_excel_name='all_merged') ``` diff --git a/skills/excel/sheet2excel/SKILL.md b/skills/excel/sheet2excel/SKILL.md index 326e6c2f..0997413a 100644 --- a/skills/excel/sheet2excel/SKILL.md +++ b/skills/excel/sheet2excel/SKILL.md @@ -18,7 +18,7 @@ description: 将同一个 Excel 文件的多个 sheet 拆分为独立文件。 ## 调用方式 ```python -from office.skills.excel import sheet2excel +from skills.excel import sheet2excel sheet2excel( file_path='./multi_sheet.xlsx', @@ -40,7 +40,7 @@ sheet2excel( ## 使用示例 ```python -from office.skills.excel import sheet2excel +from skills.excel import sheet2excel sheet2excel(file_path='./data.xlsx', output_path='./split_output/') ``` diff --git a/skills/excel/split_excel_by_column/SKILL.md b/skills/excel/split_excel_by_column/SKILL.md index da9a69c0..80739c97 100644 --- a/skills/excel/split_excel_by_column/SKILL.md +++ b/skills/excel/split_excel_by_column/SKILL.md @@ -18,7 +18,7 @@ description: 按指定列的内容拆分 Excel 文件,每个唯一值一个文 ## 调用方式 ```python -from office.skills.excel import split_excel_by_column +from skills.excel import split_excel_by_column split_excel_by_column( filepath='./data.xlsx', @@ -42,7 +42,7 @@ split_excel_by_column( ## 使用示例 ```python -from office.skills.excel import split_excel_by_column +from skills.excel import split_excel_by_column # 按第 0 列拆分 split_excel_by_column(filepath='./orders.xlsx', column=0) ``` diff --git a/skills/file/__init__.py b/skills/file/__init__.py index 59ebb3c4..cb6ff74f 100644 --- a/skills/file/__init__.py +++ b/skills/file/__init__.py @@ -1,14 +1,14 @@ # -*- coding: UTF-8 -*- """File Skills 包 - 统一暴露文件处理相关的所有 Skills""" -from office.skills.file.replace4filename import replace4filename -from office.skills.file.file_name_insert_content import file_name_insert_content -from office.skills.file.file_name_add_prefix import file_name_add_prefix -from office.skills.file.file_name_add_postfix import file_name_add_postfix -from office.skills.file.output_file_list_to_excel import output_file_list_to_excel -from office.skills.file.add_line_by_type import add_line_by_type -from office.skills.file.search_specify_type_file import search_specify_type_file -from office.skills.file.group_by_name import group_by_name -from office.skills.file.get_files import get_files +from .replace4filename import replace4filename +from .file_name_insert_content import file_name_insert_content +from .file_name_add_prefix import file_name_add_prefix +from .file_name_add_postfix import file_name_add_postfix +from .output_file_list_to_excel import output_file_list_to_excel +from .add_line_by_type import add_line_by_type +from .search_specify_type_file import search_specify_type_file +from .group_by_name import group_by_name +from .get_files import get_files __all__ = [ 'replace4filename', diff --git a/skills/file/add_line_by_type/SKILL.md b/skills/file/add_line_by_type/SKILL.md index a1e2e99e..00254d33 100644 --- a/skills/file/add_line_by_type/SKILL.md +++ b/skills/file/add_line_by_type/SKILL.md @@ -20,7 +20,7 @@ description: 根据文件类型向指定文件中添加代码行。当用户提 ## 调用方式 ```python -from office.skills.file import add_line_by_type +from skills.file import add_line_by_type add_line_by_type( add_line_dict={'import': 'import os'}, diff --git a/skills/file/file_name_add_postfix/SKILL.md b/skills/file/file_name_add_postfix/SKILL.md index 346de11b..c1bcb9b1 100644 --- a/skills/file/file_name_add_postfix/SKILL.md +++ b/skills/file/file_name_add_postfix/SKILL.md @@ -18,7 +18,7 @@ description: 给文件名批量增加指定后缀。当用户提到加后缀、 ## 调用方式 ```python -from office.skills.file import file_name_add_postfix +from skills.file import file_name_add_postfix file_name_add_postfix( file_path='./test.txt', @@ -40,7 +40,7 @@ file_name_add_postfix( ## 使用示例 ```python -from office.skills.file import file_name_add_postfix +from skills.file import file_name_add_postfix file_name_add_postfix(file_path='./data.txt', postfix_content='_v1') ``` diff --git a/skills/file/file_name_add_prefix/SKILL.md b/skills/file/file_name_add_prefix/SKILL.md index 6c3b710a..cfb31596 100644 --- a/skills/file/file_name_add_prefix/SKILL.md +++ b/skills/file/file_name_add_prefix/SKILL.md @@ -18,7 +18,7 @@ description: 给文件名批量增加指定前缀。当用户提到加前缀、 ## 调用方式 ```python -from office.skills.file import file_name_add_prefix +from skills.file import file_name_add_prefix file_name_add_prefix( file_path='./test.txt', @@ -40,7 +40,7 @@ file_name_add_prefix( ## 使用示例 ```python -from office.skills.file import file_name_add_prefix +from skills.file import file_name_add_prefix file_name_add_prefix(file_path='./doc.txt', prefix_content='backup_') ``` diff --git a/skills/file/file_name_insert_content/SKILL.md b/skills/file/file_name_insert_content/SKILL.md index 12bbe3d7..180b14b9 100644 --- a/skills/file/file_name_insert_content/SKILL.md +++ b/skills/file/file_name_insert_content/SKILL.md @@ -18,7 +18,7 @@ description: 在文件名中间指定位置插入字符。当用户提到文件 ## 调用方式 ```python -from office.skills.file import file_name_insert_content +from skills.file import file_name_insert_content file_name_insert_content( file_path='./test.txt', @@ -42,7 +42,7 @@ file_name_insert_content( ## 使用示例 ```python -from office.skills.file import file_name_insert_content +from skills.file import file_name_insert_content file_name_insert_content(file_path='./report.txt', insert_position=2, insert_content='_2024') ``` diff --git a/skills/file/get_files/SKILL.md b/skills/file/get_files/SKILL.md index 3f93f719..47139fd7 100644 --- a/skills/file/get_files/SKILL.md +++ b/skills/file/get_files/SKILL.md @@ -18,7 +18,7 @@ description: 在指定路径下搜索文件并返回路径列表,支持按后 ## 调用方式 ```python -from office.skills.file import get_files +from skills.file import get_files files = get_files( path='./data', @@ -46,7 +46,7 @@ files = get_files( ## 使用示例 ```python -from office.skills.file import get_files +from skills.file import get_files # 获取所有 .txt 文件 txt_files = get_files(path='./docs', suffix='.txt', sub=True) # 获取所有名为 report 的文件 diff --git a/skills/file/group_by_name/SKILL.md b/skills/file/group_by_name/SKILL.md index e46a376c..1988140f 100644 --- a/skills/file/group_by_name/SKILL.md +++ b/skills/file/group_by_name/SKILL.md @@ -20,7 +20,7 @@ description: 按文件名的规则将文件分组整理到不同目录。当用 ## 调用方式 ```python -from office.skills.file import group_by_name +from skills.file import group_by_name group_by_name( path='./data', diff --git a/skills/file/output_file_list_to_excel/SKILL.md b/skills/file/output_file_list_to_excel/SKILL.md index 69667b51..9f2e1e6a 100644 --- a/skills/file/output_file_list_to_excel/SKILL.md +++ b/skills/file/output_file_list_to_excel/SKILL.md @@ -18,7 +18,7 @@ description: 将文件夹下的所有文件名整理到一个 Excel 表格中。 ## 调用方式 ```python -from office.skills.file import output_file_list_to_excel +from skills.file import output_file_list_to_excel output_file_list_to_excel(dir_path='./data') ``` @@ -36,7 +36,7 @@ output_file_list_to_excel(dir_path='./data') ## 使用示例 ```python -from office.skills.file import output_file_list_to_excel +from skills.file import output_file_list_to_excel output_file_list_to_excel(dir_path='./我的文件夹') ``` diff --git a/skills/file/replace4filename/SKILL.md b/skills/file/replace4filename/SKILL.md index 7119e788..c9e041f5 100644 --- a/skills/file/replace4filename/SKILL.md +++ b/skills/file/replace4filename/SKILL.md @@ -18,7 +18,7 @@ description: 批量修改文件/文件夹名称,替换或删除指定内容。 ## 调用方式 ```python -from office.skills.file import replace4filename +from skills.file import replace4filename replace4filename( path='./my_folder', @@ -48,7 +48,7 @@ replace4filename( ## 使用示例 ```python -from office.skills.file import replace4filename +from skills.file import replace4filename # 批量替换文件名中的"old"为"new" replace4filename(path='./data', del_content='old', replace_content='new') # 批量删除文件名中的"tmp" diff --git a/skills/file/search_specify_type_file/SKILL.md b/skills/file/search_specify_type_file/SKILL.md index 60a142ca..757b0f15 100644 --- a/skills/file/search_specify_type_file/SKILL.md +++ b/skills/file/search_specify_type_file/SKILL.md @@ -18,7 +18,7 @@ description: 在指定路径下搜索指定类型的文件(如 .txt、.pdf) ## 调用方式 ```python -from office.skills.file import search_specify_type_file +from skills.file import search_specify_type_file search_specify_type_file( file_path='./data', @@ -40,7 +40,7 @@ search_specify_type_file( ## 使用示例 ```python -from office.skills.file import search_specify_type_file +from skills.file import search_specify_type_file search_specify_type_file(file_path='./docs', file_type='.pdf') ``` diff --git a/skills/finance/__init__.py b/skills/finance/__init__.py index fee1e68c..217800fd 100644 --- a/skills/finance/__init__.py +++ b/skills/finance/__init__.py @@ -1,5 +1,5 @@ # -*- coding: UTF-8 -*- """Finance Skills 包 - 统一暴露金融计算相关的所有 Skills""" -from office.skills.finance.t0 import t0 +from .t0 import t0 __all__ = ['t0'] diff --git a/skills/finance/t0/SKILL.md b/skills/finance/t0/SKILL.md index aee89107..a4911eae 100644 --- a/skills/finance/t0/SKILL.md +++ b/skills/finance/t0/SKILL.md @@ -18,7 +18,7 @@ description: 计算股票 T+0 交易的收益,考虑买入价、卖出价、 ## 调用方式 ```python -from office.skills.finance import t0 +from skills.finance import t0 profit = t0( buy_price=11.99, @@ -46,7 +46,7 @@ print(profit) ## 使用示例 ```python -from office.skills.finance import t0 +from skills.finance import t0 # 买 11.99 卖 12.26,700 股 profit = t0(buy_price=11.99, sale_price=12.26, shares=700) print(f"本次做T收益: {profit} 元") diff --git a/skills/image/__init__.py b/skills/image/__init__.py index 9ca49796..fcf59d88 100644 --- a/skills/image/__init__.py +++ b/skills/image/__init__.py @@ -1,14 +1,14 @@ # -*- coding: UTF-8 -*- """Image Skills 包 - 统一暴露图像处理相关的所有 Skills""" -from office.skills.image.compress_image import compress_image -from office.skills.image.image2gif import image2gif -from office.skills.image.add_watermark import add_watermark -from office.skills.image.img2Cartoon import img2Cartoon -from office.skills.image.down4img import down4img -from office.skills.image.txt2wordcloud import txt2wordcloud -from office.skills.image.pencil4img import pencil4img -from office.skills.image.decode_qrcode import decode_qrcode -from office.skills.image.del_watermark import del_watermark +from .compress_image import compress_image +from .image2gif import image2gif +from .add_watermark import add_watermark +from .img2Cartoon import img2Cartoon +from .down4img import down4img +from .txt2wordcloud import txt2wordcloud +from .pencil4img import pencil4img +from .decode_qrcode import decode_qrcode +from .del_watermark import del_watermark __all__ = [ 'compress_image', diff --git a/skills/image/add_watermark/SKILL.md b/skills/image/add_watermark/SKILL.md index bf18e483..617d7614 100644 --- a/skills/image/add_watermark/SKILL.md +++ b/skills/image/add_watermark/SKILL.md @@ -18,7 +18,7 @@ description: 通过交互方式给 PDF 添加水印。当用户提到 PDF 互动 ## 调用方式 ```python -from office.skills.image import add_watermark +from skills.image import add_watermark add_watermark( file='./test.png', @@ -52,7 +52,7 @@ add_watermark( ## 使用示例 ```python -from office.skills.image import add_watermark +from skills.image import add_watermark add_watermark(file='./photo.jpg', mark='我的水印') ``` diff --git a/skills/image/compress_image/SKILL.md b/skills/image/compress_image/SKILL.md index fc15d8df..f5d7fd6e 100644 --- a/skills/image/compress_image/SKILL.md +++ b/skills/image/compress_image/SKILL.md @@ -18,7 +18,7 @@ description: 压缩图片文件大小,通过调整质量参数控制输出体 ## 调用方式 ```python -from office.skills.image import compress_image +from skills.image import compress_image compress_image( input_file='./test.png', @@ -42,7 +42,7 @@ compress_image( ## 使用示例 ```python -from office.skills.image import compress_image +from skills.image import compress_image compress_image(input_file='./photo.jpg', output_file='./photo_small.jpg', quality=30) ``` diff --git a/skills/image/decode_qrcode/SKILL.md b/skills/image/decode_qrcode/SKILL.md index 20f78544..4d100571 100644 --- a/skills/image/decode_qrcode/SKILL.md +++ b/skills/image/decode_qrcode/SKILL.md @@ -18,7 +18,7 @@ description: 解析二维码图片并提取其中的文本内容。当用户提 ## 调用方式 ```python -from office.skills.image import decode_qrcode +from skills.image import decode_qrcode decode_qrcode(qrcode_path='./qrcode.png') ``` @@ -36,7 +36,7 @@ decode_qrcode(qrcode_path='./qrcode.png') ## 使用示例 ```python -from office.skills.image import decode_qrcode +from skills.image import decode_qrcode decode_qrcode(qrcode_path='./my_qrcode.png') ``` diff --git a/skills/image/del_watermark/SKILL.md b/skills/image/del_watermark/SKILL.md index 9b8744a7..29ccfec0 100644 --- a/skills/image/del_watermark/SKILL.md +++ b/skills/image/del_watermark/SKILL.md @@ -18,7 +18,7 @@ description: 从图片中删除水印并保存。当用户提到去水印、去 ## 调用方式 ```python -from office.skills.image import del_watermark +from skills.image import del_watermark del_watermark( input_image='./with_watermark.jpg', @@ -40,7 +40,7 @@ del_watermark( ## 使用示例 ```python -from office.skills.image import del_watermark +from skills.image import del_watermark del_watermark(input_image='./photo.jpg') ``` diff --git a/skills/image/down4img/SKILL.md b/skills/image/down4img/SKILL.md index dc8b0710..5ddad0ba 100644 --- a/skills/image/down4img/SKILL.md +++ b/skills/image/down4img/SKILL.md @@ -18,7 +18,7 @@ description: 从指定 URL 下载图片并保存到本地。当用户提到下 ## 调用方式 ```python -from office.skills.image import down4img +from skills.image import down4img down4img( url='https://example.com/image.png', @@ -44,7 +44,7 @@ down4img( ## 使用示例 ```python -from office.skills.image import down4img +from skills.image import down4img down4img(url='https://example.com/photo.jpg') ``` diff --git a/skills/image/image2gif/SKILL.md b/skills/image/image2gif/SKILL.md index 3db40fa9..4d0c310c 100644 --- a/skills/image/image2gif/SKILL.md +++ b/skills/image/image2gif/SKILL.md @@ -18,7 +18,7 @@ description: 将一组图像转换为 GIF 动图格式。当用户提到图片 ## 调用方式 ```python -from office.skills.image import image2gif +from skills.image import image2gif image2gif() ``` @@ -34,7 +34,7 @@ image2gif() ## 使用示例 ```python -from office.skills.image import image2gif +from skills.image import image2gif image2gif() ``` diff --git a/skills/image/img2Cartoon/SKILL.md b/skills/image/img2Cartoon/SKILL.md index 3bc0cb52..5e14e9bc 100644 --- a/skills/image/img2Cartoon/SKILL.md +++ b/skills/image/img2Cartoon/SKILL.md @@ -18,7 +18,7 @@ description: 通过百度 API 将图片转换为卡通风格。当用户提到 ## 调用方式 ```python -from office.skills.image import img2Cartoon +from skills.image import img2Cartoon img2Cartoon( path='./test.png', @@ -42,7 +42,7 @@ img2Cartoon( ## 使用示例 ```python -from office.skills.image import img2Cartoon +from skills.image import img2Cartoon img2Cartoon(path='./photo.jpg') ``` diff --git a/skills/image/pencil4img/SKILL.md b/skills/image/pencil4img/SKILL.md index 5bd280cb..d71add44 100644 --- a/skills/image/pencil4img/SKILL.md +++ b/skills/image/pencil4img/SKILL.md @@ -18,7 +18,7 @@ description: 将输入的图片转换为铅笔画风格。当用户提到铅笔 ## 调用方式 ```python -from office.skills.image import pencil4img +from skills.image import pencil4img pencil4img( input_img='./test.jpg', @@ -42,7 +42,7 @@ pencil4img( ## 使用示例 ```python -from office.skills.image import pencil4img +from skills.image import pencil4img pencil4img(input_img='./photo.jpg') ``` diff --git a/skills/image/txt2wordcloud/SKILL.md b/skills/image/txt2wordcloud/SKILL.md index b8cf1096..49be249f 100644 --- a/skills/image/txt2wordcloud/SKILL.md +++ b/skills/image/txt2wordcloud/SKILL.md @@ -18,7 +18,7 @@ description: 根据文本文件生成词云图片,支持自定义背景色。 ## 调用方式 ```python -from office.skills.image import txt2wordcloud +from skills.image import txt2wordcloud txt2wordcloud( filename='./text.txt', @@ -42,7 +42,7 @@ txt2wordcloud( ## 使用示例 ```python -from office.skills.image import txt2wordcloud +from skills.image import txt2wordcloud txt2wordcloud(filename='./article.txt', result_file='./my_wordcloud.png') ``` diff --git a/skills/markdown/__init__.py b/skills/markdown/__init__.py index 615b31aa..4af27c6f 100644 --- a/skills/markdown/__init__.py +++ b/skills/markdown/__init__.py @@ -1,5 +1,5 @@ # -*- coding: UTF-8 -*- """Markdown Skills 包 - 统一暴露 Markdown 处理相关的所有 Skills""" -from office.skills.markdown.excel2markdown import excel2markdown +from .excel2markdown import excel2markdown __all__ = ['excel2markdown'] diff --git a/skills/markdown/excel2markdown/SKILL.md b/skills/markdown/excel2markdown/SKILL.md index 321fea9b..1ba75eb2 100644 --- a/skills/markdown/excel2markdown/SKILL.md +++ b/skills/markdown/excel2markdown/SKILL.md @@ -18,7 +18,7 @@ description: 将 Excel 文件转换为 Markdown 格式的文档。当用户提 ## 调用方式 ```python -from office.skills.markdown import excel2markdown +from skills.markdown import excel2markdown excel2markdown( input_file='./data.xlsx', @@ -42,7 +42,7 @@ excel2markdown( ## 使用示例 ```python -from office.skills.markdown import excel2markdown +from skills.markdown import excel2markdown excel2markdown(input_file='./report.xlsx', output_file='./report.md') ``` diff --git a/skills/ocr/VatInvoiceOCR2Excel/SKILL.md b/skills/ocr/VatInvoiceOCR2Excel/SKILL.md index 22a094bf..bd9a4103 100644 --- a/skills/ocr/VatInvoiceOCR2Excel/SKILL.md +++ b/skills/ocr/VatInvoiceOCR2Excel/SKILL.md @@ -18,7 +18,7 @@ description: 用 OCR 技术识别增值税发票图片并导出到 Excel,支 ## 调用方式 ```python -from office.skills.ocr import VatInvoiceOCR2Excel +from skills.ocr import VatInvoiceOCR2Excel VatInvoiceOCR2Excel( input_path='./invoices', @@ -49,7 +49,7 @@ VatInvoiceOCR2Excel( ## 使用示例 ```python -from office.skills.ocr import VatInvoiceOCR2Excel +from skills.ocr import VatInvoiceOCR2Excel VatInvoiceOCR2Excel(input_path='./发票图片', output_excel='所有发票汇总.xlsx') ``` diff --git a/skills/ocr/__init__.py b/skills/ocr/__init__.py index e3e1bc6f..75089767 100644 --- a/skills/ocr/__init__.py +++ b/skills/ocr/__init__.py @@ -1,5 +1,5 @@ # -*- coding: UTF-8 -*- """OCR Skills 包 - 统一暴露 OCR 识别相关的所有 Skills""" -from office.skills.ocr.VatInvoiceOCR2Excel import VatInvoiceOCR2Excel +from .VatInvoiceOCR2Excel import VatInvoiceOCR2Excel __all__ = ['VatInvoiceOCR2Excel'] diff --git a/skills/pdf/__init__.py b/skills/pdf/__init__.py index eac05e32..48f12601 100644 --- a/skills/pdf/__init__.py +++ b/skills/pdf/__init__.py @@ -1,18 +1,18 @@ # -*- coding: UTF-8 -*- """PDF Skills 包 - 统一暴露 PDF 处理相关的所有 Skills""" -from office.skills.pdf.pdf2docx import pdf2docx -from office.skills.pdf.pdf2imgs import pdf2imgs -from office.skills.pdf.txt2pdf import txt2pdf -from office.skills.pdf.split4pdf import split4pdf -from office.skills.pdf.encrypt4pdf import encrypt4pdf -from office.skills.pdf.decrypt4pdf import decrypt4pdf -from office.skills.pdf.add_text_watermark import add_text_watermark -from office.skills.pdf.merge2pdf import merge2pdf -from office.skills.pdf.del4pdf import del4pdf -from office.skills.pdf.add_img_water import add_img_water -from office.skills.pdf.add_watermark import add_watermark -from office.skills.pdf.add_mark import add_mark -from office.skills.pdf.add_watermark_by_parameters import add_watermark_by_parameters +from .pdf2docx import pdf2docx +from .pdf2imgs import pdf2imgs +from .txt2pdf import txt2pdf +from .split4pdf import split4pdf +from .encrypt4pdf import encrypt4pdf +from .decrypt4pdf import decrypt4pdf +from .add_text_watermark import add_text_watermark +from .merge2pdf import merge2pdf +from .del4pdf import del4pdf +from .add_img_water import add_img_water +from .add_watermark import add_watermark +from .add_mark import add_mark +from .add_watermark_by_parameters import add_watermark_by_parameters __all__ = [ 'pdf2docx', diff --git a/skills/pdf/add_img_water/SKILL.md b/skills/pdf/add_img_water/SKILL.md index cd9c76be..906ae74a 100644 --- a/skills/pdf/add_img_water/SKILL.md +++ b/skills/pdf/add_img_water/SKILL.md @@ -18,7 +18,7 @@ description: 给 PDF 添加图片水印(logo 等)。当用户提到 PDF 图 ## 调用方式 ```python -from office.skills.pdf import add_img_water +from skills.pdf import add_img_water add_img_water( input_file='./test.pdf', @@ -45,7 +45,7 @@ add_img_water( ## 使用示例 ```python -from office.skills.pdf import add_img_water +from skills.pdf import add_img_water add_img_water( input_file='./report.pdf', mark_file='./logo.png', diff --git a/skills/pdf/add_mark/SKILL.md b/skills/pdf/add_mark/SKILL.md index a3d41997..5d61c8fe 100644 --- a/skills/pdf/add_mark/SKILL.md +++ b/skills/pdf/add_mark/SKILL.md @@ -18,7 +18,7 @@ description: 给 PDF 添加文字水印(简化接口)。当用户提到 PDF ## 调用方式 ```python -from office.skills.pdf import add_mark +from skills.pdf import add_mark add_mark( input_file='./test.pdf', @@ -46,7 +46,7 @@ add_mark( ## 使用示例 ```python -from office.skills.pdf import add_mark +from skills.pdf import add_mark add_mark(input_file='./report.pdf', mark_str='机密') ``` diff --git a/skills/pdf/add_text_watermark/SKILL.md b/skills/pdf/add_text_watermark/SKILL.md index ba74419f..4c971875 100644 --- a/skills/pdf/add_text_watermark/SKILL.md +++ b/skills/pdf/add_text_watermark/SKILL.md @@ -18,7 +18,7 @@ description: 给 PDF 添加文字水印,支持自定义字体、字号、颜 ## 调用方式 ```python -from office.skills.pdf import add_text_watermark +from skills.pdf import add_text_watermark add_text_watermark( input_file='./test.pdf', @@ -50,7 +50,7 @@ add_text_watermark( ## 使用示例 ```python -from office.skills.pdf import add_text_watermark +from skills.pdf import add_text_watermark add_text_watermark(input_file='./report.pdf', text='机密文件') ``` diff --git a/skills/pdf/add_watermark/SKILL.md b/skills/pdf/add_watermark/SKILL.md index cbc255b2..2c1ce9d3 100644 --- a/skills/pdf/add_watermark/SKILL.md +++ b/skills/pdf/add_watermark/SKILL.md @@ -18,7 +18,7 @@ description: 通过交互方式给 PDF 添加水印。当用户提到 PDF 互动 ## 调用方式 ```python -from office.skills.pdf import add_watermark +from skills.pdf import add_watermark add_watermark() ``` @@ -34,7 +34,7 @@ add_watermark() ## 使用示例 ```python -from office.skills.pdf import add_watermark +from skills.pdf import add_watermark add_watermark() ``` diff --git a/skills/pdf/add_watermark_by_parameters/SKILL.md b/skills/pdf/add_watermark_by_parameters/SKILL.md index aca80e3b..d5db83c8 100644 --- a/skills/pdf/add_watermark_by_parameters/SKILL.md +++ b/skills/pdf/add_watermark_by_parameters/SKILL.md @@ -18,7 +18,7 @@ description: 通过参数化方式给 PDF 添加水印。当用户提到参数 ## 调用方式 ```python -from office.skills.pdf import add_watermark_by_parameters +from skills.pdf import add_watermark_by_parameters add_watermark_by_parameters( input_file='./test.pdf', @@ -46,7 +46,7 @@ add_watermark_by_parameters( ## 使用示例 ```python -from office.skills.pdf import add_watermark_by_parameters +from skills.pdf import add_watermark_by_parameters add_watermark_by_parameters(input_file='./report.pdf', mark_str='机密') ``` diff --git a/skills/pdf/decrypt4pdf/SKILL.md b/skills/pdf/decrypt4pdf/SKILL.md index 460d2449..28f22335 100644 --- a/skills/pdf/decrypt4pdf/SKILL.md +++ b/skills/pdf/decrypt4pdf/SKILL.md @@ -18,7 +18,7 @@ description: 对加密的 PDF 文件进行解密。当用户提到 PDF 解密、 ## 调用方式 ```python -from office.skills.pdf import decrypt4pdf +from skills.pdf import decrypt4pdf decrypt4pdf( password='123456', @@ -44,7 +44,7 @@ decrypt4pdf( ## 使用示例 ```python -from office.skills.pdf import decrypt4pdf +from skills.pdf import decrypt4pdf decrypt4pdf(password='mypassword', input_file='./encrypted.pdf', output_file='./decrypted.pdf') ``` diff --git a/skills/pdf/del4pdf/SKILL.md b/skills/pdf/del4pdf/SKILL.md index 50867612..802b88e8 100644 --- a/skills/pdf/del4pdf/SKILL.md +++ b/skills/pdf/del4pdf/SKILL.md @@ -18,7 +18,7 @@ description: 删除 PDF 文件中指定的页面。当用户提到 PDF 删除页 ## 调用方式 ```python -from office.skills.pdf import del4pdf +from skills.pdf import del4pdf del4pdf( input_file='./test.pdf', @@ -42,7 +42,7 @@ del4pdf( ## 使用示例 ```python -from office.skills.pdf import del4pdf +from skills.pdf import del4pdf # 删除第 1 页和第 3 页 del4pdf(input_file='./report.pdf', output_file='./new.pdf', page_nums=[0, 2]) ``` diff --git a/skills/pdf/encrypt4pdf/SKILL.md b/skills/pdf/encrypt4pdf/SKILL.md index e2f4981f..eee25463 100644 --- a/skills/pdf/encrypt4pdf/SKILL.md +++ b/skills/pdf/encrypt4pdf/SKILL.md @@ -18,7 +18,7 @@ description: 对 PDF 文件设置密码进行加密保护。当用户提到 PDF ## 调用方式 ```python -from office.skills.pdf import encrypt4pdf +from skills.pdf import encrypt4pdf encrypt4pdf( password='123456', @@ -44,7 +44,7 @@ encrypt4pdf( ## 使用示例 ```python -from office.skills.pdf import encrypt4pdf +from skills.pdf import encrypt4pdf encrypt4pdf(password='mypassword', input_file='./report.pdf', output_file='./encrypted.pdf') ``` diff --git a/skills/pdf/merge2pdf/SKILL.md b/skills/pdf/merge2pdf/SKILL.md index 7f3f6757..f3ab1cb5 100644 --- a/skills/pdf/merge2pdf/SKILL.md +++ b/skills/pdf/merge2pdf/SKILL.md @@ -18,7 +18,7 @@ description: 将多个 PDF 文件合并为一个 PDF。当用户提到 PDF 合 ## 调用方式 ```python -from office.skills.pdf import merge2pdf +from skills.pdf import merge2pdf merge2pdf( input_file_list=['./1.pdf', './2.pdf', './3.pdf'], @@ -42,7 +42,7 @@ merge2pdf( ## 使用示例 ```python -from office.skills.pdf import merge2pdf +from skills.pdf import merge2pdf merge2pdf( input_file_list=['./part1.pdf', './part2.pdf'], output_file='./all.pdf' diff --git a/skills/pdf/pdf2docx/SKILL.md b/skills/pdf/pdf2docx/SKILL.md index 6223e133..0fbb68a7 100644 --- a/skills/pdf/pdf2docx/SKILL.md +++ b/skills/pdf/pdf2docx/SKILL.md @@ -18,7 +18,7 @@ description: 将 PDF 文件转换为 Word 文档(.docx),支持单文件和 ## 调用方式 ```python -from office.skills.pdf import pdf2docx +from skills.pdf import pdf2docx # 单个文件 pdf2docx(input_file='./test.pdf', output_file='./test.docx') @@ -46,7 +46,7 @@ pdf2docx(input_path='./pdfs/', output_path='./docs/') ## 使用示例 ```python -from office.skills.pdf import pdf2docx +from skills.pdf import pdf2docx pdf2docx(input_file='./report.pdf', output_file='./report.docx') ``` diff --git a/skills/pdf/pdf2imgs/SKILL.md b/skills/pdf/pdf2imgs/SKILL.md index b3040d2c..55530296 100644 --- a/skills/pdf/pdf2imgs/SKILL.md +++ b/skills/pdf/pdf2imgs/SKILL.md @@ -18,7 +18,7 @@ description: 将 PDF 文件转换为图片,可合并为一张长图或多张 ## 调用方式 ```python -from office.skills.pdf import pdf2imgs +from skills.pdf import pdf2imgs pdf2imgs( input_file='./test.pdf', @@ -44,7 +44,7 @@ pdf2imgs( ## 使用示例 ```python -from office.skills.pdf import pdf2imgs +from skills.pdf import pdf2imgs pdf2imgs(input_file='./report.pdf', output_file='./images/', merge=True) ``` diff --git a/skills/pdf/split4pdf/SKILL.md b/skills/pdf/split4pdf/SKILL.md index bdbb3ec7..3969a7bc 100644 --- a/skills/pdf/split4pdf/SKILL.md +++ b/skills/pdf/split4pdf/SKILL.md @@ -18,7 +18,7 @@ description: 按指定页码范围拆分 PDF 文件。当用户提到 PDF 拆分 ## 调用方式 ```python -from office.skills.pdf import split4pdf +from skills.pdf import split4pdf split4pdf( input_file='./test.pdf', @@ -44,7 +44,7 @@ split4pdf( ## 使用示例 ```python -from office.skills.pdf import split4pdf +from skills.pdf import split4pdf # 拆分第 1-5 页 split4pdf(input_file='./report.pdf', output_file='./part1.pdf', from_page=0, to_page=4) ``` diff --git a/skills/pdf/txt2pdf/SKILL.md b/skills/pdf/txt2pdf/SKILL.md index be9e0801..4f871ede 100644 --- a/skills/pdf/txt2pdf/SKILL.md +++ b/skills/pdf/txt2pdf/SKILL.md @@ -18,7 +18,7 @@ description: 将文本文件转换为 PDF 文件。当用户提到文本转 PDF ## 调用方式 ```python -from office.skills.pdf import txt2pdf +from skills.pdf import txt2pdf txt2pdf( input_file='./test.txt', @@ -40,7 +40,7 @@ txt2pdf( ## 使用示例 ```python -from office.skills.pdf import txt2pdf +from skills.pdf import txt2pdf txt2pdf(input_file='./article.txt', output_file='./article.pdf') ``` diff --git a/skills/ppt/__init__.py b/skills/ppt/__init__.py index 65a689f6..c3033bfc 100644 --- a/skills/ppt/__init__.py +++ b/skills/ppt/__init__.py @@ -1,8 +1,8 @@ # -*- coding: UTF-8 -*- """PPT Skills 包 - 统一暴露 PPT 处理相关的所有 Skills""" -from office.skills.ppt.ppt2pdf import ppt2pdf -from office.skills.ppt.ppt2img import ppt2img -from office.skills.ppt.merge4ppt import merge4ppt +from .ppt2pdf import ppt2pdf +from .ppt2img import ppt2img +from .merge4ppt import merge4ppt __all__ = [ 'ppt2pdf', diff --git a/skills/ppt/merge4ppt/SKILL.md b/skills/ppt/merge4ppt/SKILL.md index c497d598..14d1c423 100644 --- a/skills/ppt/merge4ppt/SKILL.md +++ b/skills/ppt/merge4ppt/SKILL.md @@ -18,7 +18,7 @@ description: 将多个 PowerPoint 文件合并为一个 PPT。当用户提到 PP ## 调用方式 ```python -from office.skills.ppt import merge4ppt +from skills.ppt import merge4ppt merge4ppt( input_path='./ppt_files', @@ -42,7 +42,7 @@ merge4ppt( ## 使用示例 ```python -from office.skills.ppt import merge4ppt +from skills.ppt import merge4ppt merge4ppt(input_path='./ppt_files', output_name='all_merged.pptx') ``` diff --git a/skills/ppt/ppt2img/SKILL.md b/skills/ppt/ppt2img/SKILL.md index 89c4c31c..c2d32ffa 100644 --- a/skills/ppt/ppt2img/SKILL.md +++ b/skills/ppt/ppt2img/SKILL.md @@ -18,7 +18,7 @@ description: 将 PowerPoint 转换为图片,可合并为一张长图或多张 ## 调用方式 ```python -from office.skills.ppt import ppt2img +from skills.ppt import ppt2img ppt2img( input_path='./test.pptx', @@ -42,7 +42,7 @@ ppt2img( ## 使用示例 ```python -from office.skills.ppt import ppt2img +from skills.ppt import ppt2img # 转为多张图片 ppt2img(input_path='./presentation.pptx', output_path='./images/') # 转为一张长图 diff --git a/skills/ppt/ppt2pdf/SKILL.md b/skills/ppt/ppt2pdf/SKILL.md index c5664aaa..957582a9 100644 --- a/skills/ppt/ppt2pdf/SKILL.md +++ b/skills/ppt/ppt2pdf/SKILL.md @@ -18,7 +18,7 @@ description: 将 PowerPoint 文件转换为 PDF。当用户提到 PPT 转 PDF、 ## 调用方式 ```python -from office.skills.ppt import ppt2pdf +from skills.ppt import ppt2pdf ppt2pdf( path='./test.pptx', @@ -40,7 +40,7 @@ ppt2pdf( ## 使用示例 ```python -from office.skills.ppt import ppt2pdf +from skills.ppt import ppt2pdf ppt2pdf(path='./presentation.pptx', output_path='./output/') ``` diff --git a/skills/ruiming/__init__.py b/skills/ruiming/__init__.py index e861d4a0..dec90f07 100644 --- a/skills/ruiming/__init__.py +++ b/skills/ruiming/__init__.py @@ -1,8 +1,8 @@ # -*- coding: UTF-8 -*- """Ruiming Skills 包 - 统一暴露 Ruiming(testApi)相关的所有 Skills""" -from office.skills.ruiming.screen_unmarked_image import screen_unmarked_image -from office.skills.ruiming.change_label_in_xml import change_label_in_xml -from office.skills.ruiming.screen_without_label_json_file import screen_without_label_json_file +from .screen_unmarked_image import screen_unmarked_image +from .change_label_in_xml import change_label_in_xml +from .screen_without_label_json_file import screen_without_label_json_file __all__ = [ 'screen_unmarked_image', diff --git a/skills/ruiming/change_label_in_xml/SKILL.md b/skills/ruiming/change_label_in_xml/SKILL.md index cbda9184..e145a88a 100644 --- a/skills/ruiming/change_label_in_xml/SKILL.md +++ b/skills/ruiming/change_label_in_xml/SKILL.md @@ -18,7 +18,7 @@ description: 批量修改指定目录下所有 XML 标注文件中的标签名 ## 调用方式 ```python -from office.skills.ruiming import change_label_in_xml +from skills.ruiming import change_label_in_xml change_label_in_xml( dir_path='./dataset', @@ -42,7 +42,7 @@ change_label_in_xml( ## 使用示例 ```python -from office.skills.ruiming import change_label_in_xml +from skills.ruiming import change_label_in_xml change_label_in_xml(dir_path='./annotations', old_label='person', new_label='human') ``` diff --git a/skills/ruiming/screen_unmarked_image/SKILL.md b/skills/ruiming/screen_unmarked_image/SKILL.md index 3f036682..c47ea7f2 100644 --- a/skills/ruiming/screen_unmarked_image/SKILL.md +++ b/skills/ruiming/screen_unmarked_image/SKILL.md @@ -18,7 +18,7 @@ description: 在指定目录下筛选没有对应标注文件(.xml)的图片 ## 调用方式 ```python -from office.skills.ruiming import screen_unmarked_image +from skills.ruiming import screen_unmarked_image screen_unmarked_image(dir_path='./dataset') ``` @@ -38,7 +38,7 @@ screen_unmarked_image(dir_path='./dataset') ## 使用示例 ```python -from office.skills.ruiming import screen_unmarked_image +from skills.ruiming import screen_unmarked_image screen_unmarked_image(dir_path='./my_dataset') ``` diff --git a/skills/ruiming/screen_without_label_json_file/SKILL.md b/skills/ruiming/screen_without_label_json_file/SKILL.md index 9afb2d50..7a0ae02a 100644 --- a/skills/ruiming/screen_without_label_json_file/SKILL.md +++ b/skills/ruiming/screen_without_label_json_file/SKILL.md @@ -18,7 +18,7 @@ description: 筛选 shapes 字段为空的 JSON 标注文件,并移动到「 ## 调用方式 ```python -from office.skills.ruiming import screen_without_label_json_file +from skills.ruiming import screen_without_label_json_file screen_without_label_json_file(dir_path='./jsons') ``` @@ -36,7 +36,7 @@ screen_without_label_json_file(dir_path='./jsons') ## 使用示例 ```python -from office.skills.ruiming import screen_without_label_json_file +from skills.ruiming import screen_without_label_json_file screen_without_label_json_file(dir_path='./annotations') ``` diff --git a/skills/tools/__init__.py b/skills/tools/__init__.py index 9d02c3ba..3f90b4b0 100644 --- a/skills/tools/__init__.py +++ b/skills/tools/__init__.py @@ -1,15 +1,15 @@ # -*- coding: UTF-8 -*- """Tools Skills 包 - 统一暴露工具类相关的所有 Skills""" -from office.skills.tools.transtools import transtools -from office.skills.tools.qrcodetools import qrcodetools -from office.skills.tools.passwordtools import passwordtools -from office.skills.tools.weather import weather -from office.skills.tools.url2ip import url2ip -from office.skills.tools.lottery8ticket import lottery8ticket -from office.skills.tools.create_article import create_article -from office.skills.tools.pwd4wifi import pwd4wifi -from office.skills.tools.net_speed_test import net_speed_test -from office.skills.tools.course import course +from .transtools import transtools +from .qrcodetools import qrcodetools +from .passwordtools import passwordtools +from .weather import weather +from .url2ip import url2ip +from .lottery8ticket import lottery8ticket +from .create_article import create_article +from .pwd4wifi import pwd4wifi +from .net_speed_test import net_speed_test +from .course import course __all__ = [ 'transtools', diff --git a/skills/tools/course/SKILL.md b/skills/tools/course/SKILL.md index 1ba52f11..0948da28 100644 --- a/skills/tools/course/SKILL.md +++ b/skills/tools/course/SKILL.md @@ -18,7 +18,7 @@ description: 显示 python-office 库的使用教程、群组信息、源码地 ## 调用方式 ```python -from office.skills.tools import course +from skills.tools import course course() ``` @@ -34,7 +34,7 @@ course() ## 使用示例 ```python -from office.skills.tools import course +from skills.tools import course course() ``` diff --git a/skills/tools/create_article/SKILL.md b/skills/tools/create_article/SKILL.md index 22497d2b..392fd8b1 100644 --- a/skills/tools/create_article/SKILL.md +++ b/skills/tools/create_article/SKILL.md @@ -18,7 +18,7 @@ description: 根据给定主题自动生成指定行数的文章。当用户提 ## 调用方式 ```python -from office.skills.tools import create_article +from skills.tools import create_article create_article( theme='人工智能的发展', @@ -40,7 +40,7 @@ create_article( ## 使用示例 ```python -from office.skills.tools import create_article +from skills.tools import create_article create_article(theme='Python 自动化办公', line_num=500) ``` diff --git a/skills/tools/lottery8ticket/SKILL.md b/skills/tools/lottery8ticket/SKILL.md index 628f3b86..6cba316b 100644 --- a/skills/tools/lottery8ticket/SKILL.md +++ b/skills/tools/lottery8ticket/SKILL.md @@ -18,7 +18,7 @@ description: 随机生成一组 8 位彩票号码。当用户提到生成彩票 ## 调用方式 ```python -from office.skills.tools import lottery8ticket +from skills.tools import lottery8ticket lottery8ticket() ``` @@ -34,7 +34,7 @@ lottery8ticket() ## 使用示例 ```python -from office.skills.tools import lottery8ticket +from skills.tools import lottery8ticket lottery8ticket() ``` diff --git a/skills/tools/net_speed_test/SKILL.md b/skills/tools/net_speed_test/SKILL.md index f7588928..3b33cb0a 100644 --- a/skills/tools/net_speed_test/SKILL.md +++ b/skills/tools/net_speed_test/SKILL.md @@ -18,7 +18,7 @@ description: 测试网络的上传和下载速度。当用户提到测网速、 ## 调用方式 ```python -from office.skills.tools import net_speed_test +from skills.tools import net_speed_test net_speed_test() ``` @@ -34,7 +34,7 @@ net_speed_test() ## 使用示例 ```python -from office.skills.tools import net_speed_test +from skills.tools import net_speed_test net_speed_test() ``` diff --git a/skills/tools/passwordtools/SKILL.md b/skills/tools/passwordtools/SKILL.md index a014acba..ed009446 100644 --- a/skills/tools/passwordtools/SKILL.md +++ b/skills/tools/passwordtools/SKILL.md @@ -18,7 +18,7 @@ description: 生成指定长度的随机密码。当用户提到生成密码、 ## 调用方式 ```python -from office.skills.tools import passwordtools +from skills.tools import passwordtools pwd = passwordtools(len=12) print(pwd) @@ -37,7 +37,7 @@ print(pwd) ## 使用示例 ```python -from office.skills.tools import passwordtools +from skills.tools import passwordtools pwd = passwordtools(len=16) print(f"生成的密码: {pwd}") ``` diff --git a/skills/tools/pwd4wifi/SKILL.md b/skills/tools/pwd4wifi/SKILL.md index 5e5d7f75..29fcf20e 100644 --- a/skills/tools/pwd4wifi/SKILL.md +++ b/skills/tools/pwd4wifi/SKILL.md @@ -18,7 +18,7 @@ description: 生成 WiFi 密码字典列表。当用户提到 WiFi 密码字典 ## 调用方式 ```python -from office.skills.tools import pwd4wifi +from skills.tools import pwd4wifi pwd4wifi(len_pwd=8, pwd_list=[]) ``` @@ -37,7 +37,7 @@ pwd4wifi(len_pwd=8, pwd_list=[]) ## 使用示例 ```python -from office.skills.tools import pwd4wifi +from skills.tools import pwd4wifi pwd4wifi(len_pwd=10) ``` diff --git a/skills/tools/qrcodetools/SKILL.md b/skills/tools/qrcodetools/SKILL.md index 77e15e58..7e982733 100644 --- a/skills/tools/qrcodetools/SKILL.md +++ b/skills/tools/qrcodetools/SKILL.md @@ -18,7 +18,7 @@ description: 根据 URL 生成对应的二维码图片。当用户提到生成 ## 调用方式 ```python -from office.skills.tools import qrcodetools +from skills.tools import qrcodetools qrcodetools( url='https://www.python-office.com', @@ -40,7 +40,7 @@ qrcodetools( ## 使用示例 ```python -from office.skills.tools import qrcodetools +from skills.tools import qrcodetools qrcodetools(url='https://www.python-office.com', output='./my_qrcode.png') ``` diff --git a/skills/tools/transtools/SKILL.md b/skills/tools/transtools/SKILL.md index 33ee8a42..2628cfad 100644 --- a/skills/tools/transtools/SKILL.md +++ b/skills/tools/transtools/SKILL.md @@ -18,7 +18,7 @@ description: 将内容从一种语言翻译为另一种语言。当用户提到 ## 调用方式 ```python -from office.skills.tools import transtools +from skills.tools import transtools result = transtools( to_lang='en', @@ -43,7 +43,7 @@ print(result) ## 使用示例 ```python -from office.skills.tools import transtools +from skills.tools import transtools result = transtools(to_lang='en', content='你好,世界!') print(result) # Hello, world! ``` diff --git a/skills/tools/url2ip/SKILL.md b/skills/tools/url2ip/SKILL.md index d597130d..3eebfa2a 100644 --- a/skills/tools/url2ip/SKILL.md +++ b/skills/tools/url2ip/SKILL.md @@ -18,7 +18,7 @@ description: 将 URL 解析为对应的 IP 地址。当用户提到 URL 转 IP ## 调用方式 ```python -from office.skills.tools import url2ip +from skills.tools import url2ip ip = url2ip(url='https://www.python-office.com') print(ip) @@ -37,7 +37,7 @@ print(ip) ## 使用示例 ```python -from office.skills.tools import url2ip +from skills.tools import url2ip ip = url2ip(url='https://www.baidu.com') print(f"百度 IP: {ip}") ``` diff --git a/skills/tools/weather/SKILL.md b/skills/tools/weather/SKILL.md index 187db7ed..3e3f361a 100644 --- a/skills/tools/weather/SKILL.md +++ b/skills/tools/weather/SKILL.md @@ -18,7 +18,7 @@ description: 获取当前天气信息。当用户提到查天气、天气查询 ## 调用方式 ```python -from office.skills.tools import weather +from skills.tools import weather weather() ``` @@ -34,7 +34,7 @@ weather() ## 使用示例 ```python -from office.skills.tools import weather +from skills.tools import weather weather() ``` diff --git a/skills/video/__init__.py b/skills/video/__init__.py index a7542006..db71a149 100644 --- a/skills/video/__init__.py +++ b/skills/video/__init__.py @@ -1,13 +1,30 @@ # -*- coding: UTF-8 -*- """Video Skills 包 - 统一暴露视频处理相关的所有 Skills""" -from office.skills.video.video2mp3 import video2mp3 -from office.skills.video.audio2txt import audio2txt -from office.skills.video.mark2video import mark2video -from office.skills.video.txt2mp3 import txt2mp3 +from .video2mp3 import video2mp3 +from .audio2txt import audio2txt +from .mark2video import mark2video +from .txt2mp3 import txt2mp3 +from .video_edit import ( + cut_video, + cut_audio, + crop_video, + concat_videos, + concat_audios, + add_audio_to_video, +) __all__ = [ 'video2mp3', 'audio2txt', 'mark2video', 'txt2mp3', + 'cut_video', + 'cut_audio', + 'crop_video', + 'concat_videos', + 'concat_audios', + 'add_audio_to_video', ] + + + diff --git a/skills/video/audio2txt/SKILL.md b/skills/video/audio2txt/SKILL.md index bd394324..9bd20e99 100644 --- a/skills/video/audio2txt/SKILL.md +++ b/skills/video/audio2txt/SKILL.md @@ -20,7 +20,7 @@ description: 从音频文件中提取文字(语音转文字),需要腾讯 ## 调用方式 ```python -from office.skills.video import audio2txt +from skills.video import audio2txt audio2txt( audio_path='./test.mp3', @@ -46,7 +46,7 @@ audio2txt( ## 使用示例 ```python -from office.skills.video import audio2txt +from skills.video import audio2txt audio2txt( audio_path='./audio.mp3', appid='your_appid', diff --git a/skills/video/mark2video/SKILL.md b/skills/video/mark2video/SKILL.md index d66a0ac7..9bdfe698 100644 --- a/skills/video/mark2video/SKILL.md +++ b/skills/video/mark2video/SKILL.md @@ -18,7 +18,7 @@ description: 给视频添加文字水印,支持自定义字体大小、类型 ## 调用方式 ```python -from office.skills.video import mark2video +from skills.video import mark2video mark2video( video_path='./test.mp4', @@ -50,7 +50,7 @@ mark2video( ## 使用示例 ```python -from office.skills.video import mark2video +from skills.video import mark2video mark2video(video_path='./demo.mp4', mark_str='My Channel') ``` diff --git a/skills/video/txt2mp3/SKILL.md b/skills/video/txt2mp3/SKILL.md index d726be59..55cce194 100644 --- a/skills/video/txt2mp3/SKILL.md +++ b/skills/video/txt2mp3/SKILL.md @@ -18,7 +18,7 @@ description: 将文本内容转换为 MP3 语音文件,可选择直接朗读 ## 调用方式 ```python -from office.skills.video import txt2mp3 +from skills.video import txt2mp3 txt2mp3( content='你好,世界', @@ -44,7 +44,7 @@ txt2mp3( ## 使用示例 ```python -from office.skills.video import txt2mp3 +from skills.video import txt2mp3 # 直接朗读 txt2mp3(content='你好,世界', mp3=None, speak=True) # 保存为 mp3 文件 diff --git a/skills/video/video2mp3/SKILL.md b/skills/video/video2mp3/SKILL.md index 7c739223..c1f29593 100644 --- a/skills/video/video2mp3/SKILL.md +++ b/skills/video/video2mp3/SKILL.md @@ -18,7 +18,7 @@ description: 从视频文件中提取音频并保存为 MP3。当用户提到视 ## 调用方式 ```python -from office.skills.video import video2mp3 +from skills.video import video2mp3 video2mp3( path='./test.mp4', @@ -42,7 +42,7 @@ video2mp3( ## 使用示例 ```python -from office.skills.video import video2mp3 +from skills.video import video2mp3 video2mp3(path='./movie.mp4', mp3_name='movie_audio.mp3') ``` diff --git a/skills/video/video_edit/SKILL.md b/skills/video/video_edit/SKILL.md new file mode 100644 index 00000000..0951120d --- /dev/null +++ b/skills/video/video_edit/SKILL.md @@ -0,0 +1,119 @@ +--- +name: video_edit +description: 音视频剪辑工具箱。包含视频剪辑截取、音频剪辑截取、视频画面裁剪、视频拼接合并、音频拼接合并、视频合成/替换音频。当用户提到音视频剪辑、裁剪视频、合并视频、音频剪辑、视频配音时使用。 +--- + +# video_edit Skill + +> 音视频剪辑功能集(截取、裁剪、拼接、配音/音轨替换) + +## 功能描述 + +本 Skill 将所有音视频剪辑相关功能合并为一个统一的 API 模块,包含以下 6 个核心剪辑功能: + +1. `cut_video`: 截取视频指定时间段片段 +2. `cut_audio`: 截取音频指定时间段片段 +3. `crop_video`: 裁剪视频画面的坐标区域与尺寸 +4. `concat_videos`: 多个视频文件顺序拼接合并 +5. `concat_audios`: 多个音频文件顺序拼接合并 +6. `add_audio_to_video`: 视频合成/替换背景音乐或音频 + +## 所属分类 + +`office/skills/video/video_edit/` + +## 调用方式 + +```python +from skills.video.video_edit import ( + cut_video, + cut_audio, + crop_video, + concat_videos, + concat_audios, + add_audio_to_video, +) +``` + +或从 `skills.video` 模块导入: +```python +from skills.video import video_edit + +video_edit.cut_video(video_path='./test.mp4', start_time='00:00:10', end_time='00:00:30') +``` + +## 功能与参数说明 + +### 1. 视频截取 `cut_video` +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| `video_path` | str | 是 | - | 视频文件路径 | +| `start_time` | float/str | 否 | `0` | 开始时间(秒数或格式如 `'00:01:10'`) | +| `end_time` | float/str | 否 | `None` | 结束时间(秒数或格式如 `'00:02:30'`,默认结尾) | +| `output_path` | str | 否 | `'./'` | 输出目录 | +| `output_name` | str | 否 | `None` | 输出文件名(默认原名后加 `_cut`) | + +### 2. 音频截取 `cut_audio` +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| `audio_path` | str | 是 | - | 音频文件路径 | +| `start_time` | float/str | 否 | `0` | 开始时间(秒数或格式如 `'00:00:05'`) | +| `end_time` | float/str | 否 | `None` | 结束时间 | +| `output_path` | str | 否 | `'./'` | 输出目录 | +| `output_name` | str | 否 | `None` | 输出文件名 | + +### 3. 画面裁剪 `crop_video` +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| `video_path` | str | 是 | - | 视频文件路径 | +| `x1` | int | 否 | `0` | 左上角 x 坐标 | +| `y1` | int | 否 | `0` | 左上角 y 坐标 | +| `x2` | int | 否 | `None` | 右下角 x 坐标 | +| `y2` | int | 否 | `None` | 右下角 y 坐标 | +| `width` | int | 否 | `None` | 裁剪宽度(可代替 x2) | +| `height` | int | 否 | `None` | 裁剪高度(可代替 y2) | +| `output_path` | str | 否 | `'./'` | 输出目录 | +| `output_name` | str | 否 | `None` | 输出文件名 | + +### 4. 视频拼接 `concat_videos` +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| `video_list` | list[str] | 是 | - | 视频路径列表 | +| `output_path` | str | 否 | `'./'` | 输出目录 | +| `output_name` | str | 否 | `'concat_video.mp4'` | 输出文件名 | + +### 5. 音频拼接 `concat_audios` +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| `audio_list` | list[str] | 是 | - | 音频路径列表 | +| `output_path` | str | 否 | `'./'` | 输出目录 | +| `output_name` | str | 否 | `'concat_audio.mp3'` | 输出文件名 | + +### 6. 合成音频/配音 `add_audio_to_video` +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| `video_path` | str | 是 | - | 视频文件路径 | +| `audio_path` | str | 是 | - | 音频文件路径 | +| `output_path` | str | 否 | `'./'` | 输出目录 | +| `output_name` | str | 否 | `None` | 输出文件名 | + +## 使用示例 + +```python +from skills.video import video_edit + +# 视频截取 +video_edit.cut_video(video_path='./input.mp4', start_time=0, end_time=10) + +# 视频合成音频 +video_edit.add_audio_to_video(video_path='./input.mp4', audio_path='./music.mp3') +``` + +## 原始函数 + +- `office.api.video.cut_video` +- `office.api.video.cut_audio` +- `office.api.video.crop_video` +- `office.api.video.concat_videos` +- `office.api.video.concat_audios` +- `office.api.video.add_audio_to_video` diff --git a/skills/video/video_edit/__init__.py b/skills/video/video_edit/__init__.py new file mode 100644 index 00000000..d16da5e3 --- /dev/null +++ b/skills/video/video_edit/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: UTF-8 -*- +"""video_edit Skill - 音视频剪辑集合(截取、画面裁剪、音视频拼接、合成/替换音频)""" +from office.api.video import ( + cut_video, + cut_audio, + crop_video, + concat_videos, + concat_audios, + add_audio_to_video, +) + +__all__ = [ + 'cut_video', + 'cut_audio', + 'crop_video', + 'concat_videos', + 'concat_audios', + 'add_audio_to_video', +] diff --git a/skills/web/__init__.py b/skills/web/__init__.py new file mode 100644 index 00000000..4fa8576e --- /dev/null +++ b/skills/web/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: UTF-8 -*- +"""Web Skills 包 - 统一暴露网页处理相关的所有 Skills""" +from .url2ebook import url2ebook + +__all__ = ['url2ebook'] diff --git a/skills/web/url2ebook/SKILL.md b/skills/web/url2ebook/SKILL.md new file mode 100644 index 00000000..90146b78 --- /dev/null +++ b/skills/web/url2ebook/SKILL.md @@ -0,0 +1,53 @@ +--- +name: url2ebook +description: 将网页 URL 转换为电子书。当用户提到网页转电子书、URL 转 ebook、网页转 EPUB、离线阅读网页、pospider 时使用。 +--- + +# url2ebook Skill + +> 将指定网页转换为电子书 + +## 功能描述 + +抓取网页主要内容,生成可离线阅读的电子书。依赖可选包 `pospider`。 + +## 所属分类 + +`office/skills/web/url2ebook/` + +## 调用方式 + +```python +from skills.web import url2ebook + +url2ebook( + url='https://www.python-office.com', + tile='Python-Office自动化办公指南' +) +``` + +## 参数说明 + +| 参数 | 类型 | 必填 | 默认值 | 说明 | +|------|------|------|--------|------| +| `url` | str | 是 | - | 要转换的网页地址 | +| `tile` | str | 是 | - | 电子书标题(参数名是 `tile`,不是 `title`) | + +## 返回值 + +`None`(成功后生成电子书文件) + +## 使用示例 + +```python +from skills.web import url2ebook +url2ebook(url='https://www.python-office.com', tile='Python-Office自动化办公指南') +``` + +## 原始函数 + +`office.api.web.url2ebook` + +## 示例代码 + +`examples/pospider/网页转电子书.py` diff --git a/skills/web/url2ebook/__init__.py b/skills/web/url2ebook/__init__.py new file mode 100644 index 00000000..eff1e0a7 --- /dev/null +++ b/skills/web/url2ebook/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: UTF-8 -*- +"""url2ebook Skill - 将网页转换为电子书""" +from office.api.web import url2ebook + +__all__ = ['url2ebook'] diff --git a/skills/wechat/__init__.py b/skills/wechat/__init__.py index bbd46184..d7bee7e1 100644 --- a/skills/wechat/__init__.py +++ b/skills/wechat/__init__.py @@ -1,12 +1,12 @@ # -*- coding: UTF-8 -*- """WeChat Skills 包 - 统一暴露微信自动化相关的所有 Skills""" -from office.skills.wechat.send_message import send_message -from office.skills.wechat.send_message_by_time import send_message_by_time -from office.skills.wechat.chat_by_keywords import chat_by_keywords -from office.skills.wechat.send_file import send_file -from office.skills.wechat.group_send import group_send -from office.skills.wechat.receive_message import receive_message -from office.skills.wechat.chat_robot import chat_robot +from .send_message import send_message +from .send_message_by_time import send_message_by_time +from .chat_by_keywords import chat_by_keywords +from .send_file import send_file +from .group_send import group_send +from .receive_message import receive_message +from .chat_robot import chat_robot __all__ = [ 'send_message', diff --git a/skills/wechat/chat_by_keywords/SKILL.md b/skills/wechat/chat_by_keywords/SKILL.md index 6c1b0770..25e65185 100644 --- a/skills/wechat/chat_by_keywords/SKILL.md +++ b/skills/wechat/chat_by_keywords/SKILL.md @@ -18,7 +18,7 @@ description: 通过微信按关键词列表与指定联系人自动聊天。当 ## 调用方式 ```python -from office.skills.wechat import chat_by_keywords +from skills.wechat import chat_by_keywords chat_by_keywords(who='文件传输助手', keywords=['你好', '在吗']) ``` @@ -37,7 +37,7 @@ chat_by_keywords(who='文件传输助手', keywords=['你好', '在吗']) ## 使用示例 ```python -from office.skills.wechat import chat_by_keywords +from skills.wechat import chat_by_keywords chat_by_keywords(who='文件传输助手', keywords=['你好', 'hello', 'hi']) ``` diff --git a/skills/wechat/chat_robot/SKILL.md b/skills/wechat/chat_robot/SKILL.md index be2f814e..1f6d3021 100644 --- a/skills/wechat/chat_robot/SKILL.md +++ b/skills/wechat/chat_robot/SKILL.md @@ -18,7 +18,7 @@ description: 通过微信与指定联系人进行智能聊天(基于 AI 回复 ## 调用方式 ```python -from office.skills.wechat import chat_robot +from skills.wechat import chat_robot chat_robot(who='程序员晚枫') ``` @@ -36,7 +36,7 @@ chat_robot(who='程序员晚枫') ## 使用示例 ```python -from office.skills.wechat import chat_robot +from skills.wechat import chat_robot chat_robot(who='文件传输助手') ``` diff --git a/skills/wechat/group_send/SKILL.md b/skills/wechat/group_send/SKILL.md index a45a7ab9..57cf7493 100644 --- a/skills/wechat/group_send/SKILL.md +++ b/skills/wechat/group_send/SKILL.md @@ -18,7 +18,7 @@ description: 通过微信向多个联系人群发消息。当用户提到微信 ## 调用方式 ```python -from office.skills.wechat import group_send +from skills.wechat import group_send group_send() ``` @@ -34,7 +34,7 @@ group_send() ## 使用示例 ```python -from office.skills.wechat import group_send +from skills.wechat import group_send group_send() ``` diff --git a/skills/wechat/receive_message/SKILL.md b/skills/wechat/receive_message/SKILL.md index 031d41d3..91f18d33 100644 --- a/skills/wechat/receive_message/SKILL.md +++ b/skills/wechat/receive_message/SKILL.md @@ -18,7 +18,7 @@ description: 通过微信接收消息并保存到本地文件。当用户提到 ## 调用方式 ```python -from office.skills.wechat import receive_message +from skills.wechat import receive_message receive_message( who='文件传输助手', @@ -42,7 +42,7 @@ receive_message( ## 使用示例 ```python -from office.skills.wechat import receive_message +from skills.wechat import receive_message receive_message(who='文件传输助手', txt='messages.txt', output_path='./received/') ``` diff --git a/skills/wechat/send_file/SKILL.md b/skills/wechat/send_file/SKILL.md index b96fb447..e0b19ef9 100644 --- a/skills/wechat/send_file/SKILL.md +++ b/skills/wechat/send_file/SKILL.md @@ -18,7 +18,7 @@ description: 通过微信向指定联系人发送文件。当用户提到微信 ## 调用方式 ```python -from office.skills.wechat import send_file +from skills.wechat import send_file send_file(who='文件传输助手', file='./test.txt') ``` @@ -37,7 +37,7 @@ send_file(who='文件传输助手', file='./test.txt') ## 使用示例 ```python -from office.skills.wechat import send_file +from skills.wechat import send_file send_file(who='文件传输助手', file='./report.pdf') ``` diff --git a/skills/wechat/send_message/SKILL.md b/skills/wechat/send_message/SKILL.md index 4de4373f..3c19a3bb 100644 --- a/skills/wechat/send_message/SKILL.md +++ b/skills/wechat/send_message/SKILL.md @@ -18,7 +18,7 @@ description: 通过微信自动化向指定联系人发送消息。当用户提 ## 调用方式 ```python -from office.skills.wechat import send_message +from skills.wechat import send_message send_message(who='文件传输助手', message='Hello, World!') ``` @@ -37,7 +37,7 @@ send_message(who='文件传输助手', message='Hello, World!') ## 使用示例 ```python -from office.skills.wechat import send_message +from skills.wechat import send_message send_message(who='文件传输助手', message='Hello, World!') ``` diff --git a/skills/wechat/send_message_by_time/SKILL.md b/skills/wechat/send_message_by_time/SKILL.md index 60d99478..c9243c7f 100644 --- a/skills/wechat/send_message_by_time/SKILL.md +++ b/skills/wechat/send_message_by_time/SKILL.md @@ -18,7 +18,7 @@ description: 通过微信在指定时间向联系人发送定时消息。当用 ## 调用方式 ```python -from office.skills.wechat import send_message_by_time +from skills.wechat import send_message_by_time send_message_by_time( who='文件传输助手', @@ -42,7 +42,7 @@ send_message_by_time( ## 使用示例 ```python -from office.skills.wechat import send_message_by_time +from skills.wechat import send_message_by_time send_message_by_time(who='文件传输助手', message='早安', time='08:00:00') ``` diff --git a/skills/word/__init__.py b/skills/word/__init__.py index f03916b5..42be7373 100644 --- a/skills/word/__init__.py +++ b/skills/word/__init__.py @@ -1,10 +1,10 @@ # -*- coding: UTF-8 -*- """Word Skills 包 - 统一暴露 Word 处理相关的所有 Skills""" -from office.skills.word.docx2pdf import docx2pdf -from office.skills.word.merge4docx import merge4docx -from office.skills.word.doc2docx import doc2docx -from office.skills.word.docx2doc import docx2doc -from office.skills.word.docx4imgs import docx4imgs +from .docx2pdf import docx2pdf +from .merge4docx import merge4docx +from .doc2docx import doc2docx +from .docx2doc import docx2doc +from .docx4imgs import docx4imgs __all__ = [ 'docx2pdf', diff --git a/skills/word/doc2docx/SKILL.md b/skills/word/doc2docx/SKILL.md index 9d5d4471..3994e49d 100644 --- a/skills/word/doc2docx/SKILL.md +++ b/skills/word/doc2docx/SKILL.md @@ -18,7 +18,7 @@ description: 将旧版 Word 文档(.doc)转换为新版(.docx)。当用 ## 调用方式 ```python -from office.skills.word import doc2docx +from skills.word import doc2docx doc2docx( input_path='./old.doc', @@ -30,7 +30,7 @@ doc2docx( 也可以直接把目标文件路径传给 `output_path`: ```python -from office.skills.word import doc2docx +from skills.word import doc2docx doc2docx( input_path='./old.doc', @@ -53,12 +53,12 @@ doc2docx( ## 使用示例 ```python -from office.skills.word import doc2docx +from skills.word import doc2docx doc2docx(input_path='./old.doc', output_path='./new/') ``` ```python -from office.skills.word import doc2docx +from skills.word import doc2docx doc2docx(input_path='./old.doc', output_path='./new/new.docx') ``` diff --git a/skills/word/docx2doc/SKILL.md b/skills/word/docx2doc/SKILL.md index ca70a7d2..ec2d55cf 100644 --- a/skills/word/docx2doc/SKILL.md +++ b/skills/word/docx2doc/SKILL.md @@ -18,7 +18,7 @@ description: 将新版 Word 文档(.docx)转换为旧版(.doc)。当用 ## 调用方式 ```python -from office.skills.word import docx2doc +from skills.word import docx2doc docx2doc( input_path='./new.docx', @@ -42,7 +42,7 @@ docx2doc( ## 使用示例 ```python -from office.skills.word import docx2doc +from skills.word import docx2doc docx2doc(input_path='./new.docx', output_path='./old/') ``` diff --git a/skills/word/docx2pdf/SKILL.md b/skills/word/docx2pdf/SKILL.md index 68917f02..12a29678 100644 --- a/skills/word/docx2pdf/SKILL.md +++ b/skills/word/docx2pdf/SKILL.md @@ -18,7 +18,7 @@ description: 将 Word 文档(.docx)转换为 PDF,支持单文件和整个 ## 调用方式 ```python -from office.skills.word import docx2pdf +from skills.word import docx2pdf # 单个文件 docx2pdf(path='./test.docx', output_path='./output/') @@ -41,7 +41,7 @@ docx2pdf(path='./word_files/', output_path='./pdfs/') ## 使用示例 ```python -from office.skills.word import docx2pdf +from skills.word import docx2pdf docx2pdf(path='./report.docx', output_path='./output/') ``` diff --git a/skills/word/docx4imgs/SKILL.md b/skills/word/docx4imgs/SKILL.md index 7f334752..29f1177d 100644 --- a/skills/word/docx4imgs/SKILL.md +++ b/skills/word/docx4imgs/SKILL.md @@ -18,7 +18,7 @@ description: 从 Word 文档中提取所有图片并保存到指定目录。当 ## 调用方式 ```python -from office.skills.word import docx4imgs +from skills.word import docx4imgs docx4imgs( word_path='./test.docx', @@ -40,7 +40,7 @@ docx4imgs( ## 使用示例 ```python -from office.skills.word import docx4imgs +from skills.word import docx4imgs docx4imgs(word_path='./document.docx', img_path='./extracted_images/') ``` diff --git a/skills/word/merge4docx/SKILL.md b/skills/word/merge4docx/SKILL.md index 6aecac74..f08638e5 100644 --- a/skills/word/merge4docx/SKILL.md +++ b/skills/word/merge4docx/SKILL.md @@ -18,7 +18,7 @@ description: 将多个 Word 文档合并为一个文件。当用户提到 Word ## 调用方式 ```python -from office.skills.word import merge4docx +from skills.word import merge4docx merge4docx( input_path='./word_files', @@ -42,7 +42,7 @@ merge4docx( ## 使用示例 ```python -from office.skills.word import merge4docx +from skills.word import merge4docx merge4docx( input_path='./word_files', output_path='./output/', diff --git a/tests/test_code/test_excel_split_wrapper.py b/tests/test_code/test_excel_split_wrapper.py new file mode 100644 index 00000000..32be8508 --- /dev/null +++ b/tests/test_code/test_excel_split_wrapper.py @@ -0,0 +1,69 @@ +"""Tests for the Excel split-by-column API wrapper.""" + +import importlib.util +from pathlib import Path +import sys +from types import ModuleType, SimpleNamespace +import unittest +from unittest.mock import Mock, patch + + +def load_excel_api(poexcel): + module_path = Path(__file__).resolve().parents[2] / "office" / "api" / "excel.py" + spec = importlib.util.spec_from_file_location("excel_api_under_test", module_path) + module = importlib.util.module_from_spec(spec) + + with patch.dict(sys.modules, {"poexcel": poexcel}): + spec.loader.exec_module(module) + + return module + + +class TestExcelSplitWrapper(unittest.TestCase): + def test_delegates_to_poexcel_when_export_is_available(self): + split_excel = Mock() + excel = load_excel_api( + SimpleNamespace(split_excel_by_column=split_excel) + ) + + excel.split_excel_by_column( + filepath="orders.xlsx", + column=2, + worksheet_name="Orders", + ) + + split_excel.assert_called_once_with( + filepath="orders.xlsx", + column=2, + worksheet_name="Orders", + ) + + def test_falls_back_to_bundled_implementation_when_export_is_missing(self): + split_excel = Mock() + split_module = ModuleType("office.lib.excel.SplitExcel") + split_module.split_excel_by_column = split_excel + + modules = { + "office": ModuleType("office"), + "office.lib": ModuleType("office.lib"), + "office.lib.excel": ModuleType("office.lib.excel"), + "office.lib.excel.SplitExcel": split_module, + } + excel = load_excel_api(SimpleNamespace()) + + with patch.dict(sys.modules, modules): + excel.split_excel_by_column( + filepath="orders.xlsx", + column=2, + worksheet_name="Orders", + ) + + split_excel.assert_called_once_with( + filepath="orders.xlsx", + column=2, + worksheet_name="Orders", + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_code/test_img.py b/tests/test_code/test_img.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/test_code/test_instruction_url.py b/tests/test_code/test_instruction_url.py new file mode 100644 index 00000000..592b5385 --- /dev/null +++ b/tests/test_code/test_instruction_url.py @@ -0,0 +1,89 @@ +"""Tests for the instruction URL decorator.""" + +import importlib.util +from pathlib import Path +import sys +import types +import unittest + + +class TestInstructionUrl(unittest.TestCase): + def setUp(self): + self._original_modules = { + name: sys.modules.get(name) + for name in ( + "pocode", + "pocode.api", + "pocode.api.color", + "office", + "office.api", + "office.lib", + "office.lib.conf", + "office.lib.conf.CONST", + "office.lib.decorator_utils.instruction_url", + ) + } + + sys.modules["pocode"] = types.ModuleType("pocode") + sys.modules["pocode.api"] = types.ModuleType("pocode.api") + color_module = types.ModuleType("pocode.api.color") + color_module.random_color_print = lambda *args, **kwargs: None + sys.modules["pocode.api.color"] = color_module + const_module = types.ModuleType("office.lib.conf.CONST") + const_module.SPLIT_LINE = "-" * 20 + api_module = types.ModuleType("office.api") + office_module = types.ModuleType("office") + office_module.api = api_module + sys.modules["office"] = office_module + sys.modules["office.api"] = api_module + sys.modules["office.lib"] = types.ModuleType("office.lib") + sys.modules["office.lib.conf"] = types.ModuleType("office.lib.conf") + sys.modules["office.lib.conf.CONST"] = const_module + sys.modules.pop("office.lib.decorator_utils.instruction_url", None) + + def tearDown(self): + for name in ( + "pocode", + "pocode.api", + "pocode.api.color", + "office", + "office.api", + "office.lib", + "office.lib.conf", + "office.lib.conf.CONST", + "office.lib.decorator_utils.instruction_url", + ): + sys.modules.pop(name, None) + + for name, module in self._original_modules.items(): + if module is not None: + sys.modules[name] = module + + def test_missing_method_link_does_not_block_wrapped_function(self): + module_path = ( + Path(__file__).resolve().parents[2] + / "office" + / "lib" + / "decorator_utils" + / "instruction_url.py" + ) + spec = importlib.util.spec_from_file_location( + "office.lib.decorator_utils.instruction_url", + module_path, + ) + instruction_url = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = instruction_url + spec.loader.exec_module(instruction_url) + namespace = {} + exec( + compile("def undocumented_feature():\n return 'ok'\n", "/tmp/excel.py", "exec"), + namespace, + ) + + wrapped = instruction_url.instruction(namespace["undocumented_feature"]) + + self.assertEqual("ok", wrapped()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_code/test_optional_imports.py b/tests/test_code/test_optional_imports.py index 227863e9..b98ebb44 100644 --- a/tests/test_code/test_optional_imports.py +++ b/tests/test_code/test_optional_imports.py @@ -1,4 +1,4 @@ -"""Tests for optional platform-specific imports.""" +"""Tests for optional dependency imports.""" from contextlib import contextmanager import importlib @@ -19,13 +19,13 @@ "poocr", "pomarkdown", "wftools", - "pospider", ] -WINDOWS_ONLY_DEPENDENCIES = [ +OPTIONAL_DEPENDENCIES = [ "poppt", "poword", "PyOfficeRobot", + "pospider", ] MANAGED_MODULE_PREFIXES = ( @@ -33,7 +33,7 @@ "pocode", ) -WINDOWS_ONLY_LOADERS = [ +OPTIONAL_LOADERS = [ ( "office.api.word", "_load_poword", @@ -55,6 +55,13 @@ "uiautomation", "微信自动化功能依赖 PyOfficeRobot", ), + ( + "office.api.web", + "_load_pospider", + "pospider", + "requests", + "网页转电子书功能依赖 pospider", + ), ] @@ -63,13 +70,13 @@ def _is_managed_module(name): class TestOptionalImports(unittest.TestCase): - """Check that Windows-only dependencies do not break package imports.""" + """Check that optional dependencies do not break package imports.""" @contextmanager def _optional_import_test_environment(self): module_names = ( SUPPORTED_DEPENDENCIES - + WINDOWS_ONLY_DEPENDENCIES + + OPTIONAL_DEPENDENCIES + ["pocode", "pocode.api", "pocode.api.color"] ) original_modules = { @@ -101,7 +108,7 @@ def _optional_import_test_environment(self): color_module.random_color_print = lambda *args, **kwargs: None sys.modules["pocode.api.color"] = color_module - for name in WINDOWS_ONLY_DEPENDENCIES: + for name in OPTIONAL_DEPENDENCIES: sys.modules.pop(name, None) yield @@ -119,16 +126,27 @@ def _optional_import_test_environment(self): if module is not None: sys.modules[name] = module - def test_import_office_without_windows_only_dependencies(self): + def test_import_office_without_optional_dependencies(self): with self._optional_import_test_environment(): - importlib.import_module("office") + office = importlib.import_module("office") + + self.assertIsNotNone(office.web) + + def test_compatibility_check_does_not_fail_when_mark_file_cannot_be_written(self): + with self._optional_import_test_environment(): + compatibility = importlib.import_module("office.compatibility") + + with mock.patch.object(compatibility.Path, "mkdir", side_effect=PermissionError("readonly")): + checker = compatibility.CrossPlatformCompatibility() + + self.assertFalse(checker.is_first_run) def test_loader_preserves_dependency_internal_import_errors(self): with self._optional_import_test_environment(): importlib.import_module("office") original_import = __import__ - for module_name, loader_name, dependency_name, internal_name, message in WINDOWS_ONLY_LOADERS: + for module_name, loader_name, dependency_name, internal_name, message in OPTIONAL_LOADERS: with self.subTest(dependency_name=dependency_name): api_module = importlib.import_module(module_name) loader = getattr(api_module, loader_name) @@ -150,11 +168,11 @@ def import_with_missing_internal_dependency( self.assertEqual(internal_name, error.exception.name) self.assertNotIn(message, str(error.exception)) - def test_loader_reports_missing_windows_only_dependency(self): + def test_loader_reports_missing_optional_dependency(self): with self._optional_import_test_environment(): importlib.import_module("office") - for module_name, loader_name, dependency_name, _, message in WINDOWS_ONLY_LOADERS: + for module_name, loader_name, dependency_name, _, message in OPTIONAL_LOADERS: with self.subTest(dependency_name=dependency_name): api_module = importlib.import_module(module_name) loader = getattr(api_module, loader_name) diff --git a/tests/test_code/test_pdf_add_watermark_behavior.py b/tests/test_code/test_pdf_add_watermark_behavior.py new file mode 100644 index 00000000..8c64aac0 --- /dev/null +++ b/tests/test_code/test_pdf_add_watermark_behavior.py @@ -0,0 +1,193 @@ +"""Behavioral tests for ``pdf_add_watermark`` (no real PDF deps required). + +Covers the two fixes in office/lib/pdf/add_watermark_service.py: + 1. input/mark streams are always closed, including early-return paths; + 2. an empty (0-page) watermark PDF is handled gracefully instead of raising + IndexError from ``pdf_watermark.pages[0]``. + +Dependencies (PyPDF2/reportlab/tqdm) are mocked, following the convention of +``test_pdf_add_watermark_imports.py``. +""" + +import builtins +import importlib.util +from pathlib import Path +import sys +import tempfile +import types +import unittest +from unittest import mock + + +class FakePage: + def merge_page(self, watermark): + pass + + def compress_content_streams(self): + pass + + +class FakePdfReader: + def __init__(self, pages=None, is_encrypted=False, decrypt_fails=False): + self.pages = pages if pages is not None else [FakePage()] + self.is_encrypted = is_encrypted + self.decrypt_fails = decrypt_fails + + def decrypt(self, password): + if self.decrypt_fails: + raise Exception("解密失败") + return 1 + + +class FakePdfWriter: + def __init__(self): + self.pages = [] + + def add_page(self, page): + self.pages.append(page) + + def write(self, file_obj): + file_obj.write(b"") + + +class TestPdfAddWatermarkBehavior(unittest.TestCase): + """Behavioral tests for the fixed pdf_add_watermark function.""" + + MODULE_PATH = ( + Path(__file__).resolve().parents[2] + / "office" + / "lib" + / "pdf" + / "add_watermark_service.py" + ) + + def setUp(self): + self._original_modules = {} + for name in ("PyPDF2", "reportlab", "reportlab.pdfgen", + "reportlab.pdfbase", "reportlab.pdfbase.ttfonts", + "reportlab.pdfbase.pdfmetrics", "tqdm"): + self._original_modules[name] = sys.modules.get(name) + + pypdf2 = types.ModuleType("PyPDF2") + self._pdf_reader_mock = mock.Mock() + pypdf2.PdfReader = self._pdf_reader_mock + pypdf2.PdfWriter = FakePdfWriter + sys.modules["PyPDF2"] = pypdf2 + + reportlab = types.ModuleType("reportlab") + pdfgen = types.ModuleType("reportlab.pdfgen") + pdfgen.canvas = types.SimpleNamespace(Canvas=object) + pdfbase = types.ModuleType("reportlab.pdfbase") + ttfonts = types.ModuleType("reportlab.pdfbase.ttfonts") + ttfonts.TTFont = object + pdfmetrics = types.ModuleType("reportlab.pdfbase.pdfmetrics") + pdfmetrics.registerFont = lambda *args, **kwargs: None + pdfbase.ttfonts = ttfonts + pdfbase.pdfmetrics = pdfmetrics + reportlab.pdfbase = pdfbase + sys.modules["reportlab"] = reportlab + sys.modules["reportlab.pdfgen"] = pdfgen + sys.modules["reportlab.pdfbase"] = pdfbase + sys.modules["reportlab.pdfbase.ttfonts"] = ttfonts + sys.modules["reportlab.pdfbase.pdfmetrics"] = pdfmetrics + + tqdm_module = types.ModuleType("tqdm") + tqdm_module.tqdm = lambda iterable: iterable + sys.modules["tqdm"] = tqdm_module + + def tearDown(self): + for name, module in self._original_modules.items(): + if module is not None: + sys.modules[name] = module + else: + sys.modules.pop(name, None) + + def _load_module(self): + spec = importlib.util.spec_from_file_location( + "pdf_add_watermark_service_behavior_test", + self.MODULE_PATH, + ) + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + spec.loader.exec_module(module) + return module + + @staticmethod + def _track_open(): + """Return (patcher, list_of_opened_file_objects) for builtins.open.""" + real_open = builtins.open + opened = [] + + def tracking_open(*args, **kwargs): + f = real_open(*args, **kwargs) + opened.append(f) + return f + + return mock.patch("builtins.open", side_effect=tracking_open), opened + + def test_empty_watermark_returns_false_without_crashing(self): + module = self._load_module() + self._pdf_reader_mock.side_effect = [ + FakePdfReader(pages=[FakePage(), FakePage()]), + FakePdfReader(pages=[]), + ] + + with tempfile.TemporaryDirectory() as tmp: + src = str(Path(tmp) / "source.pdf") + mark = str(Path(tmp) / "mark_empty.pdf") + out = str(Path(tmp) / "out.pdf") + Path(src).write_bytes(b"fake") + Path(mark).write_bytes(b"fake") + + patcher, opened = self._track_open() + with patcher: + result = module.pdf_add_watermark(src, mark, out) + + self.assertFalse(result) + self.assertTrue(all(f.closed for f in opened), "streams must be closed") + + def test_normal_path_returns_true_and_closes_streams(self): + module = self._load_module() + self._pdf_reader_mock.side_effect = [ + FakePdfReader(pages=[FakePage(), FakePage()]), + FakePdfReader(pages=[FakePage()]), + ] + + with tempfile.TemporaryDirectory() as tmp: + src = str(Path(tmp) / "source.pdf") + mark = str(Path(tmp) / "mark.pdf") + out = str(Path(tmp) / "out.pdf") + Path(src).write_bytes(b"fake") + Path(mark).write_bytes(b"fake") + + patcher, opened = self._track_open() + with patcher: + result = module.pdf_add_watermark(src, mark, out) + self.assertTrue(Path(out).exists()) + + self.assertTrue(result) + self.assertTrue(all(f.closed for f in opened), "streams must be closed") + + def test_encrypted_decrypt_failure_closes_input_stream(self): + module = self._load_module() + self._pdf_reader_mock.side_effect = [ + FakePdfReader(pages=[FakePage()], is_encrypted=True, decrypt_fails=True), + ] + + with tempfile.TemporaryDirectory() as tmp: + src = str(Path(tmp) / "source.pdf") + mark = str(Path(tmp) / "mark.pdf") + out = str(Path(tmp) / "out.pdf") + Path(src).write_bytes(b"fake") + Path(mark).write_bytes(b"fake") + + patcher, opened = self._track_open() + with mock.patch("builtins.input", return_value="wrong-password"), patcher: + result = module.pdf_add_watermark(src, mark, out) + + self.assertFalse(result) + self.assertTrue(all(f.closed for f in opened), "input stream must be closed on early return") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_code/test_pdf_add_watermark_imports.py b/tests/test_code/test_pdf_add_watermark_imports.py new file mode 100644 index 00000000..8753e95f --- /dev/null +++ b/tests/test_code/test_pdf_add_watermark_imports.py @@ -0,0 +1,80 @@ +"""Tests for PDF watermark service imports.""" + +import importlib.util +from pathlib import Path +import sys +import types +import unittest + + +class TestPdfAddWatermarkImports(unittest.TestCase): + def setUp(self): + self._module_names = ( + "PyPDF2", + "reportlab", + "reportlab.pdfgen", + "reportlab.pdfbase", + "reportlab.pdfbase.ttfonts", + "reportlab.pdfbase.pdfmetrics", + "tqdm", + "pdf_add_watermark_service_test", + ) + self._original_modules = {name: sys.modules.get(name) for name in self._module_names} + + pypdf2 = types.ModuleType("PyPDF2") + pypdf2.PdfReader = type("PdfReader", (), {}) + pypdf2.PdfWriter = type("PdfWriter", (), {}) + sys.modules["PyPDF2"] = pypdf2 + + reportlab = types.ModuleType("reportlab") + pdfgen = types.ModuleType("reportlab.pdfgen") + pdfgen.canvas = types.SimpleNamespace(Canvas=object) + pdfbase = types.ModuleType("reportlab.pdfbase") + ttfonts = types.ModuleType("reportlab.pdfbase.ttfonts") + ttfonts.TTFont = object + pdfmetrics = types.ModuleType("reportlab.pdfbase.pdfmetrics") + pdfmetrics.registerFont = lambda *args, **kwargs: None + pdfbase.ttfonts = ttfonts + pdfbase.pdfmetrics = pdfmetrics + reportlab.pdfbase = pdfbase + + sys.modules["reportlab"] = reportlab + sys.modules["reportlab.pdfgen"] = pdfgen + sys.modules["reportlab.pdfbase"] = pdfbase + sys.modules["reportlab.pdfbase.ttfonts"] = ttfonts + sys.modules["reportlab.pdfbase.pdfmetrics"] = pdfmetrics + + tqdm_module = types.ModuleType("tqdm") + tqdm_module.tqdm = lambda iterable: iterable + sys.modules["tqdm"] = tqdm_module + + def tearDown(self): + for name in self._module_names: + sys.modules.pop(name, None) + + for name, module in self._original_modules.items(): + if module is not None: + sys.modules[name] = module + + def test_module_imports_with_modern_pypdf2_names(self): + module_path = ( + Path(__file__).resolve().parents[2] + / "office" + / "lib" + / "pdf" + / "add_watermark_service.py" + ) + spec = importlib.util.spec_from_file_location( + "pdf_add_watermark_service_test", + module_path, + ) + module = importlib.util.module_from_spec(spec) + sys.modules[spec.name] = module + + spec.loader.exec_module(module) + + self.assertTrue(hasattr(module, "pdf_add_watermark")) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_code/test_skills_imports.py b/tests/test_code/test_skills_imports.py new file mode 100644 index 00000000..1fc5dc42 --- /dev/null +++ b/tests/test_code/test_skills_imports.py @@ -0,0 +1,40 @@ +# -*- coding: UTF-8 -*- +"""Tests for the public ``skills.`` import surface.""" + +import importlib +import unittest + + +CATEGORIES = ( + "excel", + "file", + "finance", + "image", + "markdown", + "ocr", + "pdf", + "ppt", + "ruiming", + "tools", + "video", + "web", + "wechat", + "word", +) + + +class TestSkillsImports(unittest.TestCase): + def test_category_exports_are_importable(self): + for category in CATEGORIES: + with self.subTest(category=category): + module = importlib.import_module(f"skills.{category}") + self.assertTrue(module.__all__) + for name in module.__all__: + self.assertTrue( + callable(getattr(module, name, None)), + f"skills.{category}.{name} is not callable", + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_code/test_url2ebook_skill.py b/tests/test_code/test_url2ebook_skill.py new file mode 100644 index 00000000..c494a918 --- /dev/null +++ b/tests/test_code/test_url2ebook_skill.py @@ -0,0 +1,45 @@ +# -*- coding: UTF-8 -*- +"""Tests for the url2ebook Skill wrapper.""" + +import ast +from pathlib import Path +import unittest + + +ROOT = Path(__file__).resolve().parents[2] + + +def _assigned_all(source: str): + tree = ast.parse(source) + for node in tree.body: + if isinstance(node, ast.Assign): + for target in node.targets: + if isinstance(target, ast.Name) and target.id == "__all__": + return ast.literal_eval(node.value) + return None + + +class TestUrl2ebookSkill(unittest.TestCase): + def test_web_category_exports_url2ebook(self): + source = (ROOT / "skills" / "web" / "__init__.py").read_text(encoding="utf-8") + self.assertEqual(_assigned_all(source), ["url2ebook"]) + + def test_skill_reexports_web_api(self): + source = (ROOT / "skills" / "web" / "url2ebook" / "__init__.py").read_text( + encoding="utf-8" + ) + self.assertIn("from office.api.web import url2ebook", source) + self.assertEqual(_assigned_all(source), ["url2ebook"]) + + def test_skill_doc_covers_triggers_and_tile_param(self): + skill_md = (ROOT / "skills" / "web" / "url2ebook" / "SKILL.md").read_text( + encoding="utf-8" + ) + self.assertIn("name: url2ebook", skill_md) + self.assertIn("网页转电子书", skill_md) + self.assertIn("`tile`", skill_md) + self.assertIn("office.api.web.url2ebook", skill_md) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_code/test_web.py b/tests/test_code/test_web.py index 452faf8a..64b6841e 100644 --- a/tests/test_code/test_web.py +++ b/tests/test_code/test_web.py @@ -1,18 +1,43 @@ -"""Web功能测试模块。 - -该模块包含对python-office库中Web相关功能的单元测试。 -""" +"""Tests for the web API wrapper.""" +import importlib.util +from pathlib import Path +from types import SimpleNamespace import unittest +from unittest.mock import Mock, patch + + +def load_web_api(): + module_path = Path(__file__).resolve().parents[2] / "office" / "api" / "web.py" + spec = importlib.util.spec_from_file_location("web_api_under_test", module_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +class TestWeb(unittest.TestCase): + def test_url2ebook_delegates_to_pospider(self): + web = load_web_api() + url2ebook = Mock() + pospider = SimpleNamespace(url=SimpleNamespace(url2ebook=url2ebook)) + + with patch.object(web, "_load_pospider", return_value=pospider): + web.url2ebook("https://example.com/article", tile="测试") + + url2ebook.assert_called_once_with( + url="https://example.com/article", + tile="测试", + ) + + def test_loader_reports_incompatible_pospider(self): + web = load_web_api() + + with patch("builtins.__import__", return_value=SimpleNamespace()): + with self.assertRaises(ImportError) as error: + web._load_pospider() -from office.api import web + self.assertIn("不提供 url.url2ebook", str(error.exception)) -# todo: 功能暂时未实现 -class TestWechat(unittest.TestCase): - """Web功能测试类。 - - 该类包含对Web相关API的单元测试方法。 - """ - def test_url2ebook(self): - web.url2ebook('https://www.zhihu.com/question/36810597', title='测试') +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_utils/test_pandas_mem.py b/tests/test_utils/test_pandas_mem.py new file mode 100644 index 00000000..2add4ac1 --- /dev/null +++ b/tests/test_utils/test_pandas_mem.py @@ -0,0 +1,35 @@ +import pandas as pd + +from office.lib.utils.pandas_mem import reduce_pandas_mem_usage + + +def test_object_column_with_integer_name(): + df = pd.DataFrame({0: ["a", "b", "a"]}) + + result = reduce_pandas_mem_usage(df) + + assert str(result[0].dtype) == "category" + + +def test_object_column_is_converted_to_category(): + df = pd.DataFrame({"city": ["a", "b", "a"]}) + + result = reduce_pandas_mem_usage(df) + + assert str(result["city"].dtype) == "category" + + +def test_date_column_name_is_preserved(): + df = pd.DataFrame({"date": ["2026-01-01", "2026-01-02"]}) + + result = reduce_pandas_mem_usage(df) + + assert str(result["date"].dtype) == "object" + + +def test_integer_column_is_downcast(): + df = pd.DataFrame({"count": [1, 2, 3]}) + + result = reduce_pandas_mem_usage(df) + + assert str(result["count"].dtype) == "int8" diff --git a/.qoder/repowiki/en/content/API Reference/API Reference.md b/wiki/en/content/API Reference/API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/API Reference.md rename to wiki/en/content/API Reference/API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Email API Reference.md b/wiki/en/content/API Reference/Email API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Email API Reference.md rename to wiki/en/content/API Reference/Email API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Excel API Reference.md b/wiki/en/content/API Reference/Excel API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Excel API Reference.md rename to wiki/en/content/API Reference/Excel API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/File Management API Reference.md b/wiki/en/content/API Reference/File Management API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/File Management API Reference.md rename to wiki/en/content/API Reference/File Management API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Finance API Reference.md b/wiki/en/content/API Reference/Finance API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Finance API Reference.md rename to wiki/en/content/API Reference/Finance API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Image API Reference.md b/wiki/en/content/API Reference/Image API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Image API Reference.md rename to wiki/en/content/API Reference/Image API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Markdown API Reference.md b/wiki/en/content/API Reference/Markdown API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Markdown API Reference.md rename to wiki/en/content/API Reference/Markdown API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/OCR API Reference.md b/wiki/en/content/API Reference/OCR API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/OCR API Reference.md rename to wiki/en/content/API Reference/OCR API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/PDF API Reference.md b/wiki/en/content/API Reference/PDF API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/PDF API Reference.md rename to wiki/en/content/API Reference/PDF API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/PPT API Reference.md b/wiki/en/content/API Reference/PPT API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/PPT API Reference.md rename to wiki/en/content/API Reference/PPT API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Tools API Reference.md b/wiki/en/content/API Reference/Tools API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Tools API Reference.md rename to wiki/en/content/API Reference/Tools API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Video API Reference.md b/wiki/en/content/API Reference/Video API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Video API Reference.md rename to wiki/en/content/API Reference/Video API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/WeChat API Reference.md b/wiki/en/content/API Reference/WeChat API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/WeChat API Reference.md rename to wiki/en/content/API Reference/WeChat API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Web API Reference.md b/wiki/en/content/API Reference/Web API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Web API Reference.md rename to wiki/en/content/API Reference/Web API Reference.md diff --git a/.qoder/repowiki/en/content/API Reference/Word API Reference.md b/wiki/en/content/API Reference/Word API Reference.md similarity index 100% rename from .qoder/repowiki/en/content/API Reference/Word API Reference.md rename to wiki/en/content/API Reference/Word API Reference.md diff --git a/.qoder/repowiki/en/content/Advanced Usage.md b/wiki/en/content/Advanced Usage.md similarity index 100% rename from .qoder/repowiki/en/content/Advanced Usage.md rename to wiki/en/content/Advanced Usage.md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/Core Modules Reference.md b/wiki/en/content/Core Modules Reference/Core Modules Reference.md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/Core Modules Reference.md rename to wiki/en/content/Core Modules Reference/Core Modules Reference.md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/Email Processing (poemail).md b/wiki/en/content/Core Modules Reference/Email Processing (poemail).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/Email Processing (poemail).md rename to wiki/en/content/Core Modules Reference/Email Processing (poemail).md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/Excel Processing (poexcel).md b/wiki/en/content/Core Modules Reference/Excel Processing (poexcel).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/Excel Processing (poexcel).md rename to wiki/en/content/Core Modules Reference/Excel Processing (poexcel).md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/File Management (pofile).md b/wiki/en/content/Core Modules Reference/File Management (pofile).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/File Management (pofile).md rename to wiki/en/content/Core Modules Reference/File Management (pofile).md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/Image Processing (poimage).md b/wiki/en/content/Core Modules Reference/Image Processing (poimage).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/Image Processing (poimage).md rename to wiki/en/content/Core Modules Reference/Image Processing (poimage).md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/OCR Processing (poocr).md b/wiki/en/content/Core Modules Reference/OCR Processing (poocr).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/OCR Processing (poocr).md rename to wiki/en/content/Core Modules Reference/OCR Processing (poocr).md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/PDF Processing (popdf).md b/wiki/en/content/Core Modules Reference/PDF Processing (popdf).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/PDF Processing (popdf).md rename to wiki/en/content/Core Modules Reference/PDF Processing (popdf).md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/PPT Processing (poppt).md b/wiki/en/content/Core Modules Reference/PPT Processing (poppt).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/PPT Processing (poppt).md rename to wiki/en/content/Core Modules Reference/PPT Processing (poppt).md diff --git a/.qoder/repowiki/en/content/Core Modules Reference/Word Processing (poword).md b/wiki/en/content/Core Modules Reference/Word Processing (poword).md similarity index 100% rename from .qoder/repowiki/en/content/Core Modules Reference/Word Processing (poword).md rename to wiki/en/content/Core Modules Reference/Word Processing (poword).md diff --git a/.qoder/repowiki/en/content/Development and Contribution.md b/wiki/en/content/Development and Contribution.md similarity index 100% rename from .qoder/repowiki/en/content/Development and Contribution.md rename to wiki/en/content/Development and Contribution.md diff --git a/.qoder/repowiki/en/content/GUI Interface.md b/wiki/en/content/GUI Interface.md similarity index 100% rename from .qoder/repowiki/en/content/GUI Interface.md rename to wiki/en/content/GUI Interface.md diff --git a/.qoder/repowiki/en/content/Getting Started.md b/wiki/en/content/Getting Started.md similarity index 100% rename from .qoder/repowiki/en/content/Getting Started.md rename to wiki/en/content/Getting Started.md diff --git a/.qoder/repowiki/en/content/Installation and Setup.md b/wiki/en/content/Installation and Setup.md similarity index 100% rename from .qoder/repowiki/en/content/Installation and Setup.md rename to wiki/en/content/Installation and Setup.md diff --git a/.qoder/repowiki/en/content/Introduction.md b/wiki/en/content/Introduction.md similarity index 100% rename from .qoder/repowiki/en/content/Introduction.md rename to wiki/en/content/Introduction.md diff --git a/.qoder/repowiki/en/content/Resources.md b/wiki/en/content/Resources.md similarity index 100% rename from .qoder/repowiki/en/content/Resources.md rename to wiki/en/content/Resources.md diff --git a/.qoder/repowiki/en/content/Troubleshooting.md b/wiki/en/content/Troubleshooting.md similarity index 100% rename from .qoder/repowiki/en/content/Troubleshooting.md rename to wiki/en/content/Troubleshooting.md diff --git a/.qoder/repowiki/en/meta/repowiki-metadata.json b/wiki/en/meta/repowiki-metadata.json similarity index 100% rename from .qoder/repowiki/en/meta/repowiki-metadata.json rename to wiki/en/meta/repowiki-metadata.json diff --git "a/wiki/zh/content/API\345\217\202\350\200\203/API\345\217\202\350\200\203.md" "b/wiki/zh/content/API\345\217\202\350\200\203/API\345\217\202\350\200\203.md" new file mode 100644 index 00000000..6d8727a3 --- /dev/null +++ "b/wiki/zh/content/API\345\217\202\350\200\203/API\345\217\202\350\200\203.md" @@ -0,0 +1,387 @@ +# API 参考 + + +**本文档中引用的文件** +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/image.py](file://office/api/image.py) +- [office/api/tools.py](file://office/api/tools.py) +- [office/api/file.py](file://office/api/file.py) +- [office/api/wechat.py](file://office/api/wechat.py) +- [office/api/word.py](file://office/api/word.py) +- [office/api/video.py](file://office/api/video.py) +- [office/api/finance.py](file://office/api/finance.py) +- [office/__init__.py](file://office/__init__.py) + + +## 目录 +1. [简介](#简介) +2. [模块概述](#模块概述) +3. [PDF 模块 API](#pdf-模块-api) +4. [Excel 模块 API](#excel-模块-api) +5. [Image 模块 API](#image-模块-api) +6. [Tools 模块 API](#tools-模块-api) +7. [File 模块 API](#file-模块-api) +8. [WeChat 模块 API](#wechat-模块-api) +9. [Word 模块 API](#word-模块-api) +10. [Video 模块 API](#video-模块-api) +11. [Finance 模块 API](#finance-模块-api) +12. [参数兼容与异常处理](#参数兼容与异常处理) + +## 简介 + +python-office 库提供 13 个功能模块、73 个公共方法,覆盖办公自动化的各个方面。本 API 参考文档详细说明了所有公共接口的使用方法。 + +## 模块概述 + +所有模块通过 `office.__init__.py` 自动导入,用户只需 `import office` 即可使用全部功能。 + +```mermaid +classDiagram +class office { + +pdf: module + +excel: module + +image: module + +tools: module + +file: module + +wechat: module + +word: module + +video: module + +finance: module + +ocr: module + +markdown: module + +email: module + +web: module +} +``` + +**节来源** +- [office/__init__.py](file://office/__init__.py#L1-L30) + +## PDF 模块 API + +### pdf2docx +将 PDF 转换为 Word 文档。 + +```python +def pdf2docx(input_file=None, output_file=None, input_path=None, output_path=None, file_path=None) +``` + +**参数说明** +- `input_file`: 输入 PDF 文件路径,字符串,可选 +- `output_file`: 输出 Word 文件路径,需包含 .docx 后缀,字符串,可选 +- `input_path`: 批量输入目录路径,字符串,可选 +- `output_path`: 批量输出目录路径,字符串,可选 +- `file_path`: [已弃用] 请使用 `input_file` 代替 + +**调用示例** +```python +office.pdf.pdf2docx(input_file='report.pdf', output_file='report.docx') +``` + +**节来源** +- [office/api/pdf.py](file://office/api/pdf.py#L48-L87) + +### pdf2imgs +将 PDF 转换为图片。 + +```python +def pdf2imgs(input_file=None, output_file=None, merge=False, pdf_path=None, out_dir=None) +``` + +**参数说明** +- `input_file`: 输入 PDF 文件路径,字符串,可选 +- `output_file`: 输出图片路径,字符串,可选 +- `merge`: 是否合并为一张图片,布尔,默认 False +- `pdf_path`: [已弃用] 请使用 `input_file` 代替 +- `out_dir`: [已弃用] 请使用 `output_file` 代替 + +**节来源** +- [office/api/pdf.py](file://office/api/pdf.py#L90-L125) + +### encrypt4pdf +加密 PDF 文件。 + +```python +def encrypt4pdf(password, input_file=None, output_file=None, input_path=None, output_path=None) +``` + +**参数说明** +- `password`: 加密密码,字符串,必填 +- `input_file`: 单个输入 PDF 路径,字符串,可选 +- `output_file`: 单个输出路径,字符串,可选 +- `input_path`: 批量输入目录,字符串,可选 +- `output_path`: 批量输出目录,字符串,可选 + +**节来源** +- [office/api/pdf.py](file://office/api/pdf.py#L171-L194) + +### decrypt4pdf +解密 PDF 文件。 + +```python +def decrypt4pdf(password, input_file=None, output_file=None, input_path=None, output_path=None) +``` + +**节来源** +- [office/api/pdf.py](file://office/api/pdf.py#L197-L215) + +### merge2pdf +合并多个 PDF 文件。 + +```python +def merge2pdf(input_file_list=None, output_file=None, one_by_one=None, output=None) +``` + +**参数说明** +- `input_file_list`: PDF 文件路径列表,列表,可选 +- `output_file`: 输出合并后 PDF 路径,字符串,可选 +- `one_by_one`: [已弃用] 请使用 `input_file_list` 代替 +- `output`: [已弃用] 请使用 `output_file` 代替 + +**节来源** +- [office/api/pdf.py](file://office/api/pdf.py#L245-L279) + +## Excel 模块 API + +### fake2excel +自动创建 Excel 并模拟数据。 + +```python +def fake2excel(columns=['name'], rows=1, path='./fake2excel.xlsx', language='zh_CN') +``` + +**节来源** +- [office/api/excel.py](file://office/api/excel.py#L39-L55) + +### merge2excel +合并多个 Excel 到不同 sheet。 + +```python +def merge2excel(dir_path, output_file='merge2excel.xlsx') +``` + +**节来源** +- [office/api/excel.py](file://office/api/excel.py#L58-L73) + +### excel2pdf +Excel 转 PDF。 + +```python +def excel2pdf(excel_path, pdf_path, sheet_id: int = 0) +``` + +**节来源** +- [office/api/excel.py](file://office/api/excel.py#L147-L162) + +## Image 模块 API + +### compress_image +压缩图片。 + +```python +def compress_image(input_file: str, output_file: str, quality: int) +``` + +**节来源** +- [office/api/image.py](file://office/api/image.py#L21-L35) + +### add_watermark +给图片加水印。 + +```python +def add_watermark(file, mark, output_path='./', color="#eaeaea", size=30, opacity=0.35, space=200, angle=30) +``` + +**节来源** +- [office/api/image.py](file://office/api/image.py#L58-L78) + +### txt2wordcloud +生成词云。 + +```python +def txt2wordcloud(filename, color="white", result_file="your_wordcloud.png") +``` + +**节来源** +- [office/api/image.py](file://office/api/image.py#L131-L145) + +## Tools 模块 API + +### transtools +翻译工具。 + +```python +def transtools(to_lang: str, content: str, from_lang: str = 'zh') -> str +``` + +**返回值** +- `str`: 翻译后的结果 + +**节来源** +- [office/api/tools.py](file://office/api/tools.py#L24-L37) + +### qrcodetools +生成二维码。 + +```python +def qrcodetools(url: str, output: str = r'./qrcode_img.png') +``` + +**节来源** +- [office/api/tools.py](file://office/api/tools.py#L40-L52) + +### passwordtools +生成密码。 + +```python +def passwordtools(len=8) -> str +``` + +**节来源** +- [office/api/tools.py](file://office/api/tools.py#L55-L66) + +## File 模块 API + +### replace4filename +批量重命名文件/文件夹。 + +```python +def replace4filename(path: str, del_content, replace_content='', dir_rename: bool = True, file_rename: bool = True, suffix=None) +``` + +**节来源** +- [office/api/file.py](file://office/api/file.py#L44-L61) + +### get_files +搜索指定类型文件并返回列表。 + +```python +def get_files(path: str, name: str = '', suffix: str = None, sub: bool = False, level: int = 0) -> list +``` + +**返回值** +- `list`: 文件路径列表 + +**节来源** +- [office/api/file.py](file://office/api/file.py#L182-L197) + +## WeChat 模块 API + +### send_message +发送消息给指定联系人。 + +```python +def send_message(who: str, message: str) +``` + +**异常情况** +- 非 Windows 环境或未安装 PyOfficeRobot 时抛出 ModuleNotFoundError + +**节来源** +- [office/api/wechat.py](file://office/api/wechat.py#L32-L45) + +### chat_robot +智能聊天。 + +```python +def chat_robot(who='程序员晚枫') +``` + +**节来源** +- [office/api/wechat.py](file://office/api/wechat.py#L132-L144) + +## Word 模块 API + +### docx2pdf +Word 转 PDF(仅 Windows)。 + +```python +def docx2pdf(path: str, output_path: str = None) +``` + +**节来源** +- [office/api/word.py](file://office/api/word.py#L33-L48) + +### merge4docx +合并多个 Docx 文件。 + +```python +def merge4docx(input_path: str, output_path: str, new_word_name: str = 'merge4docx') +``` + +**节来源** +- [office/api/word.py](file://office/api/word.py#L50-L64) + +## Video 模块 API + +### video2mp3 +视频转 MP3。 + +```python +def video2mp3(path, mp3_name=None, output_path=r'./') +``` + +**节来源** +- [office/api/video.py](file://office/api/video.py#L24-L37) + +### txt2mp3 +文本转语音。 + +```python +def txt2mp3(content='程序员晚枫', file=None, mp3=r'./程序员晚枫.mp3', speak=True) +``` + +**节来源** +- [office/api/video.py](file://office/api/video.py#L83-L97) + +## Finance 模块 API + +### t0 +计算 T+0 交易收益。 + +```python +def t0(buy_price: float, sale_price: float, shares: int, w_rate: float = 2.5/10000, min_rate: int = 5, stamp_tax=1/1000) -> float +``` + +**参数说明** +- `buy_price`: 买入价格 +- `sale_price`: 卖出价格 +- `shares`: 单笔数量 +- `w_rate`: 佣金费率(默认万0.25) +- `min_rate`: 单笔最低佣金(默认5元) +- `stamp_tax`: 印花税率(默认千分之一) + +**返回值** +- `float`: 做T后的收益金额 + +**节来源** +- [office/api/finance.py](file://office/api/finance.py#L21-L46) + +## 参数兼容与异常处理 + +### 参数兼容策略 +python-office 的 API 设计支持新旧参数名共存,旧参数触发 `DeprecationWarning`: + +```python +# 旧写法(会触发警告) +office.pdf.pdf2docx(file_path='report.pdf', output_path='./') + +# 新写法(推荐) +office.pdf.pdf2docx(input_file='report.pdf', output_file='report.docx') +``` + +### Windows 专用模块延迟加载 +wechat 和 word 模块采用延迟加载策略,在调用时才检查依赖: + +```mermaid +flowchart TD +A["调用 office.wechat.send_message()"] --> B{"PyOfficeRobot 可导入?"} +B -->|是| C["正常执行"] +B -->|否| D["抛出 ModuleNotFoundError"] +D --> E["提示:需要 Windows + PyOfficeRobot"] +``` + +**节来源** +- [office/api/wechat.py](file://office/api/wechat.py#L19-L29) +- [office/api/word.py](file://office/api/word.py#L20-L30) diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/Excel API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/Excel API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/Excel API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/Excel API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/Markdown\345\244\204\347\220\206API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/Markdown\345\244\204\347\220\206API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/Markdown\345\244\204\347\220\206API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/Markdown\345\244\204\347\220\206API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/OCR\350\257\206\345\210\253API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/OCR\350\257\206\345\210\253API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/OCR\350\257\206\345\210\253API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/OCR\350\257\206\345\210\253API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/PDF\345\244\204\347\220\206API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/PDF\345\244\204\347\220\206API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/PDF\345\244\204\347\220\206API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/PDF\345\244\204\347\220\206API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/PPT\345\244\204\347\220\206API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/PPT\345\244\204\347\220\206API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/PPT\345\244\204\347\220\206API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/PPT\345\244\204\347\220\206API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/Word\345\244\204\347\220\206API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/Word\345\244\204\347\220\206API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/Word\345\244\204\347\220\206API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/Word\345\244\204\347\220\206API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\345\233\276\345\203\217\345\244\204\347\220\206API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\345\233\276\345\203\217\345\244\204\347\220\206API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\345\233\276\345\203\217\345\244\204\347\220\206API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\345\233\276\345\203\217\345\244\204\347\220\206API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\345\267\245\345\205\267\347\261\273API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\345\267\245\345\205\267\347\261\273API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\345\267\245\345\205\267\347\261\273API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\345\267\245\345\205\267\347\261\273API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\346\226\207\344\273\266\347\256\241\347\220\206API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\346\226\207\344\273\266\347\256\241\347\220\206API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\346\226\207\344\273\266\347\256\241\347\220\206API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\346\226\207\344\273\266\347\256\241\347\220\206API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\346\265\213\350\257\225API (\350\257\225\351\252\214\346\200\247).md" "b/wiki/zh/content/API\345\217\202\350\200\203/\346\265\213\350\257\225API (\350\257\225\351\252\214\346\200\247).md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\346\265\213\350\257\225API (\350\257\225\351\252\214\346\200\247).md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\346\265\213\350\257\225API (\350\257\225\351\252\214\346\200\247).md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\347\275\221\351\241\265\344\272\244\344\272\222API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\347\275\221\351\241\265\344\272\244\344\272\222API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\347\275\221\351\241\265\344\272\244\344\272\222API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\347\275\221\351\241\265\344\272\244\344\272\222API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\350\247\206\351\242\221\345\244\204\347\220\206API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\350\247\206\351\242\221\345\244\204\347\220\206API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\350\247\206\351\242\221\345\244\204\347\220\206API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\350\247\206\351\242\221\345\244\204\347\220\206API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\351\202\256\344\273\266API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\351\202\256\344\273\266API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\351\202\256\344\273\266API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\351\202\256\344\273\266API.md" diff --git "a/.qoder/repowiki/zh/content/API\345\217\202\350\200\203/\351\207\221\350\236\215\345\267\245\345\205\267API.md" "b/wiki/zh/content/API\345\217\202\350\200\203/\351\207\221\350\236\215\345\267\245\345\205\267API.md" similarity index 100% rename from ".qoder/repowiki/zh/content/API\345\217\202\350\200\203/\351\207\221\350\236\215\345\267\245\345\205\267API.md" rename to "wiki/zh/content/API\345\217\202\350\200\203/\351\207\221\350\236\215\345\267\245\345\205\267API.md" diff --git "a/wiki/zh/content/Skills\347\263\273\347\273\237.md" "b/wiki/zh/content/Skills\347\263\273\347\273\237.md" new file mode 100644 index 00000000..f2a3f972 --- /dev/null +++ "b/wiki/zh/content/Skills\347\263\273\347\273\237.md" @@ -0,0 +1,152 @@ +# Skills 系统 + + +**本文档中引用的文件** +- [skills/README.md](file://skills/README.md) +- [skills/__init__.py](file://skills/__init__.py) +- [README.md](file://README.md) + + +## 目录 +1. [简介](#简介) +2. [Skills 架构](#skills-架构) +3. [13 个分类概览](#13-个分类概览) +4. [三种使用方式](#三种使用方式) +5. [SKILL.md 文档规范](#skillmd-文档规范) +6. [添加新 Skill](#添加新-skill) +7. [常见问题](#常见问题) + +## 简介 + +python-office 内置 **Skills 系统**:将库的 73 个方法封装为 73 个独立可导入的 Skill。每个 Skill 是一个独立子目录,包含 `__init__.py`(暴露接口)和 `SKILL.md`(文档说明),可被 Codex / Claude / Cursor 等 AI 工具自动识别调用。 + +**Section sources** +- [README.md](file://README.md#L97-L116) + +## Skills 架构 + +```mermaid +graph TB +subgraph "Skills 系统" +ROOT["skills/"] +CAT1["excel/ (7)"] +CAT2["file/ (9)"] +CAT3["image/ (9)"] +CAT4["pdf/ (13)"] +CAT5["ppt/ (3)"] +CAT6["tools/ (10)"] +CAT7["video/ (4)"] +CAT8["wechat/ (7)"] +CAT9["word/ (5)"] +CAT10["ocr/ (1)"] +CAT11["finance/ (1)"] +CAT12["markdown/ (1)"] +CAT13["ruiming/ (3)"] +end +ROOT --> CAT1 +ROOT --> CAT2 +ROOT --> CAT3 +ROOT --> CAT4 +ROOT --> CAT5 +ROOT --> CAT6 +ROOT --> CAT7 +ROOT --> CAT8 +ROOT --> CAT9 +ROOT --> CAT10 +ROOT --> CAT11 +ROOT --> CAT12 +ROOT --> CAT13 +``` + +每个 Skill 的目录结构: + +``` +skills/// +├── SKILL.md # Skill 的详细说明文档 +└── __init__.py # 暴露 Skill 接口,让用户可以单独调用 +``` + +**Section sources** +- [skills/README.md](file://skills/README.md#L241-L254) + +## 13 个分类概览 + +| 分类 | Skill 数量 | 典型 Skill | +|------|-----------|-----------| +| Excel | 7 | `fake2excel` / `merge2excel` / `excel2pdf` | +| File | 9 | `replace4filename` / `get_files` | +| Finance | 1 | `t0`(股票T+0收益计算) | +| Image | 9 | `compress_image` / `add_watermark` / `txt2wordcloud` | +| Markdown | 1 | `excel2markdown` | +| OCR | 1 | `VatInvoiceOCR2Excel`(增值税发票识别) | +| PDF | 13 | `pdf2docx` / `pdf2imgs` / `merge2pdf` / `encrypt4pdf` | +| PPT | 3 | `ppt2pdf` / `ppt2img` / `merge4ppt` | +| Tools | 10 | `transtools` / `qrcodetools` / `passwordtools` | +| Video | 4 | `video2mp3` / `audio2txt` / `txt2mp3` | +| WeChat | 7 | `send_message` / `chat_robot` / `receive_message` | +| Word | 5 | `docx2pdf` / `merge4docx` / `docx4imgs` | +| Ruiming | 3 | `screen_unmarked_image` / `change_label_in_xml` | + +**Section sources** +- [skills/README.md](file://skills/README.md#L117-L134) + +## 三种使用方式 + +```python +# 方式 1:直接导入特定 Skill +from skills.image import compress_image +compress_image(input_file='photo.jpg', output_file='photo_small.jpg', quality=30) + +# 方式 2:按分类导入 +from skills.pdf import pdf2docx +pdf2docx(input_file='report.pdf', output_file='report.docx') + +# 方式 3:传统 office 风格(仍然可用) +import office +office.image.compress_image(input_file='photo.jpg', output_file='photo_small.jpg', quality=30) +``` + +**Section sources** +- [README.md](file://README.md#L103-L115) +- [skills/README.md](file://skills/README.md#L27-L39) + +## SKILL.md 文档规范 + +每个 Skill 的 `SKILL.md` 文件包含以下内容: +- **功能描述**:该 Skill 的用途和适用场景 +- **参数说明**:每个参数的名称、类型、是否必填、默认值 +- **返回值**:函数返回值的类型和含义 +- **使用示例**:可直接运行的代码示例 +- **注意事项**:平台限制、依赖要求等 + +这种标准化的文档格式使 AI 工具能够自动识别用户意图并调用正确的 Skill。 + +**Section sources** +- [skills/README.md](file://skills/README.md#L241-L254) + +## 添加新 Skill + +为项目添加新 Skill 需要遵循以下步骤: + +```mermaid +flowchart TD +A["1. 在 skills// 下创建子目录"] --> B["2. 编写 __init__.py 暴露接口"] +B --> C["3. 编写 SKILL.md 文档"] +C --> D["4. 在 office/api/ 中添加 API 函数"] +D --> E["5. 在 examples/ 中添加使用示例"] +E --> F["6. 更新 skills/README.md 索引"] +F --> G["7. 提交 PR"] +``` + +**Section sources** +- [README.md](file://README.md#L317-L332) + +## 常见问题 + +1. **Skill 导入失败**:确保已安装对应的子库(如 `pip install popdf`) +2. **Windows 专用 Skill 不可用**:wechat、word、ppt 分类下的 Skill 仅在 Windows 上可用 +3. **Skill 与 office API 的关系**:Skill 是 office API 的薄封装,两者功能等价,Skill 额外提供独立导入和 SKILL.md 文档 +4. **AI 工具如何识别 Skill**:AI 工具通过读取 SKILL.md 文件中的触发条件和参数说明来识别和调用 Skill + +**Section sources** +- [skills/README.md](file://skills/README.md#L241-L274) diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/GUI\347\211\210\346\234\254\346\246\202\350\247\210.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/GUI\347\211\210\346\234\254\346\246\202\350\247\210.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/GUI\347\211\210\346\234\254\346\246\202\350\247\210.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/GUI\347\211\210\346\234\254\346\246\202\350\247\210.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version1 \346\246\202\350\277\260.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version1 \346\246\202\350\277\260.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version1 \346\246\202\350\277\260.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version1 \346\246\202\350\277\260.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\236\266\346\236\204\350\256\276\350\256\241.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\236\266\346\236\204\350\256\276\350\256\241.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\236\266\346\236\204\350\256\276\350\256\241.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\236\266\346\236\204\350\256\276\350\256\241.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\246\202\350\277\260.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\246\202\350\277\260.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\246\202\350\277\260.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/Version2 \346\246\202\350\277\260.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\344\270\273\351\242\230\344\270\216\346\240\267\345\274\217\347\263\273\347\273\237.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\344\270\273\351\242\230\344\270\216\346\240\267\345\274\217\347\263\273\347\273\237.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\344\270\273\351\242\230\344\270\216\346\240\267\345\274\217\347\263\273\347\273\237.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\344\270\273\351\242\230\344\270\216\346\240\267\345\274\217\347\263\273\347\273\237.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\345\244\232\350\257\255\350\250\200\346\224\257\346\214\201\346\234\272\345\210\266.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\345\244\232\350\257\255\350\250\200\346\224\257\346\214\201\346\234\272\345\210\266.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\345\244\232\350\257\255\350\250\200\346\224\257\346\214\201\346\234\272\345\210\266.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\345\244\232\350\257\255\350\250\200\346\224\257\346\214\201\346\234\272\345\210\266.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\346\240\270\345\277\203UI\347\273\204\344\273\266\350\257\246\350\247\243.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\346\240\270\345\277\203UI\347\273\204\344\273\266\350\257\246\350\247\243.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\346\240\270\345\277\203UI\347\273\204\344\273\266\350\257\246\350\247\243.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version2 \346\246\202\350\277\260/\346\240\270\345\277\203UI\347\273\204\344\273\266\350\257\246\350\247\243.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version3 \346\246\202\350\277\260.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version3 \346\246\202\350\277\260.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version3 \346\246\202\350\277\260.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/GUI\347\211\210\346\234\254\346\246\202\350\247\210/Version3 \346\246\202\350\277\260.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/OCR\350\257\206\345\210\253\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/OCR\350\257\206\345\210\253\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/OCR\350\257\206\345\210\253\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/OCR\350\257\206\345\210\253\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\233\276\347\211\207\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\233\276\347\211\207\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\233\276\347\211\207\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\233\276\347\211\207\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\350\247\206\351\242\221\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\350\247\206\351\242\221\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\350\247\206\351\242\221\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\350\247\206\351\242\221\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/Markdown\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/Markdown\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/Markdown\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/Markdown\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\345\267\245\345\205\267\351\233\206\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\345\267\245\345\205\267\351\233\206\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\345\267\245\345\205\267\351\233\206\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\345\267\245\345\205\267\351\233\206\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\350\264\242\345\212\241\350\256\241\347\256\227\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\350\264\242\345\212\241\350\256\241\347\256\227\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\350\264\242\345\212\241\350\256\241\347\256\227\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\225\260\346\215\256\345\267\245\345\205\267\345\212\237\350\203\275\351\233\206\346\210\220/\350\264\242\345\212\241\350\256\241\347\256\227\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Excel\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Excel\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Excel\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Excel\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PDF\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PDF\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PDF\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PDF\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PPT\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PPT\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PPT\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/PPT\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Word\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Word\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Word\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/Word\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220/\346\226\207\346\241\243\345\244\204\347\220\206\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\345\276\256\344\277\241\346\234\272\345\231\250\344\272\272\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\202\256\344\273\266\345\217\221\351\200\201\345\212\237\350\203\275\351\233\206\346\210\220.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\202\256\344\273\266\345\217\221\351\200\201\345\212\237\350\203\275\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\202\256\344\273\266\345\217\221\351\200\201\345\212\237\350\203\275\351\233\206\346\210\220.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\212\237\350\203\275\346\230\240\345\260\204\344\270\216\351\233\206\346\210\220/\351\200\232\344\277\241\350\207\252\345\212\250\345\214\226\345\212\237\350\203\275\351\233\206\346\210\220/\351\202\256\344\273\266\345\217\221\351\200\201\345\212\237\350\203\275\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\275\351\231\205\345\214\226\346\224\257\346\214\201.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\275\351\231\205\345\214\226\346\224\257\346\214\201.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\275\351\231\205\345\214\226\346\224\257\346\214\201.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\275\351\231\205\345\214\226\346\224\257\346\214\201.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\344\270\273\347\252\227\345\217\243\346\236\266\346\236\204.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\344\270\273\347\252\227\345\217\243\346\236\266\346\236\204.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\344\270\273\347\252\227\345\217\243\346\236\266\346\236\204.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\344\270\273\347\252\227\345\217\243\346\236\266\346\236\204.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\345\205\254\345\205\261\346\250\241\345\235\227\350\257\246\350\247\243.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\345\205\254\345\205\261\346\250\241\345\235\227\350\257\246\350\247\243.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\345\205\254\345\205\261\346\250\241\345\235\227\350\257\246\350\247\243.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\345\205\254\345\205\261\346\250\241\345\235\227\350\257\246\350\247\243.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\350\207\252\345\256\232\344\271\211UI\347\273\204\344\273\266.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\350\207\252\345\256\232\344\271\211UI\347\273\204\344\273\266.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\350\207\252\345\256\232\344\271\211UI\347\273\204\344\273\266.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\346\240\270\345\277\203\347\273\204\344\273\266\346\236\266\346\236\204/\350\207\252\345\256\232\344\271\211UI\347\273\204\344\273\266.md" diff --git "a/.qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\350\277\220\350\241\214\346\214\207\345\215\227\344\270\216\344\276\235\350\265\226\347\256\241\347\220\206.md" "b/wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\350\277\220\350\241\214\346\214\207\345\215\227\344\270\216\344\276\235\350\265\226\347\256\241\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\350\277\220\350\241\214\346\214\207\345\215\227\344\270\216\344\276\235\350\265\226\347\256\241\347\220\206.md" rename to "wiki/zh/content/\345\233\276\345\275\242\347\224\250\346\210\267\347\225\214\351\235\242/\350\277\220\350\241\214\346\214\207\345\215\227\344\270\216\344\276\235\350\265\226\347\256\241\347\220\206.md" diff --git "a/wiki/zh/content/\345\256\211\350\243\205\346\214\207\345\215\227.md" "b/wiki/zh/content/\345\256\211\350\243\205\346\214\207\345\215\227.md" new file mode 100644 index 00000000..84eac764 --- /dev/null +++ "b/wiki/zh/content/\345\256\211\350\243\205\346\214\207\345\215\227.md" @@ -0,0 +1,291 @@ +# 安装指南 + + +**本文引用的文件** +- [README.md](file://README.md) +- [setup.cfg](file://setup.cfg) +- [setup.py](file://setup.py) +- [office/__init__.py](file://office/__init__.py) +- [office/compatibility.py](file://office/compatibility.py) + + +## 目录 +1. [简介](#简介) +2. [项目结构](#项目结构) +3. [核心组件](#核心组件) +4. [架构总览](#架构总览) +5. [详细组件分析](#详细组件分析) +6. [依赖分析](#依赖分析) +7. [性能考虑](#性能考虑) +8. [故障排查指南](#故障排查指南) +9. [结论](#结论) +10. [附录](#附录) + +## 简介 + +本指南面向希望安装与使用 python-office 的用户,系统讲解三种安装方式: +- 使用 pip 从阿里云镜像安装完整库 +- 按需安装子库(轻量化方案) +- 从源码本地开发安装 + +同时覆盖安装过程中的常见问题排查(依赖冲突、权限问题、跨平台兼容性),以及如何验证安装成功与环境配置建议。 + +**章节来源** +- file://README.md#L139-L155 + +## 项目结构 + +python-office 作为 Python 包,其安装配置主要由以下文件定义: +- 构建与元数据:setup.cfg、setup.py +- 包入口:office/__init__.py +- 兼容性检查:office/compatibility.py +- Skills 索引:skills/README.md + +```mermaid +graph TB +A["根目录"] --> B["构建配置
setup.cfg / setup.py"] +A --> C["包入口
office/__init__.py"] +A --> D["兼容性检查
office/compatibility.py"] +A --> E["Skills 系统
skills/"] +A --> F["示例代码
examples/"] +A --> G["GUI 应用
gui/"] +A --> H["项目说明
README.md"] +``` + +**章节来源** +- file://setup.cfg#L1-L44 +- file://office/__init__.py#L1-L30 + +## 核心组件 + +- 包元数据与依赖 + - 版本与描述:见 [setup.cfg](file://setup.cfg#L1-L44) + - Python 版本要求:>=3.6(见 [setup.cfg](file://setup.cfg#L42)) + - 安装依赖列表:见 [setup.cfg](file://setup.cfg#L21-L41) +- 包导出 + - 包入口导出:见 [office/__init__.py](file://office/__init__.py#L1-L30) + - 13 个 API 模块自动导入 +- 兼容性检查 + - 首次运行自动检测平台并提示:见 [office/compatibility.py](file://office/compatibility.py#L1-L250) + +**章节来源** +- file://setup.cfg#L1-L44 +- file://office/__init__.py#L1-L30 +- file://office/compatibility.py#L1-L250 + +## 架构总览 + +下图展示 python-office 的安装与运行架构:从 pip 安装到包入口导入,再到兼容性检查和功能调用。 + +```mermaid +graph TB +subgraph "安装层" +PIP["pip 安装
阿里云镜像 / PyPI / 本地源码"] +SUB["子库按需安装
popdf / poimage / poexcel ..."] +end +subgraph "包层" +META["元数据/依赖
setup.cfg"] +PKG["python-office 包
office/__init__.py"] +COMPAT["兼容性检查
office/compatibility.py"] +end +subgraph "功能层" +API["13 个 API 模块
office/api/*"] +SKILLS["73 个 Skills
skills/*"] +end +PIP --> META --> PKG --> COMPAT --> API +SUB --> PKG +API --> SKILLS +``` + +**章节来源** +- file://setup.cfg#L1-L44 +- file://office/__init__.py#L1-L30 + +## 详细组件分析 + +### 方式一:使用 pip 安装完整库(推荐) + +- 适用场景 + - 需要使用多个功能模块的用户 + - 快速获得完整功能,无需逐个安装子库 +- 操作步骤 + +```bash +# 使用阿里云镜像加速安装 +pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U + +# 或从 PyPI 官方源安装 +pip install python-office -U +``` + +- 优点 + - 一次安装,所有功能可用 + - `import office` 即可使用全部 73 个 Skill +- 缺点 + - 安装依赖较多,首次安装时间较长 + - 包含 Windows 专用子库,非 Windows 环境会跳过 +- 验证安装 + +```python +import office +print(office.__version__) # 应输出 1.0.6 +``` + +**章节来源** +- file://README.md#L139-L155 + +### 方式二:按需安装子库(轻量化) + +- 适用场景 + - 只需要特定功能(如仅 PDF 处理) + - 减少依赖体积和安装时间 +- 操作步骤 + +```bash +pip install popdf # PDF 处理 +pip install poimage # 图片处理 +pip install poword # Word 处理(仅 Windows) +pip install poexcel # Excel 处理 +pip install pofile # 文件管理 +pip install povideo # 视频处理 +pip install poocr # OCR 识别 +pip install wftools # 工具类 +``` + +- 优点 + - 按需安装,依赖精简 + - 各子库可独立使用,也可通过 python-office 统一调用 +- 缺点 + - 需要了解各子库的对应关系 + - 多个子库分别安装时管理复杂度增加 + +**章节来源** +- file://README.md#L139-L155 + +### 方式三:从源码安装(本地开发) + +- 适用场景 + - 需要调试或二次开发 + - 需要使用未发布的特性或修复 +- 操作步骤 + +```bash +git clone https://github.com/CoderWanFeng/python-office.git +cd python-office +pip install -e . +``` + +- 优点 + - 可直接修改源码并即时生效 +- 缺点 + - 需要本地 Python 环境与构建工具 + - 依赖管理复杂度增加 + +**章节来源** +- file://README.md#L317-L332 + +### 兼容性检查机制 + +安装后首次 `import office` 时,兼容性检查器会自动运行: + +```mermaid +sequenceDiagram +participant U as "用户" +participant P as "pip" +participant I as "office/__init__.py" +participant C as "compatibility.py" +participant A as "office/api/*" +U->>P : "pip install python-office" +P->>I : "读取元数据/依赖" +P-->>U : "完成安装" +U->>I : "import office" +I->>C : "check_compatibility()" +C->>C : "检测平台与首次运行" +alt 非Windows + 首次运行 +C-->>U : "显示兼容性提示表格" +end +I->>A : "导入13个API模块" +A-->>U : "所有功能可用" +``` + +**章节来源** +- file://office/compatibility.py#L1-L250 +- file://office/__init__.py#L1-L30 + +## 依赖分析 + +- 运行时核心依赖(跨平台) + +| 依赖 | 用途 | +|------|------| +| popdf | PDF 处理 | +| poexcel | Excel 处理 | +| poimage | 图片处理 | +| pofile | 文件管理 | +| povideo | 视频处理 | +| poocr | OCR 识别 | +| wftools | 工具类(翻译、二维码等) | +| poemail | 邮件发送 | +| pomarkdown | Markdown 处理 | +| pocode | 代码管理 | +| pospider | 网络爬虫 | +| poprogress | 进度条 | +| rich | 彩色终端输出 | +| loguru | 日志记录 | +| you-get | 视频下载 | + +- Windows 专用依赖 + +| 依赖 | 用途 | +|------|------| +| poppt | PPT 处理(需要 Microsoft PowerPoint) | +| poword | Word 处理(需要 Microsoft Word) | +| PyOfficeRobot | 微信机器人(需要桌面微信客户端) | +| search4file | 文件搜索(使用 Windows 特定 API) | + +**章节来源** +- file://setup.cfg#L21-L41 + +## 性能考虑 + +- 选择合适的安装方式 + - 需要多功能的用户推荐完整安装 + - 只需单一功能的用户推荐子库安装 +- 环境隔离 + - 使用虚拟环境(venv / conda)减少依赖冲突 +- 跨平台注意 + - Windows 专用功能在 macOS/Linux 上不可用,但不会导致导入失败 + - 首次运行时兼容性检查器会提示替代方案 + +## 故障排查指南 + +- 依赖冲突 + - 现象:安装失败或运行时报错 + - 排查:检查依赖版本范围与现有环境,必要时使用虚拟环境隔离 + - 参考:[setup.cfg](file://setup.cfg#L21-L41) +- 权限问题 + - 现象:安装失败提示权限不足 + - 排查:使用用户级安装或以管理员身份运行 +- 跨平台兼容性 + - 现象:poword / poppt / PyOfficeRobot 在非 Windows 上不可用 + - 排查:查看首次运行的兼容性提示,使用 LibreOffice 等替代方案 +- 导入失败 + - 现象:`ModuleNotFoundError` + - 排查:确认对应子库已安装,或使用完整安装 `pip install python-office` + +**章节来源** +- file://office/compatibility.py#L40-L72 +- file://setup.cfg#L21-L41 + +## 结论 +- 对大多数用户,推荐使用 pip 从阿里云镜像完整安装,快速获得全部功能 +- 只需特定功能的用户可按需安装子库,减少依赖体积 +- 需要开发或调试时,采用本地源码可编辑安装 +- 安装完成后,通过 `import office` 验证安装成功,首次运行会自动显示跨平台兼容性提示 + +## 附录 +- 安装命令参考 + - 完整安装:参见 [README.md](file://README.md#L139-L155) + - 子库安装:参见 [README.md](file://README.md#L146-L150) +- 依赖清单:参见 [setup.cfg](file://setup.cfg#L21-L41) +- 兼容性信息:参见 [office/compatibility.py](file://office/compatibility.py#L40-L72) diff --git "a/.qoder/repowiki/zh/content/\345\270\270\350\247\201\351\227\256\351\242\230\344\270\216\346\225\205\351\232\234\346\216\222\351\231\244.md" "b/wiki/zh/content/\345\270\270\350\247\201\351\227\256\351\242\230\344\270\216\346\225\205\351\232\234\346\216\222\351\231\244.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\270\270\350\247\201\351\227\256\351\242\230\344\270\216\346\225\205\351\232\234\346\216\222\351\231\244.md" rename to "wiki/zh/content/\345\270\270\350\247\201\351\227\256\351\242\230\344\270\216\346\225\205\351\232\234\346\216\222\351\231\244.md" diff --git "a/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\344\273\243\347\240\201\347\273\223\346\236\204\350\257\264\346\230\216.md" "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\344\273\243\347\240\201\347\273\223\346\236\204\350\257\264\346\230\216.md" new file mode 100644 index 00000000..b1b6a740 --- /dev/null +++ "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\344\273\243\347\240\201\347\273\223\346\236\204\350\257\264\346\230\216.md" @@ -0,0 +1,326 @@ +# 代码结构说明 + + +**本文引用的文件** +- [README.md](file://README.md) +- [setup.cfg](file://setup.cfg) +- [setup.py](file://setup.py) +- [office/__init__.py](file://office/__init__.py) +- [office/compatibility.py](file://office/compatibility.py) +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/image.py](file://office/api/image.py) +- [office/api/tools.py](file://office/api/tools.py) +- [office/api/file.py](file://office/api/file.py) +- [office/api/wechat.py](file://office/api/wechat.py) +- [office/api/word.py](file://office/api/word.py) +- [office/api/video.py](file://office/api/video.py) +- [office/api/finance.py](file://office/api/finance.py) +- [skills/README.md](file://skills/README.md) + + +## 目录 +1. [简介](#简介) +2. [项目结构](#项目结构) +3. [核心组件](#核心组件) +4. [架构总览](#架构总览) +5. [详细组件分析](#详细组件分析) +6. [依赖关系分析](#依赖关系分析) +7. [性能考量](#性能考量) +8. [故障排查指南](#故障排查指南) +9. [结论](#结论) + +## 简介 +本文件面向开发者,系统性梳理 python-office 项目的分层架构设计与模块职责。与 popdf 等单一功能子库不同,python-office 采用"API 聚合层 + Skills 系统层 + 子库生态"三层架构: +- **API 聚合层**(`office/api/`):对外提供统一门面接口,13 个模块按功能领域划分,负责参数兼容处理与子库路由分发。 +- **Skills 系统层**(`skills/`):73 个独立可导入的 Skill,每个包含 `__init__.py` 和 `SKILL.md`,支持 AI 工具自动识别。 +- **子库生态**(popdf/poexcel/poimage 等):各子库独立维护,封装第三方库调用,提供稳定的功能接口。 + +同时,`office/compatibility.py` 提供跨平台兼容性检查,在非 Windows 系统首次运行时提示 Windows 专用模块的替代方案。 + +章节来源 +- [README.md](file://README.md#L1-L50) +- [office/__init__.py](file://office/__init__.py#L1-L29) + +## 项目结构 +项目采用"聚合层 + 子库 + Skills + 贡献者"的组织方式,配合 examples 与 tests 提供使用示例与测试覆盖。 + +```mermaid +graph TB +subgraph "API聚合层" +A1["office/api/pdf.py"] +A2["office/api/excel.py"] +A3["office/api/image.py"] +A4["office/api/tools.py"] +A5["office/api/file.py"] +A6["office/api/wechat.py"] +A7["office/api/word.py"] +A8["office/api/video.py"] +A9["office/api/finance.py"] +A10["office/api/ocr.py"] +A11["office/api/markdown.py"] +A12["office/api/ppt.py"] +A13["office/api/email.py"] +end +subgraph "兼容性检查" +C0["office/compatibility.py"] +end +subgraph "Skills系统" +S1["skills/ (73个Skill)"] +end +subgraph "子库生态" +L1["popdf"] +L2["poexcel"] +L3["poimage"] +L4["pofile"] +L5["povideo"] +L6["poocr"] +L7["wftools"] +L8["poemail"] +L9["pomarkdown"] +L10["pocode"] +L11["pospider"] +L12["poprogress"] +end +subgraph "Windows专用" +W1["poppt"] +W2["poword"] +W3["PyOfficeRobot"] +W4["search4file"] +end +subgraph "测试" +T1["tests/test_code/"] +T2["tests/test_main.py"] +end +subgraph "示例" +E1["examples/"] +end +subgraph "贡献者" +CON["contributors/"] +end +A1 --> L1 +A2 --> L2 +A3 --> L3 +A4 --> L7 +A5 --> L4 +A6 --> W3 +A7 --> W2 +A8 --> L5 +A9 --> A9 +A10 --> L6 +A12 --> W1 +``` + +图表来源 +- [office/__init__.py](file://office/__init__.py#L1-L29) +- [setup.cfg](file://setup.cfg#L19-L41) +- [skills/README.md](file://skills/README.md#L1-L50) + +## 核心组件 +- **office/\_\_init\_\_.py**:包入口,首先导入兼容性检查模块并执行检查,然后导入 13 个 API 模块。当前版本 `1.0.6`。 +- **office/compatibility.py**:跨平台兼容性检查器 `CrossPlatformCompatibility`,检测操作系统类型,首次运行时在 `~/.python-office/first_run_mark` 创建标记文件,非 Windows 系统显示功能兼容性表格与替代方案。 +- **office/api/\***:13 个 API 模块,每个模块导入对应子库并封装为函数式接口。pdf.py 最大(434 行,13 个函数),finance.py 最小(51 行,1 个函数)。 +- **skills/**:73 个 Skill 的索引与规范文档,每个 Skill 包含 `__init__.py`(可直接导入使用)和 `SKILL.md`(AI 工具可读的文档)。 +- **contributors/**:12 个贡献者的独立代码目录,采用隔离式贡献模式,不修改核心代码。 + +章节来源 +- [office/__init__.py](file://office/__init__.py#L1-L29) +- [office/compatibility.py](file://office/compatibility.py#L14-L50) +- [office/api/pdf.py](file://office/api/pdf.py#L1-L30) +- [skills/README.md](file://skills/README.md#L1-L30) + +## 架构总览 +下图展示了三层之间的依赖关系与典型调用链路,体现"API 调用子库,子库调用第三方库"的分层设计。 + +```mermaid +graph TB +USER["用户代码"] --> API["office/api/*
API聚合层(13个模块)"] +API --> COMPAT["office/compatibility.py
跨平台兼容性检查"] +API --> SUB1["popdf
PDF处理"] +API --> SUB2["poexcel
Excel处理"] +API --> SUB3["poimage
图片处理"] +API --> SUB4["pofile
文件管理"] +API --> SUB5["povideo
视频处理"] +API --> SUB6["poocr
OCR识别"] +API --> SUB7["wftools
工具类"] +API --> SUB8["poemail
邮件发送"] +API --> SUB9["pomarkdown
Markdown处理"] +API --> SUBW1["poword
Word处理(Windows)"] +API --> SUBW2["poppt
PPT处理(Windows)"] +API --> SUBW3["PyOfficeRobot
微信机器人(Windows)"] +SUB1 --> THIRD1["PyMuPDF / PyPDF2 / pdf2docx"] +SUB2 --> THIRD2["openpyxl / pandas / faker"] +SUB3 --> THIRD3["Pillow / opencv"] +SUB6 --> THIRD6["paddleocr"] +``` + +图表来源 +- [office/__init__.py](file://office/__init__.py#L1-L29) +- [setup.cfg](file://setup.cfg#L19-L41) +- [office/api/pdf.py](file://office/api/pdf.py#L1-L30) +- [office/api/excel.py](file://office/api/excel.py#L1-L20) + +## 详细组件分析 + +### 入口层:包初始化与兼容性检查 +- **职责** + - `office/__init__.py` 首先导入 `check_compatibility`,确保在所有 API 模块导入之前完成跨平台检测。 + - 然后按序导入 13 个 API 模块,使 `import office` 后可直接使用 `office.pdf.pdf2docx()` 等调用。 + - `office/compatibility.py` 中的 `CrossPlatformCompatibility` 类在首次运行时创建标记文件 `~/.python-office/first_run_mark`,非 Windows 系统通过 rich 库展示彩色兼容性表格。 +- **关键点** + - 兼容性检查在导入时自动执行,仅首次运行显示提示。 + - Windows 专用模块(poppt、poword、PyOfficeRobot、search4file)在 `setup.cfg` 中通过 `platform_system=='Windows'` 条件安装。 + - `__version__ = '1.0.6'`,对应 `setup.cfg` 中的版本号。 +- **示例路径** + - [包入口与模块导入](file://office/__init__.py#L1-L29) + - [兼容性检查器](file://office/compatibility.py#L14-L73) + +章节来源 +- [office/__init__.py](file://office/__init__.py#L1-L29) +- [office/compatibility.py](file://office/compatibility.py#L14-L73) + +### API 层:统一门面接口 +- **职责** + - 每个 API 模块导入对应子库,将子库功能封装为函数式接口。 + - pdf.py 是最复杂的模块(434 行),支持新旧参数兼容:旧参数名触发 `DeprecationWarning`,同时映射到新参数。 + - wechat.py 和 word.py 采用延迟加载策略:在函数调用时才 `import PyOfficeRobot` / `import poword`,避免非 Windows 系统导入失败。 +- **关键点** + - 参数兼容机制:pdf.py 中的 `pdf2docx` 支持 `file_path`(旧)和 `input_file`(新)两种参数名,旧参数触发 `warnings.warn("参数名已弃用", DeprecationWarning)`。 + - 延迟加载:wechat.py 的 `send_message` 函数在函数体内 `from PyOfficeRobot.XXBot import send_message as bot_send`,而非模块顶部导入。 + - 日志记录:使用 `loguru` 进行统一日志记录。 +- **示例路径** + - [PDF API 参数兼容](file://office/api/pdf.py#L1-L50) + - [微信延迟加载](file://office/api/wechat.py#L1-L40) + - [Excel API](file://office/api/excel.py#L1-L30) + +章节来源 +- [office/api/pdf.py](file://office/api/pdf.py#L1-L50) +- [office/api/wechat.py](file://office/api/wechat.py#L1-L40) +- [office/api/excel.py](file://office/api/excel.py#L1-L30) +- [office/api/image.py](file://office/api/image.py#L1-L30) +- [office/api/tools.py](file://office/api/tools.py#L1-L30) +- [office/api/file.py](file://office/api/file.py#L1-L30) +- [office/api/word.py](file://office/api/word.py#L1-L30) +- [office/api/video.py](file://office/api/video.py#L1-L30) +- [office/api/finance.py](file://office/api/finance.py#L1-L51) + +### Skills 系统层 +- **职责** + - 73 个 Skill 按 13 个分类组织,每个 Skill 是一个独立目录,包含 `__init__.py`(功能实现)和 `SKILL.md`(AI 可读文档)。 + - 支持三种使用方式:`from skills.分类.Skill名 import 函数名`、`import skills.分类.Skill名`、AI 工具自动识别 SKILL.md。 + - Skills 系统与 API 聚合层互补:API 面向传统 Python 开发者,Skills 面向 AI 工具用户。 +- **关键点** + - SKILL.md 遵循统一格式:名称、功能描述、参数说明、返回值、使用示例。 + - 新增 Skill 需在 `skills/` 对应分类目录下创建子目录,包含 `__init__.py` 和 `SKILL.md`。 + - 13 个分类:PDF、Excel、Word、PPT、图片、视频、文件管理、工具类、微信自动化、OCR识别、金融计算、Markdown处理、邮件。 +- **示例路径** + - [Skills 索引](file://skills/README.md#L1-L50) + +章节来源 +- [skills/README.md](file://skills/README.md#L1-L50) + +### 数据流与控制流(以典型流程为例) + +#### 流程一:PDF 转 Word(参数兼容) +```mermaid +sequenceDiagram +participant U as "调用方" +participant API as "office/api/pdf.py" +participant SUB as "popdf" +participant THIRD as "pdf2docx" +U->>API : 调用 pdf2docx(file_path='input.pdf') +API->>API : 检测旧参数file_path,触发DeprecationWarning +API->>API : 映射到input_file='input.pdf' +API->>SUB : popdf.pdf2docx(input_file, output_file) +SUB->>THIRD : Converter.convert() +THIRD-->>SUB : 转换完成 +SUB-->>API : 返回 +API-->>U : 返回 +``` + +图表来源 +- [office/api/pdf.py](file://office/api/pdf.py#L1-L50) + +#### 流程二:微信发消息(延迟加载) +```mermaid +sequenceDiagram +participant U as "调用方" +participant API as "office/api/wechat.py" +participant SUB as "PyOfficeRobot" +participant WX as "微信客户端" +U->>API : 调用 send_message(who, message) +API->>API : 函数体内导入PyOfficeRobot +API->>SUB : from PyOfficeRobot.XXBot import send_message +SUB->>WX : 调用微信客户端API +WX-->>SUB : 发送完成 +SUB-->>API : 返回 +API-->>U : 返回 +``` + +图表来源 +- [office/api/wechat.py](file://office/api/wechat.py#L1-L40) + +#### 流程三:跨平台兼容性检查(首次运行) +```mermaid +flowchart TD +Start(["import office"]) --> CheckOS["检测操作系统"] +CheckOS --> IsWin{"Windows?"} +IsWin -->|是| Skip["跳过警告"] +IsWin -->|否| CheckMark{"首次运行?"} +CheckMark -->|否| Skip +CheckMark -->|是| CreateMark["创建标记文件
~/.python-office/first_run_mark"] +CreateMark --> ShowTable["显示兼容性表格"] +ShowTable --> ShowAdvice["显示平台建议"] +ShowAdvice --> End(["继续导入API模块"]) +Skip --> End +``` + +图表来源 +- [office/compatibility.py](file://office/compatibility.py#L14-L73) + +## 依赖关系分析 +- **模块耦合** + - API 聚合层仅依赖子库包,保持对外接口稳定。 + - 子库独立发布,各自封装第三方库,向上提供简洁接口。 + - 兼容性检查器与 API 模块无直接耦合,仅在包入口处执行。 +- **外部依赖** + - 跨平台子库:popdf、poexcel、poimage、pofile、povideo、poocr、wftools、poemail、pomarkdown、pocode、pospider、poprogress + - Windows 专用子库:poppt、poword、PyOfficeRobot、search4file + - 通用依赖:rich(彩色输出)、loguru(日志)、you-get(视频下载) +- **接口契约** + - API 层函数签名统一,子库提供稳定接口,便于替换与扩展。 + - 参数兼容机制确保旧代码无需修改即可运行。 + +```mermaid +graph LR +API["office/api/*"] --> SUB["子库生态
(popdf/poexcel/...)"] +SUB --> THIRD["第三方库
(PyMuPDF/openpyxl/...)"] +API --> WIN["Windows专用
(poppt/poword/...)"] +COMPAT["compatibility.py"] --> API +``` + +图表来源 +- [setup.cfg](file://setup.cfg#L19-L41) +- [office/__init__.py](file://office/__init__.py#L1-L29) + +## 性能考量 +- **延迟加载**:Windows 专用模块(wechat、word)在调用时才导入,减少非 Windows 系统的启动开销。 +- **首次运行检测**:兼容性检查仅在首次运行时执行,后续导入无额外开销。 +- **子库按需安装**:用户可单独安装子库(如 `pip install popdf`),无需安装完整 python-office。 +- **批量操作**:支持目录级批量处理,子库内部使用进度条(poprogress)提升用户体验。 + +## 故障排查指南 +- **常见问题** + - 导入错误:非 Windows 系统导入 wechat/word 模块时,若直接 `from office.api.wechat import *` 可能触发延迟加载,但调用函数时才会报错。 + - 参数弃用警告:旧参数名会触发 `DeprecationWarning`,建议迁移到新参数名。 + - 子库版本不匹配:部分功能对子库版本有最低要求,升级至满足条件的版本。 +- **定位路径** + - 从 API 入口定位到子库调用,再深入到第三方库,逐步缩小问题范围。 + - 查看 `loguru` 日志输出定位参数错误。 +- **示例路径** + - [API 参数兼容处理](file://office/api/pdf.py#L1-L50) + - [延迟加载策略](file://office/api/wechat.py#L1-L40) + - [兼容性检查](file://office/compatibility.py#L185-L201) + +## 结论 +python-office 采用清晰的聚合层架构:API 层负责统一入口与参数兼容,子库生态负责具体功能实现,Skills 系统为 AI 工具用户提供额外入口。跨平台兼容性检查器确保非 Windows 用户获得清晰的功能限制提示。该设计使得功能扩展与维护更加清晰,子库可独立迭代,API 层保持稳定。 diff --git "a/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227.md" "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227.md" new file mode 100644 index 00000000..be212353 --- /dev/null +++ "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227.md" @@ -0,0 +1,362 @@ +# 开发者指南 + + +**本文档中引用的文件** +- [README.md](file://README.md) +- [setup.cfg](file://setup.cfg) +- [setup.py](file://setup.py) +- [office/__init__.py](file://office/__init__.py) +- [office/compatibility.py](file://office/compatibility.py) +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/wechat.py](file://office/api/wechat.py) +- [skills/README.md](file://skills/README.md) +- [tests/test_main.py](file://tests/test_main.py) +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py) +- [examples/readme.md](file://examples/readme.md) +- [gui/](file://gui/) + + +## 目录 + +1. [项目结构](#项目结构) +2. [代码分层设计](#代码分层设计) +3. [API聚合层](#api聚合层) +4. [子库生态层](#子库生态层) +5. [Skills系统层](#skills系统层) +6. [单元测试](#单元测试) +7. [添加新功能](#添加新功能) +8. [依赖管理与构建流程](#依赖管理与构建流程) +9. [贡献代码](#贡献代码) + +## 项目结构 + +本项目采用"API聚合 + 子库生态 + Skills系统 + 贡献者"的组织方式,主要目录结构如下: + +```mermaid +graph TD +A[python-office] --> B[office/ 核心包] +A --> C[skills/ Skills系统] +A --> D[tests/ 测试目录] +A --> E[examples/ 示例目录] +A --> F[contributors/ 贡献者目录] +A --> G[gui/ GUI应用] +A --> H[setup.cfg / setup.py 构建配置] +B --> B1[api/ API聚合层] +B --> B2[compatibility.py 兼容性检查] +B1 --> B1a[pdf.py] +B1 --> B1b[excel.py] +B1 --> B1c[image.py] +B1 --> B1d[tools.py] +B1 --> B1e[file.py] +B1 --> B1f[wechat.py] +B1 --> B1g[word.py] +B1 --> B1h[video.py] +B1 --> B1i[finance.py] +B1 --> B1j[ocr.py] +B1 --> B1k[markdown.py] +B1 --> B1l[ppt.py] +B1 --> B1m[email.py] +D --> D1[test_code/ 单元测试] +D --> D2[test_main.py 测试入口] +``` + +**图源** +- [README.md](file://README.md#L1-L50) +- [office/__init__.py](file://office/__init__.py#L1-L29) + +## 代码分层设计 + +项目采用三层架构设计,各层职责分明,便于维护和扩展。 + +```mermaid +graph TD +A[API聚合层
office/api/*] -->|调用| B[子库生态层
popdf/poexcel/poimage/...] +B -->|调用| C[第三方库
PyMuPDF/openpyxl/Pillow/...] +D[外部调用] --> A +D --> E[Skills系统层
skills/] +E -->|复用| B +F[兼容性检查] -->|保护| A +``` + +**图源** +- [office/__init__.py](file://office/__init__.py#L1-L29) +- [setup.cfg](file://setup.cfg#L19-L41) + +## API聚合层 + +API聚合层提供外部调用的接口,是用户与库交互的主要入口。通过`office/__init__.py`导出所有功能模块。 + +```mermaid +classDiagram +class office_api { ++pdf: pdf2docx/pdf2imgs/encrypt4pdf/... ++excel: fake2excel/merge2excel/... ++image: compress_image/add_watermark/... ++tools: transtools/qrcodetools/... ++file: replace4filename/get_files/... ++wechat: send_message/chat_robot/... ++word: docx2pdf/merge4docx/... ++video: video2mp3/txt2mp3/... ++finance: t0 ++ocr: OCR识别 ++markdown: Markdown处理 ++ppt: PPT处理 ++email: 邮件发送 +} +``` + +**关键设计模式:** + +| 模式 | 说明 | 示例 | +|------|------|------| +| 参数兼容 | 新旧参数名共存,旧参数触发 DeprecationWarning | `pdf2docx(file_path=...)` → `pdf2docx(input_file=...)` | +| 延迟加载 | Windows 专用模块在函数体内导入 | `wechat.send_message()` 内部 `from PyOfficeRobot.XXBot import ...` | +| 子库路由 | API 函数直接调用子库同名函数 | `office.api.pdf.pdf2docx()` → `popdf.pdf2docx()` | + +**图源** +- [office/api/pdf.py](file://office/api/pdf.py#L1-L50) +- [office/api/wechat.py](file://office/api/wechat.py#L1-L40) +- [office/__init__.py](file://office/__init__.py#L1-L29) + +## 子库生态层 + +子库生态层包含 16 个独立子库,各自封装特定领域的第三方库调用,实现高内聚低耦合。 + +```mermaid +graph TD +subgraph "跨平台子库" +S1[popdf - PDF处理] +S2[poexcel - Excel处理] +S3[poimage - 图片处理] +S4[pofile - 文件管理] +S5[povideo - 视频处理] +S6[poocr - OCR识别] +S7[wftools - 工具类] +S8[poemail - 邮件发送] +S9[pomarkdown - Markdown处理] +S10[pocode - 代码管理] +S11[pospider - 网络爬虫] +S12[poprogress - 进度条] +end +subgraph "Windows专用子库" +W1[poppt - PPT处理] +W2[poword - Word处理] +W3[PyOfficeRobot - 微信机器人] +W4[search4file - 文件搜索] +end +``` + +**子库依赖关系:** + +| 子库 | 主要第三方依赖 | 功能 | +|------|-------------|------| +| popdf | PyMuPDF, PyPDF2, pdf2docx, Pillow | PDF 转换/加密/解密/水印/合并/拆分 | +| poexcel | openpyxl, pandas, faker | Excel 模拟/合并/拆分/搜索/转换 | +| poimage | Pillow, opencv, wordcloud | 图片压缩/水印/词云/二维码 | +| pofile | pathlib, shutil | 文件重命名/搜索/批量管理 | +| povideo | you-get, moviepy | 视频下载/转码/音频提取 | +| poocr | paddleocr | OCR 文字识别 | +| wftools | translator, qrcode | 翻译/二维码/密码生成 | +| poemail | smtplib | 邮件发送 | +| pomarkdown | markdown | Markdown 处理 | +| poppt | python-pptx, COM接口 | PPT 处理(Windows) | +| poword | python-docx, COM接口 | Word 处理(Windows) | +| PyOfficeRobot | pywinauto | 微信自动化(Windows) | + +**图源** +- [setup.cfg](file://setup.cfg#L19-L41) + +## Skills系统层 + +Skills系统层是 python-office 的特色设计,为 AI 工具用户提供自动识别的功能入口。每个 Skill 包含 `__init__.py`(功能实现)和 `SKILL.md`(AI 可读文档)。 + +```mermaid +graph TD +A[skills/] --> B[PDF处理 7个] +A --> C[Excel处理 4个] +A --> D[图片处理 8个] +A --> E[Word处理 3个] +A --> F[PPT处理 3个] +A --> G[文件管理 6个] +A --> H[视频处理 3个] +A --> I[工具类 10个] +A --> J[微信自动化 7个] +A --> K[OCR识别 3个] +A --> L[金融计算 1个] +A --> M[Markdown处理 2个] +A --> N[邮件 2个] +``` + +**三种使用方式:** +```python +# 方式一:直接导入函数 +from skills.PDF.pdf2docx import pdf2docx +pdf2docx(input_file='input.pdf', output_file='output.docx') + +# 方式二:导入模块 +import skills.PDF.pdf2docx as skill +skill.pdf2docx(input_file='input.pdf') + +# 方式三:AI 工具自动识别 +# AI 工具读取 SKILL.md 文档,自动调用对应函数 +``` + +**图源** +- [skills/README.md](file://skills/README.md#L1-L50) + +## 单元测试 + +项目使用 `pytest` 框架进行单元测试,测试代码位于 `tests/test_code/` 目录下。 + +```mermaid +graph TD +A[tests/] --> B[test_main.py
测试入口] +A --> C[test_code/] +C --> C1[test_pdf.py] +C --> C2[test_excel.py] +C --> C3[test_image.py] +C --> C4[test_file.py] +C --> C5[test_wechat.py] +C --> C6[test_word.py] +C --> C7[test_video.py] +C --> C8[test_tools.py] +C --> C9[test_ocr.py] +C --> C10[test_markdown.py] +C --> C11[test_ppt.py] +C --> C12[test_web.py] +C --> C13[test_dev.py] +C --> C14[test_optional_imports.py] +A --> D[test_utils/] +A --> E[assets/] +``` + +测试入口支持生成 HTML 报告: +```python +# tests/test_main.py +import pytest +if __name__ == '__main__': + pytest.main(['./test_code', '--html=report.html']) +``` + +**图源** +- [tests/test_main.py](file://tests/test_main.py#L1-L25) +- [tests/test_code/](file://tests/test_code/) + +## 添加新功能 + +为项目添加新功能需要遵循以下步骤: + +```mermaid +flowchart TD +A["1. 选择子库
(如popdf/poexcel)"] --> B["2. 在子库中实现核心逻辑"] +B --> C["3. 在office/api/对应模块
添加API接口"] +C --> D["4. 在skills/对应分类下
创建Skill(可选)"] +D --> E["5. 在examples/下
创建使用示例"] +E --> F["6. 在tests/test_code/下
编写单元测试"] +F --> G["7. 更新skills/README.md
(如新增Skill)"] +G --> H["8. 提交PR"] +``` + +### 详细步骤说明 + +**步骤 1-2:子库实现** +在对应子库(如 popdf)中实现核心逻辑,确保功能独立可用。 + +**步骤 3:API 接口封装** +在 `office/api/` 对应模块中添加函数,导入子库并封装: +```python +# office/api/pdf.py 示例 +from popdf import pdf2docx as _pdf2docx + +def pdf2docx(input_file, output_file, **kwargs): + """PDF转Word + + Args: + input_file (str): 输入PDF文件路径 + output_file (str): 输出Word文件路径 + """ + _pdf2docx(input_file=input_file, output_file=output_file, **kwargs) +``` + +**步骤 4:创建 Skill(可选)** +在 `skills/` 对应分类下创建子目录: +``` +skills/PDF/my_new_feature/ +├── __init__.py # 功能实现 +└── SKILL.md # AI可读文档 +``` + +**步骤 5-6:示例与测试** +- 在 `examples/` 下创建使用示例文件 +- 在 `tests/test_code/` 下编写单元测试,使用 `unittest.TestCase` + +**图源** +- [README.md](file://README.md#L80-L100) +- [skills/README.md](file://skills/README.md#L1-L50) + +## 依赖管理与构建流程 + +项目使用 `setup.cfg` 进行依赖管理,通过 `setuptools` 进行构建。 + +```mermaid +graph TD +A[setup.cfg] --> B[依赖声明] +A --> C[构建配置] +A --> D[元数据] +B --> E[跨平台子库
popdf/poexcel/poimage/...] +B --> F[Windows专用子库
poppt/poword/PyOfficeRobot/...] +B --> G[通用依赖
rich/loguru/you-get] +C --> H[setuptools] +D --> I[name: python-office] +D --> J[version: 1.0.6] +D --> K[python_requires: >=3.6] +``` + +**构建与发布:** +```bash +# 安装构建工具 +pip install build twine + +# 构建包 +python -m build + +# 发布到PyPI +twine upload dist/* +``` + +**图源** +- [setup.cfg](file://setup.cfg#L1-L44) +- [setup.py](file://setup.py#L1-L10) + +## 贡献代码 + +欢迎任何人参与项目开发。贡献代码的步骤如下: + +1. Fork 项目到自己的仓库 +2. 克隆到本地进行修改 +3. 在 `contributors/` 下创建以 GitHub 用户名命名的文件夹 +4. 在文件夹中创建功能文件 +5. 提交代码并推送到自己的仓库 +6. 创建 Pull Request 到主分支 +7. 等待作者合并 + +```mermaid +flowchart TD +A[Fork项目] --> B[克隆到本地] +B --> C[创建贡献者文件夹
contributors/用户名/] +C --> D[编写功能代码] +D --> E[创建使用示例] +E --> F[编写单元测试] +F --> G[提交并推送] +G --> H[创建PR] +H --> I[等待合并] +``` + +**注意事项:** +- 禁止修改其他贡献者的代码或核心模块 +- 禁止修改 README.md、setup.py 等核心配置文件 +- 每个新增功能需配套使用示例和单元测试 + +**图源** +- [README.md](file://README.md#L100-L135) diff --git "a/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\346\265\213\350\257\225\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\346\265\213\350\257\225\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" new file mode 100644 index 00000000..eb8c9093 --- /dev/null +++ "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\346\265\213\350\257\225\347\255\226\347\225\245\344\270\216\345\256\236\350\267\265.md" @@ -0,0 +1,398 @@ +# 测试策略与实践 + + +**本文档引用的文件** +- [tests/test_main.py](file://tests/test_main.py) +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py) +- [tests/test_code/test_excel.py](file://tests/test_code/test_excel.py) +- [tests/test_code/test_dev.py](file://tests/test_code/test_dev.py) +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py) +- [tests/test_utils/comm_utils.py](file://tests/test_utils/comm_utils.py) +- [tests/test_utils/test_input.py](file://tests/test_utils/test_input.py) +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/compatibility.py](file://office/compatibility.py) + + +## 目录 +1. [引言](#引言) +2. [项目结构与测试布局](#项目结构与测试布局) +3. [核心测试组件分析](#核心测试组件分析) +4. [测试架构概述](#测试架构概述) +5. [详细组件测试分析](#详细组件测试分析) +6. [跨平台导入测试](#跨平台导入测试) +7. [测试工具与辅助函数](#测试工具与辅助函数) +8. [依赖关系分析](#依赖关系分析) +9. [性能与覆盖率考量](#性能与覆盖率考量) +10. [故障排查指南](#故障排查指南) +11. [结论](#结论) + +## 引言 +本文档旨在为开发者提供一套完整的单元测试策略,指导如何使用 `unittest` 与 `pytest` 框架对 python-office 的多模块功能进行高质量测试验证。通过分析 `test_pdf.py`、`test_excel.py`、`test_optional_imports.py` 的测试结构,结合 `test_utils/` 中的辅助工具,明确测试用例组织规范、测试数据管理方式以及覆盖率要求。 + +## 项目结构与测试布局 + +```mermaid +graph TB +subgraph "测试入口" +TM["tests/test_main.py
pytest主入口"] +end +subgraph "测试代码" +TC["tests/test_code/"] +TC1["test_pdf.py"] +TC2["test_excel.py"] +TC3["test_image.py"] +TC4["test_file.py"] +TC5["test_wechat.py"] +TC6["test_word.py"] +TC7["test_video.py"] +TC8["test_tools.py"] +TC9["test_ocr.py"] +TC10["test_markdown.py"] +TC11["test_ppt.py"] +TC12["test_web.py"] +TC13["test_dev.py"] +TC14["test_optional_imports.py"] +end +subgraph "测试工具" +TU["tests/test_utils/"] +TU1["comm_utils.py
通用断言工具"] +TU2["test_input.py
输入模拟工具"] +end +subgraph "测试资源" +TF["tests/test_files/"] +TA["tests/assets/"] +end +subgraph "核心实现" +API["office/api/*"] +COMPAT["office/compatibility.py"] +end +TC1 --> API +TC2 --> API +TC14 --> API +TC14 --> COMPAT +TC1 --> TU2 +TC2 --> TU1 +TM --> TC +``` + +**图示来源** +- [tests/test_main.py](file://tests/test_main.py#L1-L25) +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L1-L10) +- [tests/test_code/test_excel.py](file://tests/test_code/test_excel.py#L1-L10) +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py#L1-L30) + +## 核心测试组件分析 + +### 测试框架选型 +项目同时使用 `unittest` 和 `pytest` 两种框架: +- **unittest**:用于编写测试类和测试方法,提供 `setUpClass`、`assert*` 等标准断言。 +- **pytest**:用于运行测试套件、生成 HTML 报告、支持参数化测试。 + +```python +# tests/test_main.py — pytest 主入口 +import pytest +if __name__ == '__main__': + pytest.main(['./test_code', '--html=report.html']) +``` + +### 测试类组织 +每个功能模块对应一个测试文件,测试类继承 `unittest.TestCase`,使用 `@classmethod setUpClass` 共享测试资源。 + +**图示来源** +- [tests/test_main.py](file://tests/test_main.py#L1-L25) +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L12-L22) + +## 测试架构概述 + +```mermaid +classDiagram +class TestPDF { ++setUpClass() ++test_add_watermark() ++test_add_watermark_by_parameters() ++test_pdf2imgs() ++test_pdf2docx() ++test_pdf2docx_path() ++test_merge2pdf() ++test_single_encrypt4pdf() ++test_batch_encrypt4pdf() ++test_single_decrypt4pdf() ++test_batch_decrypt4pdf() ++test_add_img_water() +} +class TestExcel { ++test_fake2excel() ++test_split_excel_by_column() ++test_sheet2excel() ++test_merge2sheet() ++test_merge2excel() ++test_find_excel_data() +} +class TestOptionalImports { +-test_import_office_without_windows_only_dependencies() +-test_loader_preserves_dependency_internal_import_errors() +-test_loader_reports_missing_windows_only_dependency() +} +class OfficeAPI { ++pdf: pdf2docx/encrypt4pdf/... ++excel: fake2excel/merge2excel/... +} +TestPDF --> OfficeAPI : 调用 +TestExcel --> OfficeAPI : 调用 +TestOptionalImports --> OfficeAPI : 导入验证 +``` + +**图示来源** +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L12-L112) +- [tests/test_code/test_excel.py](file://tests/test_code/test_excel.py#L11-L81) +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py#L65-L166) + +## 详细组件测试分析 + +### PDF 功能测试分析 + +#### 测试场景覆盖 + +| 测试方法 | 测试场景 | 覆盖类型 | +|---------|---------|---------| +| `test_add_watermark` | 交互式输入添加水印 | 正常流程(stdin模拟) | +| `test_add_watermark_by_parameters` | 参数式添加水印 | 正常流程 | +| `test_pdf2imgs` | PDF转图片 | 正常流程 | +| `test_pdf2docx` | 单文件PDF转Word | 正常流程 | +| `test_pdf2docx_path` | 批量PDF转Word(目录) | 批量处理 | +| `test_merge2pdf` | 合并多个PDF | 正常流程 | +| `test_single_encrypt4pdf` | 单文件加密 | 正常流程 | +| `test_batch_encrypt4pdf` | 批量加密 | 批量处理 | +| `test_single_decrypt4pdf` | 单文件解密 | 正常流程 | +| `test_batch_decrypt4pdf` | 批量解密 | 批量处理 | +| `test_add_img_water` | 图片水印 | 正常流程 | + +#### 测试流程(以PDF转Word为例) + +```mermaid +sequenceDiagram +participant Test as TestPDF +participant API as office.api.pdf +participant SUB as popdf +participant THIRD as pdf2docx +Test->>Test : setUpClass() 设置INPUT_PDF路径 +Test->>API : pdf2docx(input_file, output_file) +API->>API : 参数兼容检查 +API->>SUB : popdf.pdf2docx(input_file, output_file) +SUB->>THIRD : Converter.convert() +THIRD-->>SUB : 转换完成 +SUB-->>API : 返回 +API-->>Test : 返回 +Test->>Test : 隐式验证输出文件存在 +``` + +**图示来源** +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L18-L112) + +### Excel 功能测试分析 + +#### 测试特点 +Excel 测试是项目中验证最严格的模块,使用了多种断言方法: + +```mermaid +flowchart TD +A["test_fake2excel"] --> B["assertTrue: 文件存在"] +A --> C["assertEqual: 标题为name"] +A --> D["assertTrue: 内容为中文"] +E["test_split_excel_by_column"] --> F["assertIn: Sheet名存在"] +E --> G["验证拆分后内容"] +H["test_sheet2excel"] --> I["assertTrue: 拆分文件存在"] +H --> J["assertEqual: 标题一致"] +H --> K["assertEqual: 内容一致"] +L["test_merge2excel"] --> M["assertTrue: 合并文件存在"] +L --> N["assertIn: Sheet名存在"] +L --> O["assertNotIn: 排除项验证"] +``` + +**关键断言模式:** +```python +# 文件存在性验证 +self.assertTrue(file_exist(test_file_name)) + +# 内容一致性验证 +self.assertEqual( + get_colum_content(test_file_name, 0, sheet_name), + get_colum_content(f'./{sheet_name}.xlsx', 0, sheet_name) +) + +# 排除性验证 +self.assertNotIn("sedemo_Split_2022-08-23_203413", + get_all_sheet_names(test_file_name)) +``` + +**图示来源** +- [tests/test_code/test_excel.py](file://tests/test_code/test_excel.py#L16-L81) + +## 跨平台导入测试 + +`test_optional_imports.py` 是项目最复杂的测试文件,验证 Windows 专用模块在非 Windows 系统上的导入安全性。 + +### 测试策略 + +```mermaid +flowchart TD +Start(["开始测试"]) --> Setup["创建隔离测试环境"] +Setup --> MockModules["模拟跨平台子库
(poexcel/popdf/...)"] +Setup --> RemoveWinModules["移除Windows专用模块
(poppt/poword/PyOfficeRobot)"] +Setup --> MockHome["模拟HOME目录
创建首次运行标记"] +MockModules --> ImportOffice["import office"] +RemoveWinModules --> ImportOffice +MockHome --> ImportOffice +ImportOffice --> VerifyImport{"导入成功?"} +VerifyImport -->|是| TestLoaders["测试延迟加载器"] +VerifyImport -->|否| Fail["测试失败"] +TestLoaders --> TestMissingDep["验证缺失依赖报错信息"] +TestLoaders --> TestInternalDep["验证内部依赖错误透传"] +TestMissingDep --> End(["测试通过"]) +TestInternalDep --> End +``` + +### 三种测试场景 + +| 测试方法 | 测试目标 | 验证点 | +|---------|---------|-------| +| `test_import_office_without_windows_only_dependencies` | 无 Windows 依赖时包导入正常 | `import office` 不抛出异常 | +| `test_loader_reports_missing_windows_only_dependency` | 延迟加载器报告友好的缺失依赖信息 | `ModuleNotFoundError` 消息包含中文说明 | +| `test_loader_preserves_dependency_internal_import_errors` | 内部依赖错误不被吞没 | 原始 `ModuleNotFoundError` 透传 | + +### 测试环境隔离技术 + +```python +# 使用 contextmanager 创建隔离环境 +@contextmanager +def _optional_import_test_environment(self): + # 1. 保存原始模块状态 + original_modules = {name: sys.modules.get(name) for name in ...} + # 2. 创建临时 HOME 目录(模拟首次运行标记) + with tempfile.TemporaryDirectory() as temp_home: + os.environ["HOME"] = temp_home + # 3. 创建标记文件跳过兼容性检查 + mark_file.write("already checked") + # 4. 注入模拟模块 + for name in SUPPORTED_DEPENDENCIES: + sys.modules[name] = types.ModuleType(name) + # 5. 移除 Windows 专用模块 + for name in WINDOWS_ONLY_DEPENDENCIES: + sys.modules.pop(name, None) + yield + # 6. 恢复原始状态 +``` + +**图示来源** +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py#L65-L166) + +## 测试工具与辅助函数 + +### comm_utils.py — 通用测试工具 + +| 工具函数 | 功能 | 使用场景 | +|---------|------|---------| +| `file_exist(file_path)` | 判断文件是否存在 | 验证输出文件生成 | +| `get_colum_content(file_path, col, sheet)` | 获取 Excel 列标题 | 验证 Excel 内容 | +| `get_content(file_path, row, col, sheet)` | 获取 Excel 单元格值 | 验证 Excel 数据一致性 | +| `get_all_sheet_names(file_path)` | 获取所有 Sheet 名称 | 验证合并/拆分结果 | +| `get_filter_names(file_path, col)` | 获取列分类值 | 验证拆分逻辑 | +| `get_latest_file(dir_path)` | 获取目录最新文件 | 验证生成文件 | +| `is_chinese_chars_regex(s)` | 判断中文字符串 | 验证中文内容 | +| `get_file_by_suffix(dir_path, suffix)` | 按后缀获取文件 | 测试资源管理 | + +### test_input.py — 输入模拟工具 + +```python +# 模拟 stdin 输入,用于交互式功能的测试 +stub_stdin(self, f'{self.INPUT_PDF}\npython-office\n') +add_watermark() # 函数内部读取 stdin +``` + +**图示来源** +- [tests/test_utils/comm_utils.py](file://tests/test_utils/comm_utils.py#L1-L187) +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L22-L24) + +## 依赖关系分析 + +```mermaid +graph TD +A[test_main.py] --> B[pytest] +B --> C[test_code/*.py] +C --> D[office.api.*] +D --> E[子库 (popdf/poexcel/...)] +C --> F[test_utils/comm_utils.py] +C --> G[test_utils/test_input.py] +F --> H[pandas] +F --> I[openpyxl] +D --> J[office.compatibility] +J --> K[rich / platform] +``` + +所有测试用例均依赖于 `office.api.*` 提供的高层接口,而这些接口又依赖于子库的具体实现。`test_utils/` 提供通用的断言工具,减少重复代码。 + +**图示来源** +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L1-L10) +- [tests/test_code/test_excel.py](file://tests/test_code/test_excel.py#L1-L10) +- [tests/test_utils/comm_utils.py](file://tests/test_utils/comm_utils.py#L1-L10) + +## 性能与覆盖率考量 + +### 测试覆盖率要求 + +| 功能模块 | 正常流程 | 批量处理 | 异常处理 | 边界情况 | +|---------|---------|---------|---------|---------| +| PDF转Word | ✓ | ✓ (目录) | 参数兼容 | — | +| PDF转图片 | ✓ | — | — | — | +| PDF加密 | ✓ | ✓ (目录) | — | — | +| PDF解密 | ✓ | ✓ (目录) | — | — | +| PDF水印 | ✓ (交互) | ✓ (参数) | — | — | +| PDF合并 | ✓ | — | — | — | +| Excel模拟 | ✓ | — | — | — | +| Excel拆分 | ✓ | — | — | — | +| Excel合并 | ✓ | — | — | ✓ (排除验证) | +| 跨平台导入 | ✓ | — | ✓ (缺失依赖) | ✓ (内部错误透传) | + +### 测试数据管理规范 +- **测试代码**:存放于 `tests/test_code/` 目录下 +- **测试工具**:存放于 `tests/test_utils/` 目录下 +- **测试资源**:存放于 `tests/test_files/` 对应子目录中 +- **命名规范**:测试文件与功能模块对应,如 `test_pdf.py` 对应 PDF 功能 +- **共享资源**:使用 `@classmethod setUpClass` 在测试类级别共享测试文件路径 + +### 运行测试 + +```bash +# 运行所有测试并生成HTML报告 +cd tests +python test_main.py + +# 运行单个测试文件 +python -m pytest tests/test_code/test_pdf.py -v + +# 运行特定测试类 +python -m pytest tests/test_code/test_excel.py::TestExcel -v + +# 运行并查看覆盖率 +python -m pytest tests/test_code/ --cov=office --cov-report=html +``` + +## 故障排查指南 + +当测试失败时,请按以下步骤排查: + +1. **检查路径问题**:确认测试文件路径使用 `./tests/test_files/` 前缀,使用 `os.path.join` 构造跨平台路径 +2. **验证依赖项**:确保子库(popdf、poexcel 等)已正确安装 +3. **查看日志输出**:检查 `loguru` 输出的错误信息,定位参数错误原因 +4. **测试数据完整性**:确认测试用 PDF/Excel 文件未损坏且可正常打开 +5. **权限问题**:确保程序有读写目标目录的权限 +6. **Windows 专用模块**:非 Windows 系统运行 wechat/word/ppt 测试时,需确认延迟加载机制正常工作 +7. **首次运行标记**:如兼容性检查干扰测试,可创建 `~/.python-office/first_run_mark` 标记文件跳过 + +**图示来源** +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L18-L22) +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py#L68-L90) + +## 结论 +python-office 项目采用分层测试策略:功能测试(`test_pdf.py`、`test_excel.py` 等)验证 API 层的正确性,跨平台导入测试(`test_optional_imports.py`)验证延迟加载机制的健壮性,通用工具(`comm_utils.py`)提供统一的断言辅助。建议在后续开发中持续完善测试用例,特别是补充图片处理、视频处理、微信自动化等模块的断言验证,并使用 `coverage.py` 确保核心模块测试覆盖率不低于 85%。 diff --git "a/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\350\264\241\347\214\256\344\273\243\347\240\201\346\214\207\345\215\227.md" "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\350\264\241\347\214\256\344\273\243\347\240\201\346\214\207\345\215\227.md" new file mode 100644 index 00000000..4b064469 --- /dev/null +++ "b/wiki/zh/content/\345\274\200\345\217\221\350\200\205\346\214\207\345\215\227/\350\264\241\347\214\256\344\273\243\347\240\201\346\214\207\345\215\227.md" @@ -0,0 +1,418 @@ +# 贡献代码指南 + + +**本文引用的文件** +- [README.md](file://README.md) +- [setup.cfg](file://setup.cfg) +- [setup.py](file://setup.py) +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/wechat.py](file://office/api/wechat.py) +- [office/compatibility.py](file://office/compatibility.py) +- [skills/README.md](file://skills/README.md) +- [contributors/demo/WordType.py](file://contributors/demo/WordType.py) +- [contributors/CatchDr/doc2docx.py](file://contributors/CatchDr/doc2docx.py) +- [contributors/bulabean/SearchExcel.py](file://contributors/bulabean/SearchExcel.py) +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py) +- [tests/test_code/test_excel.py](file://tests/test_code/test_excel.py) +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py) + + +## 目录 +1. [简介](#简介) +2. [项目结构与贡献模式](#项目结构与贡献模式) +3. [核心贡献流程](#核心贡献流程) +4. [架构总览](#架构总览) +5. [详细规范说明](#详细规范说明) +6. [依赖关系分析](#依赖关系分析) +7. [性能与质量建议](#性能与质量建议) +8. [故障排查指南](#故障排查指南) +9. [结语](#结语) + +## 简介 +本指南面向希望参与 python-office 项目开发的贡献者。与一般开源项目不同,python-office 采用独特的"隔离式贡献"模式: +- 所有贡献者必须在 `contributors/` 目录下创建独立文件夹,不修改核心代码。 +- 同时欢迎通过子库生态(popdf、poexcel 等)贡献核心功能。 +- 新增功能需配套使用示例和单元测试。 + +本指南依据仓库 README.md 的贡献要求,系统化说明从 fork 到 PR 提交的完整流程。 + +## 项目结构与贡献模式 + +```mermaid +graph TB +subgraph "核心代码(不建议修改)" +A["office/api/*
API聚合层"] +B["office/compatibility.py
兼容性检查"] +C["skills/
Skills系统"] +end +subgraph "贡献者代码(自由发挥)" +D["contributors/"] +D --> D1["CatchDr/"] +D --> D2["bulabean/"] +D --> D3["demo/"] +D --> D4["yinzeyuan/"] +D --> D5["你的用户名/"] +end +subgraph "子库生态(独立仓库)" +E["popdf / poexcel / poimage
pofile / povideo / poocr
..."] +end +subgraph "测试与示例" +F["tests/test_code/"] +G["examples/"] +end +A --> E +F --> A +G --> A +``` + +**图表来源** +- [README.md](file://README.md#L1-L50) +- [contributors/](file://contributors/) + +章节来源 +- [README.md](file://README.md#L100-L135) + +## 核心贡献流程 + +### 步骤 1:Fork 与克隆 +```bash +# Fork 项目到个人仓库 +git clone https://github.com/YOUR_USERNAME/python-office.git +cd python-office +git remote add upstream https://github.com/CoderWanFeng/python-office.git +``` + +### 步骤 2:创建贡献分支 +```bash +git checkout -b feature-your-feature-name +``` + +### 步骤 3:创建贡献文件夹 +```bash +# 在 contributors 目录下创建以 GitHub 用户名命名的文件夹 +mkdir contributors/your-github-username +``` + +### 步骤 4:编写功能代码 +在个人文件夹中创建功能文件,遵循代码规范(见下文)。 + +### 步骤 5:配套示例与测试 +- 在 `examples/` 下创建使用示例 +- 在 `tests/test_code/` 下编写单元测试 + +### 步骤 6:提交 PR +```bash +git add . +git commit -m "feat: 添加新功能描述" +git push origin feature-your-feature-name +# 在 GitHub/Gitee/atomgit 上创建 Pull Request +``` + +```mermaid +flowchart TD +A["Fork 项目"] --> B["克隆到本地"] +B --> C["创建功能分支"] +C --> D["创建贡献者文件夹
contributors/用户名/"] +D --> E["编写功能代码"] +E --> F["创建使用示例"] +F --> G["编写单元测试"] +G --> H["提交并推送"] +H --> I["创建 PR"] +I --> J["等待审核"] +J --> K{"审核通过?"} +K -->|是| L["合并并发布"] +K -->|否| M["根据反馈修改"] +M --> H +``` + +**图表来源** +- [README.md](file://README.md#L100-L135) + +## 架构总览 + +python-office 的贡献架构分为三个层次: + +```mermaid +graph TB +subgraph "贡献层次一:隔离式贡献" +CON["contributors/用户名/
独立功能文件"] +CON --> API1["office/api/*
(只读引用)"] +end +subgraph "贡献层次二:子库贡献" +SUB["子库仓库
(popdf/poexcel/...)"] +SUB --> API2["office/api/*
通过子库更新"] +end +subgraph "贡献层次三:Skills贡献" +SKILL["skills/分类/Skill名/
__init__.py + SKILL.md"] +SKILL --> SUB2["子库功能复用"] +end +subgraph "测试验证" +TEST["tests/test_code/
单元测试"] +TEST --> API1 +TEST --> API2 +end +``` + +**图表来源** +- [office/api/pdf.py](file://office/api/pdf.py#L1-L20) +- [contributors/demo/WordType.py](file://contributors/demo/WordType.py#L1-L20) +- [skills/README.md](file://skills/README.md#L1-L30) + +## 详细规范说明 + +### 1) 隔离式贡献规范 + +每个贡献者在 `contributors/` 下创建独立文件夹,文件命名应清晰反映功能用途: + +``` +contributors/ +├── CatchDr/ +│ ├── Baidu_Text_transAPI.py +│ ├── doc2docx.py +│ └── docx2doc.py +├── bulabean/ +│ ├── SearchExcel.py +│ └── SplitExcel.py +├── demo/ +│ └── WordType.py +├── yinzeyuan/ +│ ├── Rename-AddSomething.py +│ └── SearchSpecifyTypeFile.py +└── your-username/ + └── your-function.py +``` + +**核心原则:** +- **禁止修改他人代码**:严禁修改其他贡献者的代码或核心模块 +- **禁止修改核心配置**:不修改 README.md、setup.cfg、setup.py 等 +- **鼓励创新实验**:个人文件夹内可自由发挥 + +章节来源 +- [README.md](file://README.md#L117-L135) +- [contributors/CatchDr/doc2docx.py](file://contributors/CatchDr/doc2docx.py#L1-L20) +- [contributors/bulabean/SearchExcel.py](file://contributors/bulabean/SearchExcel.py#L1-L20) + +### 2) 代码规范 + +#### 文件头部注释 +```python +# -*- coding: UTF-8 -*- +""" +功能描述:简要说明功能用途 +作者:GitHub用户名 +项目:https://www.python-office.com +""" +``` + +#### 函数文档字符串 +```python +def your_function(param1: str, param2: int) -> bool: + """功能简述。 + + Args: + param1 (str): 参数1说明 + param2 (int): 参数2说明 + + Returns: + bool: 返回值说明 + + Raises: + FileNotFoundError: 当文件不存在时抛出 + """ +``` + +#### 命名规范 +| 类型 | 规范 | 示例 | +|------|------|------| +| 函数/变量 | snake_case | `merge2pdf`, `input_file` | +| 类 | PascalCase | `CrossPlatformCompatibility` | +| 常量 | UPPER_CASE | `INPUT_PDF` | +| 文件名 | 功能导向 | `doc2docx.py`, `SearchExcel.py` | + +#### 参数兼容规范(核心模块) +如需修改核心 API 参数名,必须保持向后兼容: +```python +# 旧参数名触发 DeprecationWarning,同时映射到新参数 +def pdf2docx(input_file=None, output_file=None, file_path=None, ...): + if file_path is not None: + warnings.warn("'file_path' 已弃用,请使用 'input_file'", DeprecationWarning) + input_file = input_file or file_path +``` + +章节来源 +- [office/api/pdf.py](file://office/api/pdf.py#L1-L50) +- [contributors/demo/WordType.py](file://contributors/demo/WordType.py#L1-L20) + +### 3) 延迟加载规范(Windows 专用模块) + +对于依赖 Windows 专用库(poword、PyOfficeRobot 等)的 API 函数,必须在函数体内导入,而非模块顶部: + +```python +# 正确:延迟加载 +# office/api/wechat.py +def send_message(who, message): + from PyOfficeRobot.XXBot import send_message as bot_send + bot_send(who, message) + +# 错误:顶部导入(非 Windows 系统会失败) +# from PyOfficeRobot.XXBot import send_message # 不要这样写 +``` + +章节来源 +- [office/api/wechat.py](file://office/api/wechat.py#L1-L40) +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py#L36-L58) + +### 4) 创建使用示例 + +在 `examples/` 下选择合适子目录,新增 Python 文件: + +```python +# examples/your_category/your_feature.py +""" +功能:演示 your_feature 的使用方法 +""" +import office + +# 示例1:基本用法 +office.your_module.your_function( + input_file='input.txt', + output_file='output.txt' +) + +# 示例2:批量用法 +office.your_module.your_function( + input_path='./input_dir/', + output_path='./output_dir/' +) +``` + +章节来源 +- [README.md](file://README.md#L80-L90) + +### 5) 编写单元测试 + +在 `tests/test_code/` 下新增测试文件,使用 `unittest.TestCase`: + +```python +# tests/test_code/test_your_feature.py +import unittest +from office.api.your_module import your_function +from tests.test_utils.comm_utils import file_exist + +class TestYourFeature(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.INPUT_FILE = './tests/test_files/your_module/input.txt' + + def test_your_function(self): + """测试基本功能""" + your_function( + input_file=self.INPUT_FILE, + output_file='./tests/test_files/your_module/output.txt' + ) + # 验证输出文件存在 + self.assertTrue(file_exist('./tests/test_files/your_module/output.txt')) + + def test_your_function_batch(self): + """测试批量处理""" + your_function( + input_path='./tests/test_files/your_module/', + output_path='./tests/test_files/your_module/batch_output/' + ) +``` + +**测试覆盖要求:** +- 正常路径:单文件处理 +- 批量路径:目录级批量处理 +- 边界条件:空参数、非法路径 +- 回归测试:历史兼容参数 + +章节来源 +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L1-L112) +- [tests/test_code/test_excel.py](file://tests/test_code/test_excel.py#L1-L81) + +### 6) 添加新 Skill(可选) + +如功能适合 AI 工具使用,可在 `skills/` 下创建 Skill: + +``` +skills/分类/your_skill/ +├── __init__.py # 功能实现(可复用子库) +└── SKILL.md # AI可读文档 +``` + +SKILL.md 格式: +```markdown +# Skill名称 + +## 功能描述 +简要描述功能用途。 + +## 参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| input_file | str | 输入文件路径 | +| output_file | str | 输出文件路径 | + +## 使用示例 +\`\`\`python +from skills.分类.your_skill import your_function +your_function(input_file='input.pdf', output_file='output.pdf') +\`\`\` +``` + +章节来源 +- [skills/README.md](file://skills/README.md#L1-L50) + +## 依赖关系分析 + +```mermaid +graph LR +CONTRIB["contributors/用户名/"] --> API["office/api/*"] +TEST["tests/test_code/"] --> API +EXAMPLE["examples/"] --> API +SKILL["skills/"] --> SUB["子库生态"] +API --> SUB +SUB --> THIRD["第三方库"] +COMPAT["compatibility.py"] --> API +``` + +- **贡献者代码**通过 `import office` 调用 API 层接口 +- **测试代码**通过 `from office.api.* import *` 直接调用 API +- **示例代码**通过 `import office` 演示使用方法 +- **Skills** 复用子库功能,可独立于 API 层 + +**图表来源** +- [office/api/pdf.py](file://office/api/pdf.py#L1-L20) +- [tests/test_code/test_pdf.py](file://tests/test_code/test_pdf.py#L1-L10) +- [skills/README.md](file://skills/README.md#L1-L30) + +## 性能与质量建议 +- 示例与测试应尽量覆盖常见输入规模与边界情况,避免长耗时任务阻塞 CI +- 测试文件中使用相对路径与固定测试资源,减少对环境的依赖 +- 新增功能时,优先在 API 层增加参数校验与错误提示,提升用户体验 +- Windows 专用功能必须使用延迟加载,确保跨平台导入安全 +- 测试中可使用 `tests/test_utils/comm_utils.py` 中的工具函数,减少重复代码 + +## 故障排查指南 +- **导入错误**:非 Windows 系统导入 wechat/word/ppt 模块时,检查是否使用了延迟加载 +- **参数弃用警告**:旧参数名触发 `DeprecationWarning`,建议迁移到新参数名 +- **测试路径问题**:确保测试文件路径使用 `./tests/test_files/` 前缀 +- **首次运行标记**:如兼容性检查干扰测试,创建 `~/.python-office/first_run_mark` 文件跳过 +- **子库版本不匹配**:部分功能对子库版本有最低要求,通过 `pip install --upgrade 子库名` 升级 + +章节来源 +- [office/compatibility.py](file://office/compatibility.py#L185-L201) +- [office/api/pdf.py](file://office/api/pdf.py#L1-L50) +- [tests/test_code/test_optional_imports.py](file://tests/test_code/test_optional_imports.py#L68-L90) + +## 结语 +感谢每一位贡献者的付出。python-office 采用隔离式贡献模式,既保护核心代码稳定性,又为社区创新提供空间。请严格遵守新增/修改功能必须配套示例与测试的原则,共同维护 python-office 的高质量与易用性。如有任何疑问,欢迎在项目交流群中沟通。 + +| 平台 | 链接 | 适用场景 | +|------|------|---------| +| GitHub | https://github.com/CoderWanFeng/python-office/issues | 国际用户 | +| Gitee | https://gitee.com/CoderWanFeng/python-office/issues | 国内镜像 | +| atomgit | https://atomgit.com/CoderWanFeng1/python-office/issues | 国内首选 | +| 交流群 | https://www.python4office.cn/wechat-group | 技术交流 | diff --git "a/wiki/zh/content/\345\277\253\351\200\237\345\205\245\351\227\250.md" "b/wiki/zh/content/\345\277\253\351\200\237\345\205\245\351\227\250.md" new file mode 100644 index 00000000..74f5f499 --- /dev/null +++ "b/wiki/zh/content/\345\277\253\351\200\237\345\205\245\351\227\250.md" @@ -0,0 +1,299 @@ +# 快速入门 + + +**本文档中引用的文件** +- [README.md](file://README.md) +- [office/__init__.py](file://office/__init__.py) +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/image.py](file://office/api/image.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/tools.py](file://office/api/tools.py) +- [office/api/file.py](file://office/api/file.py) +- [examples/popdf/pdf转word.py](file://examples/popdf/pdf转word.py) +- [examples/poimage/图片加水印.py](file://examples/poimage/图片加水印.py) +- [examples/poexcel/批量模拟数据.py](file://examples/poexcel/批量模拟数据.py) + + +## 目录 + +1. [简介](#简介) +2. [安装与验证](#安装与验证) +3. [核心功能快速上手](#核心功能快速上手) + 1. [PDF转Word](#pdf转word) + 2. [图片压缩](#图片压缩) + 3. [图片加水印](#图片加水印) + 4. [生成词云](#生成词云) + 5. [生成二维码](#生成二维码) + 6. [Excel模拟数据](#excel模拟数据) + 7. [批量重命名文件](#批量重命名文件) + 8. [微信发送消息](#微信发送消息) +4. [Skills 系统快速上手](#skills-系统快速上手) +5. [常见注意事项](#常见注意事项) +6. [总结](#总结) + +## 简介 + +`python-office` 是中文世界最受欢迎的 Python 办公自动化库,提供 73 个开箱即用的 Skill,覆盖 PDF、Word、Excel、PPT、图片、视频、邮件等场景。本教程将引导您从零开始,快速掌握核心功能的使用方法。 + +所有功能均通过统一的 `office` 接口调用,无需深入了解底层实现细节,即可在 5 分钟内完成第一个办公自动化任务。 + +## 安装与验证 + +首先,使用 pip 安装 `python-office` 库: + +```bash +pip install -i https://mirrors.aliyun.com/pypi/simple/ python-office -U +``` + +安装完成后,验证安装是否成功: + +```python +import office +print(office.__version__) # 应输出 1.0.6 +``` + +**Section sources** + +- [README.md](file://README.md#L139-L155) +- [office/__init__.py](file://office/__init__.py#L1-L30) + +## 核心功能快速上手 + +### PDF转Word + +将 PDF 文件转换为 Word 文档是常见需求。使用 `office.pdf.pdf2docx()` 函数即可轻松实现。 + +```python +import office + +office.pdf.pdf2docx( + input_file='report.pdf', + output_file='report.docx' +) +``` + +**关键参数说明:** + +- `input_file`: 输入 PDF 文件的路径 +- `output_file`: 输出 Word 文件的路径,必须包含 `.docx` 后缀 + +该功能底层调用 popdf 库,基于 pdf2docx 实现高质量转换。 + +**Section sources** + +- [office/api/pdf.py](file://office/api/pdf.py#L48-L87) +- [examples/popdf/pdf转word.py](file://examples/popdf/pdf转word.py) + +### 图片压缩 + +压缩图片文件大小,同时尽量保持视觉质量。 + +```python +import office + +office.image.compress_image( + input_file='big.jpg', + output_file='small.jpg', + quality=30 +) +``` + +**关键参数说明:** + +- `input_file`: 输入图片路径 +- `output_file`: 压缩后图片保存路径 +- `quality`: 压缩质量,取值 0-95,数值越高质量越好但文件越大 + +**Section sources** + +- [office/api/image.py](file://office/api/image.py#L21-L35) + +### 图片加水印 + +给图片添加自定义文本水印。 + +```python +import office + +office.image.add_watermark( + file='photo.jpg', + mark='@python-office' +) +``` + +**关键参数说明:** + +- `file`: 图片文件路径 +- `mark`: 水印内容 +- `output_path`: 输出路径(默认当前目录) +- `color`: 水印颜色(默认 `#eaeaea`) +- `opacity`: 不透明度(默认 0.35) + +**Section sources** + +- [office/api/image.py](file://office/api/image.py#L58-L78) +- [examples/poimage/图片加水印.py](file://examples/poimage/图片加水印.py) + +### 生成词云 + +根据文本文件生成词云图像。 + +```python +import office + +office.image.txt2wordcloud( + filename='article.txt', + result_file='wordcloud.png' +) +``` + +**关键参数说明:** + +- `filename`: 文本文件路径 +- `color`: 词云背景色(默认 `white`) +- `result_file`: 输出词云图片路径 + +**Section sources** + +- [office/api/image.py](file://office/api/image.py#L131-L145) + +### 生成二维码 + +生成二维码图片。 + +```python +import office + +office.tools.qrcodetools( + url='https://www.python-office.com', + output='qrcode.png' +) +``` + +**关键参数说明:** + +- `url`: 用于生成二维码的 URL 地址 +- `output`: 二维码图片保存路径(默认 `./qrcode_img.png`) + +**Section sources** + +- [office/api/tools.py](file://office/api/tools.py#L40-L52) + +### Excel模拟数据 + +自动创建 Excel 文件并填充模拟数据。 + +```python +import office + +office.excel.fake2excel( + columns=['name', 'phone'], + rows=1000, + path='test.xlsx' +) +``` + +**关键参数说明:** + +- `columns`: 列名列表,支持 name、phone、email 等多种类型 +- `rows`: 生成的行数 +- `path`: 输出 Excel 文件路径 +- `language`: 数据语言(默认 `zh_CN` 中文,可选 `english`) + +**Section sources** + +- [office/api/excel.py](file://office/api/excel.py#L39-L55) +- [examples/poexcel/批量模拟数据.py](file://examples/poexcel/批量模拟数据.py) + +### 批量重命名文件 + +批量修改文件/文件夹名称。 + +```python +import office + +office.file.replace4filename( + path='./test_dir', + del_content='old', + replace_content='new' +) +``` + +**关键参数说明:** + +- `path`: 需要修改文件名称的根目录 +- `del_content`: 需要替换的内容 +- `replace_content`: 替换后的内容(不填则实现删除效果) + +**Section sources** + +- [office/api/file.py](file://office/api/file.py#L44-L61) + +### 微信发送消息 + +通过微信机器人发送消息给指定联系人。 + +```python +import office + +office.wechat.send_message( + who='文件传输助手', + message='Hello from python-office!' +) +``` + +**注意事项:** 此功能仅支持 Windows 环境,需要桌面微信已登录且 PyOfficeRobot 已安装。 + +**Section sources** + +- [office/api/wechat.py](file://office/api/wechat.py#L32-L45) + +## Skills 系统快速上手 + +python-office 内置 73 个 Skill,每个 Skill 可独立导入: + +```python +# 方式 1:直接导入 Skill +from skills.pdf import pdf2docx +pdf2docx(input_file='report.pdf', output_file='report.docx') + +# 方式 2:导入分类模块 +from skills.image import compress_image +compress_image(input_file='big.jpg', output_file='small.jpg', quality=30) + +# 方式 3:传统 office 风格(仍然可用) +import office +office.image.compress_image(input_file='big.jpg', output_file='small.jpg', quality=30) +``` + +每个 Skill 目录下都有 `SKILL.md` 文件,详细说明参数、返回值和使用示例,可被 AI 工具自动识别。 + +**Section sources** + +- [README.md](file://README.md#L97-L135) +- [skills/README.md](file://skills/README.md#L1-L50) + +## 常见注意事项 + +1. **文件路径处理**:建议使用绝对路径或基于 `os.path` 的相对路径构造,避免因工作目录不同导致文件找不到。 +2. **跨平台兼容性**:poword(Word处理)、poppt(PPT处理)、PyOfficeRobot(微信机器人)仅支持 Windows,macOS/Linux 首次运行会看到兼容性提示。 +3. **参数弃用**:部分函数支持新旧参数名共存,使用旧参数会触发 DeprecationWarning,建议迁移到新参数名。 +4. **子库独立安装**:如果只需特定功能,可以单独安装对应子库(如 `pip install popdf`),减少依赖体积。 +5. **Windows 专用功能延迟加载**:wechat、word 等模块在非 Windows 环境下不会导致 `import office` 失败,但调用对应功能时会报错。 + +**Section sources** + +- [office/compatibility.py](file://office/compatibility.py#L40-L72) +- [office/api/wechat.py](file://office/api/wechat.py#L19-L29) + +## 总结 + +通过本快速入门教程,您已掌握了 `python-office` 库的核心功能。从安装验证到 PDF 转换、图片压缩、Excel 模拟数据、微信发消息等操作,每个功能都提供了简洁的 API 和可直接运行的示例代码。 + +建议您从 `examples/` 目录中的示例开始,逐个运行并修改参数,以加深理解。随着实践的深入,您将能够高效地完成各种办公自动化任务。 + +**Section sources** + +- [README.md](file://README.md#L157-L180) +- [examples/](file://examples/) + diff --git "a/.qoder/repowiki/zh/content/\345\277\253\351\200\237\345\274\200\345\247\213.md" "b/wiki/zh/content/\345\277\253\351\200\237\345\274\200\345\247\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\345\277\253\351\200\237\345\274\200\345\247\213.md" rename to "wiki/zh/content/\345\277\253\351\200\237\345\274\200\345\247\213.md" diff --git "a/wiki/zh/content/\346\211\271\351\207\217\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\211\271\351\207\217\345\244\204\347\220\206.md" new file mode 100644 index 00000000..4a513570 --- /dev/null +++ "b/wiki/zh/content/\346\211\271\351\207\217\345\244\204\347\220\206.md" @@ -0,0 +1,311 @@ +# 批量处理 + + +**本文引用的文件** +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/file.py](file://office/api/file.py) +- [office/api/image.py](file://office/api/image.py) +- [office/compatibility.py](file://office/compatibility.py) +- [setup.cfg](file://setup.cfg) + + +## 目录 +1. [简介](#简介) +2. [批量处理架构](#批量处理架构) +3. [PDF 批量处理](#pdf-批量处理) +4. [Excel 批量处理](#excel-批量处理) +5. [文件管理批量处理](#文件管理批量处理) +6. [图片批量处理](#图片批量处理) +7. [批量处理最佳实践](#批量处理最佳实践) +8. [故障排查](#故障排查) + +## 简介 +python-office 通过"单文件参数 + 目录参数"双模式设计,在同一个 API 函数中同时支持单文件和批量处理。用户只需将 `input_file` 替换为 `input_path`(目录路径),即可自动批量处理目录下所有匹配文件。 + +## 批量处理架构 + +```mermaid +graph TB +USER["用户调用"] --> CHECK{"input_file
还是 input_path?"} +CHECK -->|input_file| SINGLE["单文件模式"] +CHECK -->|input_path| BATCH["批量模式"] +SINGLE --> SUB1["子库单文件接口
如: popdf.pdf2docx()"] +BATCH --> SUB2["子库批量接口
如: popdf.pdf2docx(input_path=...)"] +SUB1 --> OUT1["单个输出文件"] +SUB2 --> SCAN["扫描目录文件"] +SCAN --> LOOP["遍历每个文件"] +LOOP --> PROC["调用子库处理"] +PROC --> PROGRESS["显示进度条"] +PROGRESS --> LOOP +LOOP --> OUT2["批量输出到目录"] +``` + +**图表来源** +- [office/api/pdf.py](file://office/api/pdf.py#L48-L80) +- [office/api/excel.py](file://office/api/excel.py#L1-L30) + +## PDF 批量处理 + +### 支持批量处理的 PDF 函数 + +| 函数 | 单文件参数 | 批量参数 | 说明 | +|------|-----------|---------|------| +| `pdf2docx` | `input_file`, `output_file` | `input_path`, `output_path` | PDF 转 Word | +| `encrypt4pdf` | `input_file`, `output_file` | `input_path`, `output_path` | PDF 加密 | +| `decrypt4pdf` | `input_file`, `output_file` | `input_path`, `output_path` | PDF 解密 | +| `pdf2imgs` | `input_file`, `output_file` | — | PDF 转图片 | +| `del4pdf` | `input_file`, `output_file` | `input_path`, `output_path` | 删除指定页 | + +### 使用示例 + +#### 批量 PDF 转 Word +```python +import office + +# 批量转换目录下所有 PDF 为 Word +office.pdf.pdf2docx( + input_path='./pdf_files/', + output_path='./word_output/' +) +``` + +#### 批量 PDF 加密 +```python +import office + +# 批量加密目录下所有 PDF +office.pdf.encrypt4pdf( + input_path='./pdf_files/', + output_path='./encrypted/', + password='123456' +) +``` + +#### 批量 PDF 解密 +```python +import office + +# 批量解密目录下所有 PDF +office.pdf.decrypt4pdf( + input_path='./encrypted/', + output_path='./decrypted/', + password='123456' +) +``` + +### 批量处理流程 + +```mermaid +sequenceDiagram +participant U as "用户" +participant API as "office.api.pdf" +participant SUB as "popdf" +participant FS as "文件系统" +U->>API : pdf2docx(input_path='./pdfs/', output_path='./docs/') +API->>SUB : popdf.pdf2docx(input_path, output_path) +SUB->>FS : 扫描 ./pdfs/ 目录 +FS-->>SUB : 返回 PDF 文件列表 +loop 遍历每个文件 + SUB->>SUB : 调用 pdf2docx 转换单个文件 + SUB->>FS : 写入输出到 ./docs/ +end +SUB-->>API : 批量处理完成 +API-->>U : 返回 +``` + +**图表来源** +- [office/api/pdf.py](file://office/api/pdf.py#L48-L80) + +## Excel 批量处理 + +### 支持批量处理的 Excel 函数 + +| 函数 | 参数 | 说明 | +|------|------|------| +| `merge2excel` | `dir_path`, `output_file` | 合并目录下所有 Excel 到一个文件 | +| `merge2sheet` | `dir_path` | 合并目录下所有 Excel 到同一个 Sheet | +| `sheet2excel` | `file_path` | 将 Excel 的多个 Sheet 拆分为独立文件 | +| `split_excel_by_column` | `filepath`, `column` | 按列值拆分 Excel | +| `find_excel_data` | `search_key`, `target_dir` | 在目录下搜索 Excel 数据 | + +### 使用示例 + +#### 批量合并 Excel +```python +import office + +# 合并目录下所有 Excel 文件 +office.excel.merge2excel( + dir_path='./excel_files/', + output_file='merged.xlsx' +) +``` + +#### 按列拆分 Excel +```python +import office + +# 按第6列的值拆分 Excel +office.excel.split_excel_by_column( + filepath='data.xlsx', + column=6 +) +``` + +#### 批量搜索 Excel 数据 +```python +import office + +# 在目录下所有 Excel 中搜索关键词 +office.excel.find_excel_data( + search_key='程序员晚枫', + target_dir='./excel_files/' +) +``` + +**图表来源** +- [office/api/excel.py](file://office/api/excel.py#L1-L80) + +## 文件管理批量处理 + +### 支持批量处理的文件管理函数 + +| 函数 | 参数 | 说明 | +|------|------|------| +| `replace4filename` | `main_path`, `del_content`, `replace_content` | 批量替换文件名 | +| `get_files` | `path`, `file_type` | 获取目录下指定类型文件 | +| `file_name_add_prefix` | `file_path`, `prefix` | 批量添加前缀 | +| `file_name_add_postfix` | `file_path`, `postfix` | 批量添加后缀 | +| `search_by_content` | `search_content`, `search_dir` | 按内容搜索文件 | + +### 使用示例 + +#### 批量重命名文件 +```python +import office + +# 将目录下所有文件名中的"副本"替换为"正式" +office.file.replace4filename( + main_path='./files/', + del_content='副本', + replace_content='正式' +) +``` + +#### 获取目录下指定类型文件 +```python +import office + +# 获取目录下所有 PDF 文件 +files = office.file.get_files( + path='./documents/', + file_type='pdf' +) +``` + +**图表来源** +- [office/api/file.py](file://office/api/file.py#L1-L50) + +## 图片批量处理 + +### 支持批量处理的图片函数 + +| 函数 | 参数 | 说明 | +|------|------|------| +| `compress_image` | `input_file`, `output_file` | 图片压缩(需循环调用实现批量) | +| `add_watermark` | `input_file`, `mark_str`, `output_file` | 图片加水印 | +| `del_watermark` | `input_file`, `output_file` | 图片去水印 | + +### 批量压缩图片示例 +```python +import office +from office.api.file import get_files + +# 批量压缩目录下所有图片 +image_files = get_files(path='./images/', file_type='jpg') +for img in image_files: + office.image.compress_image( + input_file=f'./images/{img}', + output_file=f'./compressed/{img}' + ) +``` + +**图表来源** +- [office/api/image.py](file://office/api/image.py#L1-L50) + +## 批量处理最佳实践 + +### 1. 输出目录管理 +```python +import os + +# 批量处理前确保输出目录存在 +output_dir = './output/' +os.makedirs(output_dir, exist_ok=True) +``` + +### 2. 错误处理 +```python +import office +import logging + +# 批量处理时捕获单个文件错误,不影响整体流程 +try: + office.pdf.pdf2docx( + input_path='./pdfs/', + output_path='./docs/' + ) +except Exception as e: + logging.error(f"批量处理出错: {e}") +``` + +### 3. 进度监控 +python-office 的子库内部使用 `poprogress` 显示进度条,用户无需额外处理: +```python +# 调用批量接口时自动显示进度条 +office.pdf.encrypt4pdf( + input_path='./pdfs/', + output_path='./encrypted/', + password='123456' +) +# 输出示例: +# [████████████████████████] 15/30 files (50%) +``` + +### 4. 内存管理 +对于大文件批量处理,建议分批执行: +```python +import office +from office.api.file import get_files + +# 分批处理大量文件 +all_pdfs = get_files(path='./large_dir/', file_type='pdf') +batch_size = 50 + +for i in range(0, len(all_pdfs), batch_size): + batch = all_pdfs[i:i+batch_size] + for pdf in batch: + try: + office.pdf.pdf2docx( + input_file=f'./large_dir/{pdf}', + output_file=f'./output/{pdf.replace(".pdf", ".docx")}' + ) + except Exception as e: + print(f"处理 {pdf} 失败: {e}") +``` + +## 故障排查 + +| 问题 | 原因 | 解决方案 | +|------|------|---------| +| 批量处理只处理了部分文件 | 目录中包含非目标类型文件 | 使用 `get_files()` 预先筛选文件 | +| 输出目录不存在 | 子库未自动创建输出目录 | 提前 `os.makedirs(output_path, exist_ok=True)` | +| 内存不足 | 大文件批量处理占用过多内存 | 分批处理,每批 50-100 个文件 | +| 进度条不显示 | 终端不支持或 poprogress 未安装 | `pip install poprogress` | +| 权限错误 | 输出目录无写入权限 | 检查目录权限,使用 `chmod` 修改 | +| 跨平台问题 | Windows 专用模块在非 Windows 系统 | 检查兼容性提示,使用替代方案 | + +**图表来源** +- [office/compatibility.py](file://office/compatibility.py#L40-L72) +- [setup.cfg](file://setup.cfg#L19-L41) diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/AI\351\233\206\346\210\220.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/AI\351\233\206\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/AI\351\233\206\346\210\220.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/AI\351\233\206\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\346\240\270\345\277\203\345\233\276\345\203\217\346\223\215\344\275\234.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\346\240\270\345\277\203\345\233\276\345\203\217\346\223\215\344\275\234.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\346\240\270\345\277\203\345\233\276\345\203\217\346\223\215\344\275\234.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\346\240\270\345\277\203\345\233\276\345\203\217\346\223\215\344\275\234.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\351\253\230\347\272\247\345\233\276\345\203\217\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\351\253\230\347\272\247\345\233\276\345\203\217\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\351\253\230\347\272\247\345\233\276\345\203\217\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206/\351\253\230\347\272\247\345\233\276\345\203\217\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\350\247\206\351\242\221\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\350\247\206\351\242\221\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\350\247\206\351\242\221\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\345\244\232\345\252\222\344\275\223\345\244\204\347\220\206/\350\247\206\351\242\221\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\344\273\266\347\256\241\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\344\273\266\347\256\241\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\344\273\266\347\256\241\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\344\273\266\347\256\241\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Excel\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Excel\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Excel\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Excel\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PDF\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PDF\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PDF\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PDF\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PPT\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PPT\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PPT\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/PPT\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Word\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Word\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Word\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/Word\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/\346\226\207\346\241\243\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/\346\226\207\346\241\243\345\244\204\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/\346\226\207\346\241\243\345\244\204\347\220\206.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\226\207\346\241\243\345\244\204\347\220\206/\346\226\207\346\241\243\345\244\204\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\231\272\350\203\275\350\257\206\345\210\253.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\231\272\350\203\275\350\257\206\345\210\253.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\231\272\350\203\275\350\257\206\345\210\253.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\231\272\350\203\275\350\257\206\345\210\253.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\240\270\345\277\203\345\212\237\350\203\275.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\240\270\345\277\203\345\212\237\350\203\275.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\240\270\345\277\203\345\212\237\350\203\275.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\346\240\270\345\277\203\345\212\237\350\203\275.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\217\221\351\200\201\346\266\210\346\201\257.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\217\221\351\200\201\346\266\210\346\201\257.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\217\221\351\200\201\346\266\210\346\201\257.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\217\221\351\200\201\346\266\210\346\201\257.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\256\232\346\227\266\345\217\221\351\200\201\346\266\210\346\201\257.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\256\232\346\227\266\345\217\221\351\200\201\346\266\210\346\201\257.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\256\232\346\227\266\345\217\221\351\200\201\346\266\210\346\201\257.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\256\232\346\227\266\345\217\221\351\200\201\346\266\210\346\201\257.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\226\207\344\273\266\344\274\240\350\276\223.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\226\207\344\273\266\344\274\240\350\276\223.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\226\207\344\273\266\344\274\240\350\276\223.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\226\207\344\273\266\344\274\240\350\276\223.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\231\272\350\203\275\350\201\212\345\244\251\346\234\272\345\231\250\344\272\272.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\231\272\350\203\275\350\201\212\345\244\251\346\234\272\345\231\250\344\272\272.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\231\272\350\203\275\350\201\212\345\244\251\346\234\272\345\231\250\344\272\272.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\231\272\350\203\275\350\201\212\345\244\251\346\234\272\345\231\250\344\272\272.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\266\210\346\201\257\346\216\245\346\224\266.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\266\210\346\201\257\346\216\245\346\224\266.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\266\210\346\201\257\346\216\245\346\224\266.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\346\266\210\346\201\257\346\216\245\346\224\266.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\347\276\244\345\217\221\346\266\210\346\201\257.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\347\276\244\345\217\221\346\266\210\346\201\257.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\347\276\244\345\217\221\346\266\210\346\201\257.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226/\347\276\244\345\217\221\346\266\210\346\201\257.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241.md" diff --git "a/.qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226.md" rename to "wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275/\350\207\252\345\212\250\345\214\226\351\200\232\344\277\241/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226.md" diff --git "a/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/Excel\345\244\204\347\220\206/Excel\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/Excel\345\244\204\347\220\206/Excel\345\244\204\347\220\206.md" new file mode 100644 index 00000000..06964ff6 --- /dev/null +++ "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/Excel\345\244\204\347\220\206/Excel\345\244\204\347\220\206.md" @@ -0,0 +1,122 @@ +# Excel 处理 + + +**本文档中引用的文件** +- [office/api/excel.py](file://office/api/excel.py) +- [examples/poexcel/批量模拟数据.py](file://examples/poexcel/批量模拟数据.py) +- [examples/poexcel/合并多个Excel到一个Excel的不同sheet中.py](file://examples/poexcel/合并多个Excel到一个Excel的不同sheet中.py) +- [examples/poexcel/同一个excel里的不同sheet,拆分为不同的excel文件.py](file://examples/poexcel/同一个excel里的不同sheet,拆分为不同的excel文件.py) +- [examples/poexcel/Excel转PDF.py](file://examples/poexcel/Excel转PDF.py) + + +## 目录 +1. [简介](#简介) +2. [功能列表](#功能列表) +3. [数据模拟](#数据模拟) +4. [文件合并与拆分](#文件合并与拆分) +5. [内容搜索](#内容搜索) +6. [格式转换](#格式转换) + +## 简介 + +python-office 的 Excel 处理模块(`office.excel`)基于 poexcel 库,提供 7 个功能,覆盖 Excel 数据模拟、文件合并拆分、内容搜索、格式转换等场景。 + +## 功能列表 + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 模拟数据 | `fake2excel` | 自动创建 Excel 并填充模拟数据 | +| 合并到不同 Sheet | `merge2excel` | 多个 Excel 合并到一个文件的不同 sheet | +| Sheet 拆分 | `sheet2excel` | 同一 Excel 不同 sheet 拆分为不同文件 | +| 合并到同一 Sheet | `merge2sheet` | 多个 Excel 的多个 sheet 自动合并 | +| 内容搜索 | `find_excel_data` | 搜索 Excel 中指定内容 | +| 按列拆分 | `split_excel_by_column` | 按指定列的内容拆分 Excel | +| Excel 转 PDF | `excel2pdf` | 将 Excel 工作表转换为 PDF | + +## 数据模拟 + +### fake2excel +自动创建 Excel 文件并填充模拟数据,基于 Faker 库实现。 + +```python +import office + +office.excel.fake2excel( + columns=['name', 'phone', 'email'], + rows=1000, + path='test.xlsx', + language='zh_CN' +) +``` + +**参数说明:** +- `columns`: 列名列表,支持 name、phone、email、address 等多种类型 +- `rows`: 生成的行数 +- `path`: 输出 Excel 文件路径 +- `language`: 数据语言(`zh_CN` 中文 / `english` 英文) + +## 文件合并与拆分 + +### merge2excel — 合并到不同 Sheet +将目录下多个 Excel 文件合并到一个 Excel 文件的不同 sheet 中。 + +```python +office.excel.merge2excel(dir_path='./my_excels', output_file='all.xlsx') +``` + +### sheet2excel — Sheet 拆分 +将同一个 Excel 里的不同 sheet 拆分为不同的 Excel 文件。 + +```python +office.excel.sheet2excel(file_path='multi_sheet.xlsx', output_path='./output/') +``` + +### merge2sheet — 合并到同一 Sheet +将多个 Excel 文件的多个 sheet 自动合并到同一个 sheet。 + +```python +office.excel.merge2sheet( + dir_path='./my_excels', + output_sheet_name='Sheet1', + output_excel_name='merge2sheet' +) +``` + +### split_excel_by_column — 按列拆分 +按指定列的内容拆分 Excel 文件。 + +```python +office.excel.split_excel_by_column( + filepath='data.xlsx', + column=2, + worksheet_name='Sheet1' +) +``` + +## 内容搜索 + +### find_excel_data +搜索 Excel 中指定内容的文件、行数、内容详情。 + +```python +office.excel.find_excel_data( + search_key='张三', + target_dir='./excels/' +) +``` + +## 格式转换 + +### excel2pdf +将 Excel 文件的指定工作表转换为 PDF 格式。 + +```python +office.excel.excel2pdf( + excel_path='report.xlsx', + pdf_path='report.pdf', + sheet_id=0 +) +``` + +**Section sources** +- [office/api/excel.py](file://office/api/excel.py#L1-L163) diff --git "a/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/PDF\345\244\204\347\220\206/PDF\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/PDF\345\244\204\347\220\206/PDF\345\244\204\347\220\206.md" new file mode 100644 index 00000000..f0af74cf --- /dev/null +++ "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/PDF\345\244\204\347\220\206/PDF\345\244\204\347\220\206.md" @@ -0,0 +1,184 @@ +# PDF 处理 + + +**本文档中引用的文件** +- [office/api/pdf.py](file://office/api/pdf.py) +- [examples/popdf/pdf转word.py](file://examples/popdf/pdf转word.py) +- [examples/popdf/pdf转图片.py](file://examples/popdf/pdf转图片.py) +- [examples/popdf/PDF加密.py](file://examples/popdf/PDF加密.py) +- [examples/popdf/PDF解密.py](file://examples/popdf/PDF解密.py) +- [examples/popdf/合并PDF.py](file://examples/popdf/合并PDF.py) +- [examples/popdf/TXT转PDF.py](file://examples/popdf/TXT转PDF.py) +- [examples/popdf/PDF加水印.py](file://examples/popdf/PDF加水印.py) + + +## 目录 +1. [简介](#简介) +2. [功能架构](#功能架构) +3. [PDF 转换功能](#pdf-转换功能) +4. [PDF 安全功能](#pdf-安全功能) +5. [PDF 编辑功能](#pdf-编辑功能) +6. [PDF 组织功能](#pdf-组织功能) +7. [参数兼容机制](#参数兼容机制) + +## 简介 + +python-office 的 PDF 处理模块(`office.pdf`)基于 popdf 库,提供 13 个功能,覆盖 PDF 转 Word、PDF 转图片、文本转 PDF、PDF 拆分、加密/解密、添加水印、合并、删除页面等常见操作。 + +## 功能架构 + +```mermaid +graph TD +A[office.pdf API] --> B[popdf 子库] +B --> C[PyMuPDF] +B --> D[PyPDF2] +B --> E[pdf2docx] +A --> F[PDF 转换] +A --> G[PDF 安全] +A --> H[PDF 编辑] +A --> I[PDF 组织] +F --> F1[pdf2docx] +F --> F2[pdf2imgs] +F --> F3[txt2pdf] +G --> G1[encrypt4pdf] +G --> G2[decrypt4pdf] +H --> H1[add_text_watermark] +H --> H2[add_img_water] +H --> H3[add_mark] +I --> I1[split4pdf] +I --> I2[merge2pdf] +I --> I3[del4pdf] +``` + +## PDF 转换功能 + +### PDF 转 Word +将 PDF 转换为 .docx 文件,底层基于 pdf2docx 库。 + +```python +import office +office.pdf.pdf2docx(input_file='report.pdf', output_file='report.docx') +``` + +### PDF 转图片 +将 PDF 每页转换为图片,支持合并为一张长图。 + +```python +# 分页模式 +office.pdf.pdf2imgs(input_file='report.pdf', output_file='./images/') + +# 合并模式 +office.pdf.pdf2imgs(input_file='report.pdf', output_file='output.jpg', merge=True) +``` + +### 文本转 PDF +将 .txt 文件转换为 PDF 格式。 + +```python +office.pdf.txt2pdf(input_file='notes.txt', output_file='notes.pdf') +``` + +## PDF 安全功能 + +### PDF 加密 +为 PDF 文件设置密码保护。 + +```python +office.pdf.encrypt4pdf(password='123456', input_file='doc.pdf', output_file='encrypted.pdf') +``` + +### PDF 解密 +移除 PDF 密码保护。 + +```python +office.pdf.decrypt4pdf(password='123456', input_file='encrypted.pdf', output_file='decrypted.pdf') +``` + +## PDF 编辑功能 + +### 添加文本水印 +在 PDF 指定位置添加文本水印。 + +```python +office.pdf.add_text_watermark( + input_file='doc.pdf', + point=(100, 100), + text='机密文件', + output_file='watermarked.pdf', + fontsize=24, + color=(0.5, 0.5, 0.5) +) +``` + +### 添加图片水印 +给 PDF 添加图片水印。 + +```python +office.pdf.add_img_water( + input_file='doc.pdf', + mark_file='logo.png', + output_file='watermarked.pdf' +) +``` + +### 参数化添加水印 +通过参数方式添加水印到 PDF。 + +```python +office.pdf.add_watermark_by_parameters( + input_file='doc.pdf', + mark_str='python-office', + output_path='./output/', + output_file='watermarked.pdf' +) +``` + +## PDF 组织功能 + +### PDF 拆分 +按页码范围提取 PDF 内容。 + +```python +office.pdf.split4pdf(input_file='book.pdf', output_file='chapter1.pdf', from_page=1, to_page=10) +``` + +### 合并 PDF +将多个 PDF 文件合并为一个。 + +```python +office.pdf.merge2pdf( + input_file_list=['file1.pdf', 'file2.pdf', 'file3.pdf'], + output_file='merged.pdf' +) +``` + +### 删除页面 +从 PDF 中删除指定页码的页面。 + +```python +office.pdf.del4pdf(input_file='doc.pdf', output_file='cleaned.pdf', page_nums=[2, 4]) +``` + +## 参数兼容机制 + +python-office 的 PDF 模块支持新旧参数名共存,旧参数会触发 `DeprecationWarning`: + +```mermaid +flowchart TD +A["函数调用"] --> B{"使用旧参数?"} +B -->|是| C["触发 DeprecationWarning"] +C --> D["映射到新参数"] +B -->|否| E["直接使用新参数"] +D --> F["转发到 popdf"] +E --> F +``` + +| 新参数 | 旧参数(已弃用) | 函数 | +|--------|-----------------|------| +| `input_file` | `file_path` / `pdf_path` | pdf2docx / pdf2imgs | +| `output_file` | `output` / `output_file_name` | merge2pdf / add_mark | +| `input_file` | `pdf_file_in` | add_img_water | +| `mark_file` | `pdf_file_mark` | add_img_water | + +**Section sources** +- [office/api/pdf.py](file://office/api/pdf.py#L1-L434) diff --git "a/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/\345\233\276\347\211\207\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/\345\233\276\347\211\207\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206.md" new file mode 100644 index 00000000..337e157e --- /dev/null +++ "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/\345\233\276\347\211\207\345\244\204\347\220\206/\345\233\276\347\211\207\345\244\204\347\220\206.md" @@ -0,0 +1,150 @@ +# 图片处理 + + +**本文档中引用的文件** +- [office/api/image.py](file://office/api/image.py) +- [examples/poimage/图片加水印.py](file://examples/poimage/图片加水印.py) +- [examples/poimage/图片去水印.py](file://examples/poimage/图片去水印.py) +- [examples/poimage/文本转词云.py](file://examples/poimage/文本转词云.py) +- [examples/poimage/下载图片.py](file://examples/poimage/下载图片.py) + + +## 目录 +1. [简介](#简介) +2. [功能列表](#功能列表) +3. [图片压缩](#图片压缩) +4. [水印处理](#水印处理) +5. [风格转换](#风格转换) +6. [其他功能](#其他功能) + +## 简介 + +python-office 的图片处理模块(`office.image`)基于 poimage 库,提供 9 个功能,覆盖图片压缩、水印添加/去除、风格转换、词云生成、二维码解析等场景。 + +## 功能列表 + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 图片压缩 | `compress_image` | 压缩图片,减小文件大小 | +| 图片加水印 | `add_watermark` | 给图片添加文本水印 | +| 图片去水印 | `del_watermark` | 去除图片水印 | +| 生成词云 | `txt2wordcloud` | 根据文本生成词云图 | +| 铅笔画风格 | `pencil4img` | 将图片转换为铅笔画风格 | +| 卡通风格 | `img2Cartoon` | 将图片转换为卡通风格 | +| 下载图片 | `down4img` | 从 URL 下载图片 | +| 解析二维码 | `decode_qrcode` | 解析二维码图片内容 | +| 图片转 GIF | `image2gif` | 将图片转换为 GIF 格式 | + +## 图片压缩 + +### compress_image +压缩图片文件大小,同时尽量保持视觉质量。 + +```python +import office + +office.image.compress_image( + input_file='big.jpg', + output_file='small.jpg', + quality=30 +) +``` + +**参数说明:** +- `input_file`: 输入图片路径 +- `output_file`: 压缩后图片保存路径 +- `quality`: 压缩质量(0-95),数值越高越好但文件越大 + +## 水印处理 + +### add_watermark — 添加水印 +给图片添加文本水印,支持自定义颜色、大小、透明度、角度等。 + +```python +office.image.add_watermark( + file='photo.jpg', + mark='@python-office', + output_path='./', + color="#eaeaea", + size=30, + opacity=0.35, + space=200, + angle=30 +) +``` + +### del_watermark — 去除水印 +从图片中去除水印。 + +```python +office.image.del_watermark( + input_image='watermarked.jpg', + output_image='clean.jpg' +) +``` + +## 风格转换 + +### txt2wordcloud — 生成词云 +根据文本文件生成词云图像。 + +```python +office.image.txt2wordcloud( + filename='article.txt', + color='white', + result_file='wordcloud.png' +) +``` + +### pencil4img — 铅笔画风格 +将图片转换为铅笔画风格。 + +```python +office.image.pencil4img( + input_img='photo.jpg', + output_path='./', + output_name='pencil.jpg' +) +``` + +### img2Cartoon — 卡通风格 +将图片转换为卡通风格,基于百度 API。 + +```python +office.image.img2Cartoon( + path='photo.jpg', + client_api='your_api_key', + client_secret='your_secret' +) +``` + +## 其他功能 + +### down4img — 下载图片 +从 URL 下载图片并保存到指定路径。 + +```python +office.image.down4img( + url='https://example.com/image.jpg', + output_path='./', + output_name='downloaded', + type='jpg' +) +``` + +### decode_qrcode — 解析二维码 +解析二维码图片内容。 + +```python +office.image.decode_qrcode(qrcode_path='qrcode.png') +``` + +### image2gif — 图片转 GIF +将图片转换为 GIF 格式。 + +```python +office.image.image2gif() +``` + +**Section sources** +- [office/api/image.py](file://office/api/image.py#L1-L202) diff --git "a/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243.md" "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243.md" new file mode 100644 index 00000000..1b3cbd6f --- /dev/null +++ "b/wiki/zh/content/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243/\346\240\270\345\277\203\345\212\237\350\203\275\350\257\246\350\247\243.md" @@ -0,0 +1,248 @@ +# 核心功能详解 + + +**本文档中引用的文件** +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/image.py](file://office/api/image.py) +- [office/api/word.py](file://office/api/word.py) +- [office/api/file.py](file://office/api/file.py) +- [office/api/tools.py](file://office/api/tools.py) +- [office/api/video.py](file://office/api/video.py) +- [office/api/wechat.py](file://office/api/wechat.py) +- [office/api/finance.py](file://office/api/finance.py) +- [office/api/ocr.py](file://office/api/ocr.py) +- [office/api/markdown.py](file://office/api/markdown.py) + + +## 目录 +1. [简介](#简介) +2. [功能架构](#功能架构) +3. [PDF 处理功能](#pdf-处理功能) +4. [Excel 处理功能](#excel-处理功能) +5. [图片处理功能](#图片处理功能) +6. [Word 处理功能](#word-处理功能) +7. [文件管理功能](#文件管理功能) +8. [视频处理功能](#视频处理功能) +9. [微信自动化功能](#微信自动化功能) +10. [工具类功能](#工具类功能) +11. [金融计算功能](#金融计算功能) +12. [最佳实践建议](#最佳实践建议) + +## 简介 + +python-office 是一个专为 Python 自动化办公设计的多功能聚合库,覆盖 PDF、Excel、图片、Word、PPT、视频、微信、文件管理、工具类、金融计算、OCR、Markdown 等 13 个分类、73 个功能。通过简洁的 API 设计,用户可以轻松实现各种办公自动化任务。 + +## 功能架构 + +python-office 采用"API 聚合层 → 子库 → 第三方依赖"的分层架构。API 聚合层提供用户友好的函数接口,子库负责具体功能实现,第三方依赖提供底层能力。 + +```mermaid +graph TD +A[API 聚合层 office.api.*] --> B[子库生态] +B --> C[第三方依赖] +A -->|pdf| B1[popdf] +A -->|excel| B2[poexcel] +A -->|image| B3[poimage] +A -->|word| B4[poword] +A -->|file| B5[pofile] +A -->|tools| B6[wftools] +A -->|video| B7[povideo] +A -->|wechat| B8[PyOfficeRobot] +A -->|finance| B9[内置实现] +A -->|ocr| B10[poocr] +A -->|markdown| B11[pomarkdown] +B1 --> C1[PyMuPDF / PyPDF2] +B2 --> C2[openpyxl / Faker] +B3 --> C3[Pillow] +B7 --> C7[ffmpeg / you-get] +``` + +**Diagram sources** +- [office/__init__.py](file://office/__init__.py#L1-L30) +- [setup.cfg](file://setup.cfg#L21-L41) + +## PDF 处理功能 + +python-office 的 PDF 处理模块(`office.pdf`)基于 popdf 库,提供 13 个功能: + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| PDF 转 Word | `pdf2docx` | 将 PDF 转换为 .docx 文件 | +| PDF 转图片 | `pdf2imgs` | 将 PDF 每页转换为图片,支持合并为一张 | +| 文本转 PDF | `txt2pdf` | 将 .txt 文件转换为 PDF | +| PDF 拆分 | `split4pdf` | 按页码范围提取 PDF 内容 | +| PDF 加密 | `encrypt4pdf` | 为 PDF 设置密码保护 | +| PDF 解密 | `decrypt4pdf` | 移除 PDF 密码保护 | +| 添加文本水印 | `add_text_watermark` | 在 PDF 指定位置添加文本水印 | +| 合并 PDF | `merge2pdf` | 将多个 PDF 合并为一个文件 | +| 删除页面 | `del4pdf` | 删除 PDF 中指定页码的页面 | +| 添加图片水印 | `add_img_water` | 给 PDF 添加图片水印 | +| 添加水印(参数化)| `add_watermark_by_parameters` | 参数化方式添加水印 | +| 添加水印(交互)| `add_mark` | 添加水印到 PDF | + +```mermaid +sequenceDiagram +participant 用户 +participant API as office.pdf +participant popdf +participant 第三方库 +用户->>API : 调用 office.pdf.pdf2docx() +API->>API : 参数兼容性处理 +API->>popdf : 转发调用 +popdf->>第三方库 : 调用 pdf2docx 库 +第三方库-->>popdf : 返回转换结果 +popdf-->>API : 返回状态 +API-->>用户 : 返回执行结果 +``` + +**Section sources** +- [office/api/pdf.py](file://office/api/pdf.py#L1-L434) + +## Excel 处理功能 + +Excel 处理模块(`office.excel`)基于 poexcel 库,提供 7 个功能: + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 模拟数据 | `fake2excel` | 自动创建 Excel 并填充模拟数据 | +| 合并到不同 Sheet | `merge2excel` | 多个 Excel 合并到一个文件的不同 sheet | +| Sheet 拆分 | `sheet2excel` | 同一 Excel 不同 sheet 拆分为不同文件 | +| 合并到同一 Sheet | `merge2sheet` | 多个 Excel 的多个 sheet 自动合并 | +| 内容搜索 | `find_excel_data` | 搜索 Excel 中指定内容 | +| 按列拆分 | `split_excel_by_column` | 按指定列的内容拆分 Excel | +| Excel 转 PDF | `excel2pdf` | 将 Excel 工作表转换为 PDF | + +**Section sources** +- [office/api/excel.py](file://office/api/excel.py#L1-L163) + +## 图片处理功能 + +图片处理模块(`office.image`)基于 poimage 库,提供 9 个功能: + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 图片压缩 | `compress_image` | 压缩图片,减小文件大小 | +| 图片加水印 | `add_watermark` | 给图片添加文本水印 | +| 图片去水印 | `del_watermark` | 去除图片水印 | +| 生成词云 | `txt2wordcloud` | 根据文本生成词云图 | +| 铅笔画风格 | `pencil4img` | 将图片转换为铅笔画风格 | +| 卡通风格 | `img2Cartoon` | 将图片转换为卡通风格 | +| 下载图片 | `down4img` | 从 URL 下载图片 | +| 解析二维码 | `decode_qrcode` | 解析二维码图片内容 | +| 图片转 GIF | `image2gif` | 将图片转换为 GIF 格式 | + +**Section sources** +- [office/api/image.py](file://office/api/image.py#L1-L202) + +## Word 处理功能 + +Word 处理模块(`office.word`)基于 poword 库,提供 5 个功能(仅 Windows): + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| Word 转 PDF | `docx2pdf` | 将 Word 文档转换为 PDF | +| 合并 Word | `merge4docx` | 合并多个 Docx 文件 | +| Doc 转 Docx | `doc2docx` | 将 .doc 转换为 .docx | +| Docx 转 Doc | `docx2doc` | 将 .docx 转换为 .doc | +| 提取图片 | `docx4imgs` | 从 Word 文档中提取图片 | + +**Section sources** +- [office/api/word.py](file://office/api/word.py#L1-L119) + +## 文件管理功能 + +文件管理模块(`office.file`)基于 pofile 库,提供 9 个功能: + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 批量重命名 | `replace4filename` | 批量修改文件/文件夹名称 | +| 插入字符 | `file_name_insert_content` | 在文件名中间插入字符 | +| 添加前缀 | `file_name_add_prefix` | 给文件名添加前缀 | +| 添加后缀 | `file_name_add_postfix` | 给文件名添加后缀 | +| 整理到 Excel | `output_file_list_to_excel` | 将文件名整理到 Excel | +| 搜索文件 | `search_specify_type_file` | 搜索指定类型文件 | +| 按名分组 | `group_by_name` | 按名称分组整理文件 | +| 获取文件列表 | `get_files` | 搜索指定类型文件并返回列表 | +| 按类型添加行 | `add_line_by_type` | 根据文件类型添加行内容 | + +**Section sources** +- [office/api/file.py](file://office/api/file.py#L1-L198) + +## 视频处理功能 + +视频处理模块(`office.video`)基于 povideo 库,提供 4 个功能: + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 视频转 MP3 | `video2mp3` | 从视频中提取音频 | +| 音频转文字 | `audio2txt` | 从音频中提取文字(语音识别) | +| 视频加水印 | `mark2video` | 给视频添加水印 | +| 文本转语音 | `txt2mp3` | 将文本转换为语音 MP3 | + +**Section sources** +- [office/api/video.py](file://office/api/video.py#L1-L98) + +## 微信自动化功能 + +微信自动化模块(`office.wechat`)基于 PyOfficeRobot 库,提供 7 个功能(仅 Windows): + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 发送消息 | `send_message` | 发送消息给指定联系人 | +| 定时发送 | `send_message_by_time` | 在指定时间发送消息 | +| 关键词聊天 | `chat_by_keywords` | 根据关键词自动聊天 | +| 发送文件 | `send_file` | 发送文件给指定联系人 | +| 群发消息 | `group_send` | 群发消息 | +| 接收消息 | `receive_message` | 接收微信消息并保存 | +| 智能聊天 | `chat_robot` | 智能聊天机器人 | + +**Section sources** +- [office/api/wechat.py](file://office/api/wechat.py#L1-L145) + +## 工具类功能 + +工具类模块(`office.tools`)基于 wftools 库,提供 10 个功能: + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| 翻译 | `transtools` | 多语言翻译 | +| 生成二维码 | `qrcodetools` | 生成二维码图片 | +| 生成密码 | `passwordtools` | 生成指定长度密码 | +| 天气查询 | `weather` | 获取当前天气信息 | +| URL 转 IP | `url2ip` | 将 URL 转换为 IP 地址 | +| 生成彩票 | `lottery8ticket` | 生成 8 位彩票号码 | +| 创建文章 | `create_article` | 自动创建文章 | +| WiFi 密码 | `pwd4wifi` | 生成 WiFi 密码列表 | +| 网速测试 | `net_speed_test` | 测试网络速度 | +| 课程信息 | `course` | 显示课程信息与资源链接 | + +**Section sources** +- [office/api/tools.py](file://office/api/tools.py#L1-L195) + +## 金融计算功能 + +金融计算模块(`office.finance`)内置实现,提供股票 T+0 交易收益计算: + +| 功能 | 函数名 | 说明 | +|------|--------|------| +| T+0 收益计算 | `t0` | 计算做 T 的收益(含手续费、印花税) | + +该模块使用 Python 内置 `decimal` 模块进行精确计算,考虑买入佣金、卖出佣金和印花税。 + +**Section sources** +- [office/api/finance.py](file://office/api/finance.py#L1-L51) + +## 最佳实践建议 + +1. **路径处理**:始终使用绝对路径或确保相对路径正确 +2. **跨平台注意**:Word、PPT、微信功能仅 Windows 可用,首次运行查看兼容性提示 +3. **参数兼容**:使用新参数名,旧参数会触发弃用警告 +4. **按需安装**:只需特定功能时安装对应子库,减少依赖体积 +5. **Skills 系统**:优先使用 Skills 方式导入,便于 AI 工具识别 +6. **错误处理**:关注函数日志输出,使用 loguru 记录的问题信息 +7. **批量操作**:合理设置输出目录,避免文件覆盖 + +**Section sources** +- [office/compatibility.py](file://office/compatibility.py#L40-L72) +- [README.md](file://README.md#L56-L100) diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/AI\351\233\206\346\210\220\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/AI\351\233\206\346\210\220\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/AI\351\233\206\346\210\220\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/AI\351\233\206\346\210\220\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/OCR\346\226\207\345\255\227\350\257\206\345\210\253\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/OCR\346\226\207\345\255\227\350\257\206\345\210\253\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/OCR\346\226\207\345\255\227\350\257\206\345\210\253\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/OCR\346\226\207\345\255\227\350\257\206\345\210\253\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\225\260\346\215\256\345\217\257\350\247\206\345\214\226\344\270\216\350\257\215\344\272\221\347\224\237\346\210\220.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\225\260\346\215\256\345\217\257\350\247\206\345\214\226\344\270\216\350\257\215\344\272\221\347\224\237\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\225\260\346\215\256\345\217\257\350\247\206\345\214\226\344\270\216\350\257\215\344\272\221\347\224\237\346\210\220.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\225\260\346\215\256\345\217\257\350\247\206\345\214\226\344\270\216\350\257\215\344\272\221\347\224\237\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\226\207\346\234\254\346\231\272\350\203\275\345\244\204\347\220\206\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\226\207\346\234\254\346\231\272\350\203\275\345\244\204\347\220\206\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\226\207\346\234\254\346\231\272\350\203\275\345\244\204\347\220\206\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\346\226\207\346\234\254\346\231\272\350\203\275\345\244\204\347\220\206\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\347\275\221\351\241\265\345\206\205\345\256\271\346\217\220\345\217\226\344\270\216\347\224\265\345\255\220\344\271\246\347\224\237\346\210\220.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\347\275\221\351\241\265\345\206\205\345\256\271\346\217\220\345\217\226\344\270\216\347\224\265\345\255\220\344\271\246\347\224\237\346\210\220.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\347\275\221\351\241\265\345\206\205\345\256\271\346\217\220\345\217\226\344\270\216\347\224\265\345\255\220\344\271\246\347\224\237\346\210\220.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/AI\351\233\206\346\210\220\347\244\272\344\276\213/\347\275\221\351\241\265\345\206\205\345\256\271\346\217\220\345\217\226\344\270\216\347\224\265\345\255\220\344\271\246\347\224\237\346\210\220.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\345\244\204\347\220\206\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\345\244\204\347\220\206\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\345\244\204\347\220\206\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\345\244\204\347\220\206\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\346\240\274\345\274\217\350\275\254\346\215\242.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\346\240\274\345\274\217\350\275\254\346\215\242.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\346\240\274\345\274\217\350\275\254\346\215\242.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/Excel\346\240\274\345\274\217\350\275\254\346\215\242.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\210\233\345\273\272Excel\346\226\207\344\273\266.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\210\233\345\273\272Excel\346\226\207\344\273\266.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\210\233\345\273\272Excel\346\226\207\344\273\266.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\210\233\345\273\272Excel\346\226\207\344\273\266.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266Excel\346\226\207\344\273\266.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266Excel\346\226\207\344\273\266.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266Excel\346\226\207\344\273\266.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266Excel\346\226\207\344\273\266.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\344\270\215\345\220\214Sheet.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\344\270\215\345\220\214Sheet.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\344\270\215\345\220\214Sheet.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\344\270\215\345\220\214Sheet.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\345\220\214\344\270\200Sheet.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\345\220\214\344\270\200Sheet.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\345\220\214\344\270\200Sheet.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\345\220\210\345\271\266Excel\346\226\207\344\273\266/\345\220\210\345\271\266\345\210\260\345\220\214\344\270\200Sheet.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\213\206\345\210\206Excel\346\226\207\344\273\266.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\213\206\345\210\206Excel\346\226\207\344\273\266.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\213\206\345\210\206Excel\346\226\207\344\273\266.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\213\206\345\210\206Excel\346\226\207\344\273\266.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\210\227\345\200\274\346\213\206\345\210\206.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\210\227\345\200\274\346\213\206\345\210\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\210\227\345\200\274\346\213\206\345\210\206.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\210\227\345\200\274\346\213\206\345\210\206.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\267\245\344\275\234\350\241\250\346\213\206\345\210\206.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\267\245\344\275\234\350\241\250\346\213\206\345\210\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\267\245\344\275\234\350\241\250\346\213\206\345\210\206.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\213\206\345\210\206Excel\346\226\207\344\273\266/\346\214\211\345\267\245\344\275\234\350\241\250\346\213\206\345\210\206.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\237\245\350\257\242Excel\346\225\260\346\215\256.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\237\245\350\257\242Excel\346\225\260\346\215\256.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\237\245\350\257\242Excel\346\225\260\346\215\256.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/Excel\345\244\204\347\220\206\347\244\272\344\276\213/\346\237\245\350\257\242Excel\346\225\260\346\215\256.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\206\205\345\256\271\345\220\210\345\271\266.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\206\205\345\256\271\345\220\210\345\271\266.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\206\205\345\256\271\345\220\210\345\271\266.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\206\205\345\256\271\345\220\210\345\271\266.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\212\240\346\260\264\345\215\260.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\212\240\346\260\264\345\215\260.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\212\240\346\260\264\345\215\260.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\212\240\346\260\264\345\215\260.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\256\211\345\205\250\346\223\215\344\275\234.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\256\211\345\205\250\346\223\215\344\275\234.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\256\211\345\205\250\346\223\215\344\275\234.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\345\256\211\345\205\250\346\223\215\344\275\234.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\223\215\344\275\234\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\223\215\344\275\234\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\223\215\344\275\234\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\223\215\344\275\234\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\346\240\274\345\274\217\350\275\254\346\215\242.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\346\240\274\345\274\217\350\275\254\346\215\242.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\346\240\274\345\274\217\350\275\254\346\215\242.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\346\240\274\345\274\217\350\275\254\346\215\242.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254Word.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254Word.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254Word.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254Word.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254\345\233\276\347\211\207.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254\345\233\276\347\211\207.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254\345\233\276\347\211\207.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/PDF\350\275\254\345\233\276\347\211\207.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/TXT\350\275\254PDF.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/TXT\350\275\254PDF.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/TXT\350\275\254PDF.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/PDF\346\223\215\344\275\234\347\244\272\344\276\213/PDF\346\240\274\345\274\217\350\275\254\346\215\242/TXT\350\275\254PDF.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\205\266\344\273\226\345\267\245\345\205\267\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\205\266\344\273\226\345\267\245\345\205\267\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\205\266\344\273\226\345\267\245\345\205\267\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\205\266\344\273\226\345\267\245\345\205\267\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\344\270\213\350\275\275.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\344\270\213\350\275\275.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\344\270\213\350\275\275.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\344\270\213\350\275\275.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\212\240\346\260\264\345\215\260.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\212\240\346\260\264\345\215\260.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\212\240\346\260\264\345\215\260.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\212\240\346\260\264\345\215\260.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\213\347\274\251.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\213\347\274\251.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\213\347\274\251.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\213\347\274\251.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\345\233\276\347\211\207\345\216\273\346\260\264\345\215\260.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\346\226\207\346\234\254\350\275\254\350\257\215\344\272\221.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\346\226\207\346\234\254\350\275\254\350\257\215\344\272\221.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\346\226\207\346\234\254\350\275\254\350\257\215\344\272\221.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\233\276\345\203\217\345\244\204\347\220\206\347\244\272\344\276\213/\346\226\207\346\234\254\350\275\254\350\257\215\344\272\221.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/AI\351\233\206\346\210\220\344\270\216\346\231\272\350\203\275\345\257\271\350\257\235.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/AI\351\233\206\346\210\220\344\270\216\346\231\272\350\203\275\345\257\271\350\257\235.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/AI\351\233\206\346\210\220\344\270\216\346\231\272\350\203\275\345\257\271\350\257\235.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/AI\351\233\206\346\210\220\344\270\216\346\231\272\350\203\275\345\257\271\350\257\235.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\237\272\347\241\200\351\200\232\344\277\241\345\212\237\350\203\275.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\237\272\347\241\200\351\200\232\344\277\241\345\212\237\350\203\275.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\237\272\347\241\200\351\200\232\344\277\241\345\212\237\350\203\275.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\237\272\347\241\200\351\200\232\344\277\241\345\212\237\350\203\275.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\205\263\351\224\256\350\257\215\350\207\252\345\212\250\345\233\236\345\244\215.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\256\232\346\227\266\346\266\210\346\201\257\345\217\221\351\200\201.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\256\232\346\227\266\346\266\210\346\201\257\345\217\221\351\200\201.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\256\232\346\227\266\346\266\210\346\201\257\345\217\221\351\200\201.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\345\256\232\346\227\266\346\266\210\346\201\257\345\217\221\351\200\201.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\347\276\244\347\273\204\344\270\216\345\245\275\345\217\213\347\256\241\347\220\206.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\347\276\244\347\273\204\344\270\216\345\245\275\345\217\213\347\256\241\347\220\206.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\347\276\244\347\273\204\344\270\216\345\245\275\345\217\213\347\256\241\347\220\206.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\346\266\210\346\201\257\345\244\204\347\220\206\344\270\216\350\207\252\345\212\250\345\214\226\345\223\215\345\272\224/\347\276\244\347\273\204\344\270\216\345\245\275\345\217\213\347\256\241\347\220\206.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\347\213\254\347\253\213\344\275\277\347\224\250\346\250\241\345\274\217.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\347\213\254\347\253\213\344\275\277\347\224\250\346\250\241\345\274\217.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\347\213\254\347\253\213\344\275\277\347\224\250\346\250\241\345\274\217.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\345\276\256\344\277\241\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213/\347\213\254\347\253\213\344\275\277\347\224\250\346\250\241\345\274\217.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\346\226\207\344\273\266\347\256\241\347\220\206\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\346\226\207\344\273\266\347\256\241\347\220\206\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\346\226\207\344\273\266\347\256\241\347\220\206\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\346\226\207\344\273\266\347\256\241\347\220\206\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\347\244\272\344\276\213\345\244\247\345\205\250.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\347\244\272\344\276\213\345\244\247\345\205\250.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\347\244\272\344\276\213\345\244\247\345\205\250.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\347\244\272\344\276\213\345\244\247\345\205\250.md" diff --git "a/.qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" "b/wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" rename to "wiki/zh/content/\347\244\272\344\276\213\345\244\247\345\205\250/\351\202\256\344\273\266\350\207\252\345\212\250\345\214\226\347\244\272\344\276\213.md" diff --git "a/.qoder/repowiki/zh/content/\350\264\241\347\214\256\346\214\207\345\215\227.md" "b/wiki/zh/content/\350\264\241\347\214\256\346\214\207\345\215\227.md" similarity index 100% rename from ".qoder/repowiki/zh/content/\350\264\241\347\214\256\346\214\207\345\215\227.md" rename to "wiki/zh/content/\350\264\241\347\214\256\346\214\207\345\215\227.md" diff --git "a/wiki/zh/content/\351\241\271\347\233\256\346\246\202\350\277\260.md" "b/wiki/zh/content/\351\241\271\347\233\256\346\246\202\350\277\260.md" new file mode 100644 index 00000000..26d5da06 --- /dev/null +++ "b/wiki/zh/content/\351\241\271\347\233\256\346\246\202\350\277\260.md" @@ -0,0 +1,346 @@ +# 项目概述 + + +**本文引用的文件** +- [README.md](file://README.md) +- [setup.cfg](file://setup.cfg) +- [setup.py](file://setup.py) +- [office/__init__.py](file://office/__init__.py) +- [office/compatibility.py](file://office/compatibility.py) +- [office/api/pdf.py](file://office/api/pdf.py) +- [office/api/excel.py](file://office/api/excel.py) +- [office/api/image.py](file://office/api/image.py) +- [office/api/tools.py](file://office/api/tools.py) +- [office/api/file.py](file://office/api/file.py) +- [office/api/wechat.py](file://office/api/wechat.py) +- [office/api/word.py](file://office/api/word.py) +- [office/api/video.py](file://office/api/video.py) +- [office/api/finance.py](file://office/api/finance.py) +- [skills/README.md](file://skills/README.md) + + +## 目录 +1. [简介](#简介) +2. [项目结构](#项目结构) +3. [核心组件](#核心组件) +4. [架构总览](#架构总览) +5. [详细组件分析](#详细组件分析) +6. [依赖关系分析](#依赖关系分析) +7. [性能与可用性考量](#性能与可用性考量) +8. [故障排查指南](#故障排查指南) +9. [结论](#结论) +10. [附录](#附录) + +## 简介 + +python-office 是中文世界最受欢迎的 Python 办公自动化聚合库,一个库覆盖 90% 的办公场景:PDF/Word/Excel/PPT 转换、图片处理、视频音频、微信机器人、邮件发送、文件管理、OCR 识别、AI 工具等。项目自 2020 年持续维护,累计下载量 40 万+,GitHub Star 1200+,MIT 开源协议。 + +- 官方网站:[python-office.com](https://www.python-office.com/) +- 中文文档:[python4office.cn](https://www.python4office.cn/python-office/profile/) +- 社区交流:README 提供官方微信群二维码与多平台链接 +- 核心理念:零 Python 基础也能用,每个功能只需一行代码 + +项目内置 **Skills 系统**:将 73 个方法封装为 73 个独立可导入的 Skill,每个 Skill 配有 `SKILL.md` 文档,可被 Codex / Claude / Cursor 等 AI 工具自动识别调用。 + +**章节来源** +- file://README.md#L1-L70 + +## 项目结构 + +项目采用"API 聚合层 + Skills 系统层 + 工具库层"的三层组织方式: + +- **API 聚合层**(`office/api/`):对外暴露统一的函数接口,将请求转发给底层子库(popdf、poimage、poexcel 等) +- **Skills 系统层**(`skills/`):将每个方法封装为独立 Skill,支持单独导入和 AI 自动识别 +- **工具库层**:通过依赖独立的子库(popdf、poimage、povideo、poocr 等)实现具体功能 +- **兼容性层**(`office/compatibility.py`):跨平台兼容性检查,首次运行提示 +- **GUI 与示例**:提供桌面 GUI 和丰富的使用示例 + +```mermaid +graph TB +subgraph "API 聚合层" +A1["office/api/pdf.py"] +A2["office/api/excel.py"] +A3["office/api/image.py"] +A4["office/api/tools.py"] +A5["office/api/file.py"] +A6["office/api/wechat.py"] +A7["office/api/word.py"] +A8["office/api/video.py"] +A9["office/api/finance.py"] +end +subgraph "Skills 系统层" +S1["skills/pdf/ (13 Skills)"] +S2["skills/excel/ (7 Skills)"] +S3["skills/image/ (9 Skills)"] +S4["skills/tools/ (10 Skills)"] +S5["skills/file/ (9 Skills)"] +S6["skills/wechat/ (7 Skills)"] +S7["skills/word/ (5 Skills)"] +S8["skills/video/ (4 Skills)"] +end +subgraph "工具库层(外部依赖)" +D1["popdf"] +D2["poexcel"] +D3["poimage"] +D4["pofile"] +D5["wftools"] +D6["povideo"] +D7["PyOfficeRobot"] +D8["poword"] +D9["poocr"] +end +A1 --> D1 +A2 --> D2 +A3 --> D3 +A4 --> D5 +A5 --> D4 +A6 --> D7 +A7 --> D8 +A8 --> D6 +S1 --> A1 +S2 --> A2 +S3 --> A3 +S4 --> A4 +S5 --> A5 +S6 --> A6 +``` + +**图表来源** +- [office/__init__.py](file://office/__init__.py#L1-L30) +- [setup.cfg](file://setup.cfg#L19-L41) +- [skills/README.md](file://skills/README.md#L1-L274) + +**章节来源** +- file://README.md#L56-L100 +- file://setup.cfg#L19-L41 + +## 核心组件 + +- **API 聚合层**:提供统一的 `office.module.method()` 调用方式,13 个模块覆盖 PDF、Excel、图片、Word、PPT、视频、微信、文件、工具、金融、OCR、Markdown、邮件 +- **Skills 系统**:73 个独立可导入的 Skill,每个 Skill 对应一个 `SKILL.md` 文档,支持 AI 工具自动识别 +- **兼容性检查器**:`office/compatibility.py` 中的 `CrossPlatformCompatibility` 类,在非 Windows 系统首次运行时提示功能兼容性 +- **子库生态**:popdf、poimage、poexcel、pofile、povideo、poocr、wftools、poword、poppt、PyOfficeRobot、poemail、pomarkdown、pocode、pospider、poprogress、pohan、potime、search4file + +**章节来源** +- file://office/__init__.py#L1-L30 +- file://office/compatibility.py#L1-L250 +- file://skills/README.md#L1-L274 + +## 架构总览 + +python-office 的整体架构遵循"聚合层 → 子库 → 第三方依赖"的分层设计: + +- API 聚合层作为统一门面,将用户请求转发给对应的子库 +- Skills 系统层为 API 层的薄封装,提供独立导入和 AI 识别能力 +- 子库负责具体功能实现,封装第三方库调用 +- 兼容性检查器在模块导入时自动执行,提供跨平台提示 + +```mermaid +graph TB +subgraph "用户入口" +U1["import office"] +U2["from skills.pdf import pdf2docx"] +end +subgraph "API 聚合层" +API["office.api.*"] +COMPAT["office.compatibility"] +end +subgraph "Skills 系统" +SKILLS["skills///"] +end +subgraph "子库生态" +S1["popdf"] +S2["poexcel"] +S3["poimage"] +S4["pofile"] +S5["wftools"] +S6["povideo"] +S7["PyOfficeRobot"] +S8["poword"] +S9["poocr"] +end +subgraph "第三方依赖" +T1["PyMuPDF / PyPDF2"] +T2["openpyxl / Faker"] +T3["Pillow"] +T4["requests"] +end +U1 --> API +U2 --> SKILLS +SKILLS --> API +API --> S1 +API --> S2 +API --> S3 +API --> S4 +API --> S5 +API --> S6 +API --> S7 +API --> S8 +API --> S9 +S1 --> T1 +S2 --> T2 +S3 --> T3 +COMPAT -.-> API +``` + +**图表来源** +- [office/__init__.py](file://office/__init__.py#L1-L30) +- [setup.cfg](file://setup.cfg#L19-L41) + +## 详细组件分析 + +### API 聚合层:统一门面接口 +- 13 个模块文件,每个模块对应一个功能类别 +- 统一调用方式:`office.module.method()` +- 参数兼容:支持新旧参数名共存,旧参数触发 DeprecationWarning +- 延迟导入:Windows 专用模块(poword、PyOfficeRobot)采用延迟加载,在非 Windows 环境下不报错 + +```mermaid +sequenceDiagram +participant User as "用户" +participant API as "office.api.*" +participant SubLib as "子库 (popdf/poimage/...)" +participant ThirdParty as "第三方库" +User->>API : 调用 office.module.method() +API->>API : 参数校验与兼容性处理 +API->>SubLib : 转发调用到对应子库 +SubLib->>ThirdParty : 调用 PyMuPDF/Pillow 等 +ThirdParty-->>SubLib : 返回处理结果 +SubLib-->>API : 返回状态 +API-->>User : 返回结果 +``` + +**章节来源** +- file://office/api/pdf.py#L1-L434 +- file://office/api/image.py#L1-L202 + +### Skills 系统层:AI 友好的独立 Skill +- 73 个 Skill 分布在 13 个分类目录下 +- 每个 Skill 是一个独立子目录,包含 `__init__.py` 和 `SKILL.md` +- 支持三种导入方式:`from skills.xxx import yyy`、`from office.skills.xxx import yyy`、`import office; office.xxx.yyy()` +- `SKILL.md` 遵循标准格式,包含触发条件、参数说明、使用示例 + +```mermaid +classDiagram +class SkillCategory { + +category_name: str + +skills: list + +get_skill(name) +} +class Skill { + +name: str + +description: str + +SKILL_MD: str + +execute(*args, **kwargs) +} +class PDFFactory { + +pdf2docx() + +pdf2imgs() + +encrypt4pdf() + +decrypt4pdf() + +merge2pdf() +} +class ImageFactory { + +compress_image() + +add_watermark() + +txt2wordcloud() + +pencil4img() +} +SkillCategory --> Skill : 包含 +PDFFactory --|> Skill : 继承 +ImageFactory --|> Skill : 继承 +``` + +**章节来源** +- file://skills/README.md#L1-L274 + +### 兼容性检查器:跨平台支持 +- 首次运行检测:通过标记文件 `~/.python-office/first_run_mark` 判断是否首次运行 +- 平台识别:自动识别 Windows、macOS、Linux +- 功能兼容性分类:完全支持 / 仅 Windows 支持两类 +- 替代方案建议:为非 Windows 用户提供 LibreOffice 等替代方案 + +**章节来源** +- file://office/compatibility.py#L1-L250 + +### GUI 与示例 +- GUI:提供基于 PySide6/PyQt 的桌面应用(PDF 转 Word 工具、Fluent Gallery),位于 `gui/` 目录 +- 示例:`examples/` 目录按子库名分类,提供每个功能的使用示例 + +**章节来源** +- file://README.md#L56-L100 + +## 依赖关系分析 + +- **核心子库**:popdf、poexcel、poimage、pofile、povideo、poocr、wftools、poemail、pomarkdown、pocode、pospider、poprogress +- **Windows 专用子库**:poppt、poword、search4file、PyOfficeRobot(通过 `platform_system=='Windows'` 条件安装) +- **通用依赖**:rich(彩色输出)、loguru(日志)、you-get(视频下载) +- Python 版本要求:>=3.6 + +```mermaid +graph LR +PO["python-office"] --> D1["popdf"] +PO --> D2["poexcel"] +PO --> D3["poimage"] +PO --> D4["pofile"] +PO --> D5["povideo"] +PO --> D6["poocr"] +PO --> D7["wftools"] +PO --> D8["poemail"] +PO --> D9["pomarkdown"] +PO --> D10["pocode"] +PO --> D11["pospider"] +PO --> D12["poprogress"] +PO --> D13["rich"] +PO --> D14["loguru"] +PO --> D15["you-get"] +PO -->|Windows only| W1["poppt"] +PO -->|Windows only| W2["poword"] +PO -->|Windows only| W3["PyOfficeRobot"] +PO -->|Windows only| W4["search4file"] +``` + +**图表来源** +- [setup.cfg](file://setup.cfg#L19-L41) + +**章节来源** +- file://setup.cfg#L19-L41 + +## 性能与可用性考量 + +- **轻量化安装**:用户可只安装需要的子库(如 `pip install popdf`),避免全量安装的依赖膨胀 +- **延迟导入**:Windows 专用模块采用延迟加载策略,避免在非 Windows 环境下导入失败 +- **参数兼容**:新旧参数名共存,旧参数触发 DeprecationWarning,确保向后兼容 +- **跨平台提示**:首次运行自动提示功能兼容性,帮助用户了解平台限制 +- **AI 友好**:Skills 系统使 AI 工具能自动识别并调用正确的方法 + +[本节为通用指导,无需特定文件来源] + +## 故障排查指南 + +- **导入失败**:检查 Python 版本是否 >=3.6,子库是否已安装 +- **Windows 专用功能不可用**:poword、poppt、PyOfficeRobot 仅在 Windows 上可用,macOS/Linux 用户请查看兼容性提示 +- **参数弃用警告**:使用旧参数名会触发 DeprecationWarning,建议迁移到新参数名 +- **依赖冲突**:使用虚拟环境隔离依赖,或只安装需要的子库 +- **微信机器人无法运行**:确保 Windows 环境、桌面微信已登录、PyOfficeRobot 已安装 + +**章节来源** +- file://office/compatibility.py#L1-L250 +- file://office/api/wechat.py#L1-L30 + +## 结论 + +python-office 以聚合层 + Skills 系统的双层设计,为 Python 自动化办公提供了覆盖面最广的一站式解决方案。通过统一的 `import office` 入口,用户可以一行代码完成 PDF 转换、图片压缩、Excel 合并、微信发消息等 73 种常见办公任务。Skills 系统进一步使每个功能可被 AI 工具自动识别调用,代表了办公自动化库的 AI 化方向。 + +**章节来源** +- file://README.md#L1-L70 + +## 附录 +- 安装与使用:README 提供 pip 安装与子库独立安装说明 +- 功能清单:README 列举了 13 个分类、73 个 Skill 的完整索引 +- 社区与贡献:README 提供 issue 与 PR 流程说明,contributors 目录存放贡献者代码 +- Skills 索引:[skills/README.md](file://skills/README.md) 提供完整的 Skill 分类与调用示例 + +**章节来源** +- file://README.md#L56-L100 +- file://skills/README.md#L1-L274 diff --git a/wiki/zh/meta/repowiki-metadata.json b/wiki/zh/meta/repowiki-metadata.json new file mode 100644 index 00000000..7a0883eb --- /dev/null +++ b/wiki/zh/meta/repowiki-metadata.json @@ -0,0 +1,115 @@ +{ + "code_snippets": [ + { + "id": "po_office_init", + "path": "office/__init__.py", + "line_range": "1-30", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_compatibility", + "path": "office/compatibility.py", + "line_range": "1-250", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_image", + "path": "office/api/image.py", + "line_range": "1-202", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_pdf", + "path": "office/api/pdf.py", + "line_range": "1-434", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_excel", + "path": "office/api/excel.py", + "line_range": "1-163", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_tools", + "path": "office/api/tools.py", + "line_range": "1-195", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_file", + "path": "office/api/file.py", + "line_range": "1-198", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_wechat", + "path": "office/api/wechat.py", + "line_range": "1-145", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_word", + "path": "office/api/word.py", + "line_range": "1-119", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_video", + "path": "office/api/video.py", + "line_range": "1-98", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_api_finance", + "path": "office/api/finance.py", + "line_range": "1-51", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_setup_cfg", + "path": "setup.cfg", + "line_range": "1-44", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_setup_py", + "path": "setup.py", + "line_range": "1-14", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_readme", + "path": "README.md", + "line_range": "1-420", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + }, + { + "id": "po_skills_readme", + "path": "skills/README.md", + "line_range": "1-274", + "gmt_create": "2026-07-21T23:37:00+08:00", + "gmt_modified": "2026-07-21T23:37:00+08:00" + } + ], + "project_info": { + "name": "python-office", + "version": "1.0.6", + "language": "zh", + "description": "面向Python自动化办公的多功能聚合库,73个Skill覆盖PDF/Word/Excel/PPT/图片/视频/微信/邮件等场景" + } +}