|
|
|
|
@ -0,0 +1,172 @@
|
|
|
|
|
# python-pptx使用
|
|
|
|
|
### 安装
|
|
|
|
|
```bash
|
|
|
|
|
poetry add python-pptx
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 修改摘要信息,修改模版名称
|
|
|
|
|
```python
|
|
|
|
|
import os
|
|
|
|
|
from pptx import Presentation
|
|
|
|
|
from config import Config
|
|
|
|
|
from pptx.util import Inches
|
|
|
|
|
|
|
|
|
|
def set_slides_prop(ppt_path):
|
|
|
|
|
prs = Presentation(ppt_path)
|
|
|
|
|
|
|
|
|
|
text = "创意素材铺"
|
|
|
|
|
# 设置文档属性
|
|
|
|
|
prs.core_properties.title = text
|
|
|
|
|
prs.core_properties.subject = text
|
|
|
|
|
prs.core_properties.author = text
|
|
|
|
|
prs.core_properties.category = text
|
|
|
|
|
prs.core_properties.keywords = text
|
|
|
|
|
prs.core_properties.comments = text
|
|
|
|
|
|
|
|
|
|
# 保存演示文稿
|
|
|
|
|
prs.save(ppt_path)
|
|
|
|
|
print(f"'{os.path.basename(ppt_path)}'设置属性成功")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def batch_set_slides(directory):
|
|
|
|
|
for filename in os.listdir(directory):
|
|
|
|
|
if filename.endswith(".pptx") or filename.endswith(".ppt"):
|
|
|
|
|
ppt_path = os.path.join(directory, filename)
|
|
|
|
|
set_slides_prop(ppt_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 调用批量删除函数
|
|
|
|
|
batch_set_slides(Config.get_latest_folder(Config.WORK_PATH))
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
# pywin32使用
|
|
|
|
|
|
|
|
|
|
### 安装
|
|
|
|
|
```bash
|
|
|
|
|
poetry add pywin32
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 修改摘要信息,修改模版名称
|
|
|
|
|
```python
|
|
|
|
|
import win32com.client
|
|
|
|
|
|
|
|
|
|
# 连接PowerPoint
|
|
|
|
|
powerpoint = win32com.client.Dispatch("PowerPoint.Application")
|
|
|
|
|
|
|
|
|
|
# 不显示PowerPoint界面
|
|
|
|
|
if powerpoint.Visible != 0:
|
|
|
|
|
powerpoint.Visible = 0
|
|
|
|
|
|
|
|
|
|
# 打开指定文件
|
|
|
|
|
presentation = powerpoint.Presentations.Open("xxx.pptx")
|
|
|
|
|
|
|
|
|
|
# 修改模版名称
|
|
|
|
|
presentation.SlideMaster.Name = "模版名称"
|
|
|
|
|
|
|
|
|
|
# 修改摘要信息
|
|
|
|
|
presentation.BuiltInDocumentProperties("Title").Value = "标题"
|
|
|
|
|
presentation.BuiltInDocumentProperties("Author").Value = "作者"
|
|
|
|
|
presentation.BuiltInDocumentProperties("Subject").Value = "主题"
|
|
|
|
|
presentation.BuiltInDocumentProperties("Keywords").Value = "关键字"
|
|
|
|
|
presentation.BuiltInDocumentProperties("Comments").Value = "摘要信息"
|
|
|
|
|
# BuiltInDocumentProperties 断点调试无法查看所有属性问题
|
|
|
|
|
for item in presentation.BuiltInDocumentProperties:
|
|
|
|
|
print(item.Name, item.Value)
|
|
|
|
|
|
|
|
|
|
# 保存文件
|
|
|
|
|
presentation.Save()
|
|
|
|
|
|
|
|
|
|
# 关闭文件
|
|
|
|
|
presentation.Close()
|
|
|
|
|
|
|
|
|
|
# 退出PowerPoint
|
|
|
|
|
powerpoint.Quit()
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
----
|
|
|
|
|
----
|
|
|
|
|
# presentation.BuiltInDocumentProperties("Title").Value = '新标题' 这句代码可以成功修改,但是在断点调试的时候为什么无法看到Title属性
|
|
|
|
|
|
|
|
|
|
在使用 `win32com.client` 操作 PowerPoint 的 `BuiltInDocumentProperties` 时,虽然在代码中可以通过 `presentation.BuiltInDocumentProperties("Title").Value = '新标题'` 成功修改属性,但在 **断点调试时无法直接看到 `Title` 属性**,这是由以下原因导致的:
|
|
|
|
|
|
|
|
|
|
### **1. 动态 COM 对象的限制**
|
|
|
|
|
`win32com.client` 生成的 COM 对象是 **动态派发(Late Binding)** 的,Python 调试器(如 VS Code、PyCharm)无法直接识别这些动态属性。具体表现:
|
|
|
|
|
- **调试器中看不到完整属性列表**:`BuiltInDocumentProperties` 是一个动态集合,调试器只能显示基础的 COM 接口方法(如 `Item`, `Count`),而无法显示具体的属性名(如 `Title`, `Author`)。
|
|
|
|
|
- **属性需通过字符串名称访问**:调试时无法像普通 Python 对象那样直接通过 `.` 访问属性(如 `obj.Title`),必须用 `Item("Title")` 或 `("Title")` 语法。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### **2. 如何验证属性存在?**
|
|
|
|
|
#### **方法 1:遍历所有属性(调试时可用)**
|
|
|
|
|
在调试器中执行以下代码片段,查看所有内置属性:
|
|
|
|
|
```python
|
|
|
|
|
props = presentation.BuiltInDocumentProperties
|
|
|
|
|
for i in props:
|
|
|
|
|
print(f"{i.Name}: {i.Value}")
|
|
|
|
|
```
|
|
|
|
|
这会输出类似以下内容:
|
|
|
|
|
```
|
|
|
|
|
Title: 新标题
|
|
|
|
|
Author: 张三
|
|
|
|
|
Subject: 年度报告
|
|
|
|
|
...
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### **方法 2:直接访问属性(需知道名称)**
|
|
|
|
|
在调试器中手动测试:
|
|
|
|
|
```python
|
|
|
|
|
# 检查属性是否存在
|
|
|
|
|
has_title = hasattr(presentation.BuiltInDocumentProperties, "Title") # 可能返回 False(动态属性无法被 hasattr 识别)
|
|
|
|
|
title_value = presentation.BuiltInDocumentProperties("Title").Value # 实际可运行
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### **3. 为什么代码能运行但调试器看不到?**
|
|
|
|
|
- **COM 动态接口**:PowerPoint 的 COM 对象在运行时通过 IDispatch 接口动态解析属性名称,调试器无法静态分析这些属性。
|
|
|
|
|
- **Python 的 `dir()` 限制**:调试器依赖 `dir(obj)` 获取对象属性列表,但 `win32com` 动态对象不会返回完整的属性名。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### **4. 解决方案**
|
|
|
|
|
#### **(1) 调试时显式打印属性**
|
|
|
|
|
在代码中添加临时调试语句:
|
|
|
|
|
```python
|
|
|
|
|
print([prop.Name for prop in presentation.BuiltInDocumentProperties])
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### **(2) 使用 `makepy` 生成静态接口**
|
|
|
|
|
运行以下命令生成静态包装类(提升调试体验):
|
|
|
|
|
```bash
|
|
|
|
|
python -m win32com.client.makepy "Microsoft PowerPoint 16.0 Object Library"
|
|
|
|
|
```
|
|
|
|
|
生成后,调试器可能能识别更多属性(但部分动态属性仍不可见)。
|
|
|
|
|
|
|
|
|
|
#### **(3) 查阅官方文档**
|
|
|
|
|
参考 [Microsoft Office 文档属性列表](https://docs.microsoft.com/en-us/office/vba/api/powerpoint.documentproperties) 确认支持的属性名。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### **5. 示例:安全的属性修改**
|
|
|
|
|
```python
|
|
|
|
|
def safe_modify_property(doc_props, name, value):
|
|
|
|
|
try:
|
|
|
|
|
doc_props.Item(name).Value = value
|
|
|
|
|
print(f"修改成功: {name} -> {value}")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"修改失败(属性可能不存在或只读): {name} - {e}")
|
|
|
|
|
|
|
|
|
|
# 调用示例
|
|
|
|
|
safe_modify_property(presentation.BuiltInDocumentProperties, "Title", "新标题")
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### **总结**
|
|
|
|
|
- **代码能运行但调试器看不到属性**:这是 `win32com` 动态 COM 对象的正常行为。
|
|
|
|
|
- **验证属性**:通过遍历 `BuiltInDocumentProperties` 或直接访问属性名(字符串形式)。
|
|
|
|
|
- **调试技巧**:添加打印语句或使用 `makepy` 生成静态接口。
|
|
|
|
|
|
|
|
|
|
如果问题仍存在,可能是 PowerPoint 版本差异导致属性名不同(如 `"Title"` 在某些语言版本中可能是本地化名称)。
|