文章目录
- 简介
- 基本操作
- 封装工具类
简介
可以操作.ppt&.pptx文件
必须在windows平台,必须安装MS Office或WPS
conda create -n pptdeal python=3.7
conda activate pptdeal
pip install pypiwin32
基本操作
# 1. 调用PPT程序
# 调用Microsoft PPT,不显示警告
pptCOM = DispatchEx("PowerPoint.Application")
pptCOM.DisplayAlerts = 0
...
# 关闭调用
pptCOM.Quit()
# 调用WPS PPT,不显示警告
pptCOM = DispatchEx("kwpp.Application")
pptCOM.DisplayAlerts = 0
...
# 关闭调用
pptCOM.Quit()
# 2. 文档操作模板【所有path使用绝对路径,不能使用相对路径】
# 打开已有文档【必须save或saveAs,否则PPT程序将中断并询问是否保存,python端将发生错误】
ppt = pptCOM.Presentations.Open(ppt_path)
...
# 保存
ppt.Save()
# 关闭
ppt.Close()
# 打开已有文档【必须save或saveAs,否则PPT程序将中断并询问是否保存,python端将发生错误】
ppt = pptCOM.Presentations.Open(ppt_path)
...
# 另存为
ppt.SaveAs()
# 关闭
ppt.Close()
# 新建文档 【ppt中必须存在内容否则将报错失败,可以通过Copy&Paste或InsertFromFile等操作获得】
# 【必须saveAs,否则PPT程序将中断并询问是否保存,python端将发生错误】
ppt = pptCOM.Presentations.Add()
...
# 另存为
ppt.SaveAs(ppt_path)
# 关闭
ppt.Close()
# 3. 常用文档操作【所有path使用绝对路径,不能使用相对路径】【所有的index从1开始】
# 当前ppt页数
print(ppt.Slides.Count)
# 删除页
ppt.Slides(page_index).Delete()
# 从其他文档中添加【源文档路径、目标文档插入位置(0为最前,ppt.Slides.Count为最后),从源文档插入的起始页码,从源文档插入的终止页码】
# 【添加仅限文字和图片等,并没有保留源文档的模板格式】
ppt.Slides.InsertFromFile(source_ppt_path, insert_index, start, end)
# 复制粘贴,将粘贴到ppt的最后【粘贴仅限文字和图片等,并没有保留源文档的模板格式】
source_ppt.Slides(page_index).Copy()
ppt.Slides.Paste()
封装工具类
# ms_office_tool.py
from shutil import copyfile
import os
from win32com.client import DispatchEx
def splitAndMergePPT(pathList, savePath, pageList, pptx):
"""
截取PPT
将第一个文件复制并删除无用的页,将第二个及之后的文件欲截取的页加入到该文件中,这样可以使用第一个PPT的背景模板
若新建PPT,将所有需要的页粘贴进来则丢掉了背景模板
调用示例:
# 或pptx = DispatchEx("kwpp.Application"),调用wps版本的PowerPoint
pptx = DispatchEx("PowerPoint.Application")
pptx.DisplayAlerts = 0
pptx.Visible = 1
splitAndMergePPT('1.ppt', 'sp1.ppt', '5-10', pptx)
splitAndMergePPT(['1.ppt', '1.ppt'], 'sp2.ppt', ['5-10', '15-20'], pptx)
splitAndMergePPT(['1.ppt', '2.ppt'], 'sp3.ppt', ['5-10', '15-20'], pptx)
pptx.Quit()
:param pathList: PPT路径列表(str/str list)
:param savePath: PPT结果保存位置
:param pageList: 欲截取的PPT片段起止页码列表(str/str list),格式为'开始页码-截止页码'(从1开始),
开始页码/截止页码需使用整数
:param pptx: ppt应用操作句柄
:return: 空
"""
# 若为str,转为str list
if isinstance(pathList, str):
pathList = [pathList]
if isinstance(pageList, str):
pageList = [pageList]
# 解析并标准化起止页码,标准格式为int类型
startList = []
endList = []
for item in pageList:
t = item.split('-')
startList.append(int(t[0]))
endList.append(int(t[1]))
# 将第一个文件复制并删除无用的页
copyfile(pathList[0], savePath)
if ':' in savePath:
pptnew = pptx.Presentations.Open(savePath)
else:
pptnew = pptx.Presentations.Open(os.path.join(os.getcwd(), savePath))
for i in range(startList[0] - 1):
pptnew.Slides(1).Delete()
num = endList[0] - startList[0] + 1
cnt = pptnew.Slides.Count
while cnt != num:
pptnew.Slides(pptnew.Slides.Count).Delete()
cnt = cnt - 1
# 将第二个及之后的文件欲截取的页加入到该文件中
for item, start, end in zip(pathList[1:], startList[1:], endList[1:]):
if ':' not in savePath:
item = os.path.join(os.getcwd(), item)
pptnew.Slides.InsertFromFile(item, pptnew.Slides.Count, start, end)
# 保存并关闭
pptnew.Save()
pptnew.Close()
if __name__ == '__main__':
# 测试splitAndMergePPT
pptx = DispatchEx("PowerPoint.Application")
pptx.DisplayAlerts = 0
pptx.Visible = 1
splitAndMergePPT('../test_data/1.ppt', '../test_data/sp1.ppt', '5-10', pptx)
splitAndMergePPT(['../test_data/1.ppt', '../test_data/1.ppt'], '../test_data/sp2.ppt', ['5-10', '15-20'], pptx)
splitAndMergePPT(['../test_data/1.ppt', '../test_data/2.ppt'], '../test_data/sp3.ppt', ['5-10', '15-20'], pptx)
pptx.Quit()
exit()