[亲妈版]Python批量将PPT转换为PPTX

前言:

本文基于Python语言环境实现,以及vsCode工具开发完成,可以支持ppt转pptx 或 pptx转ppt pdf png 等格式。

正式开发:

1、安装reportlab模块

#安装reportlab模块
pip3 install reportlab

2、安装win32com模块

第一种:

pip3 install pywin32

第二种:

python -m pip install --upgrade pip -i https://pypi.douban.com/simple

3、创建pptToPptx.py

import os
import logging

from reportlab.lib.pagesizes import A4, landscape
from reportlab.pdfgen import canvas
import win32com.client

logger = logging.getLogger('Sun')
logging.basicConfig(level=20,
                    # format="[%(name)s][%(levelname)s][%(asctime)s] %(message)s",
                    format="[%(levelname)s][%(asctime)s] %(message)s",
                    datefmt='%Y-%m-%d %H:%M:%S'  # 注意月份和天数不要搞乱了,这里的格式化符与time模块相同
                    )


def getFiles(dir, suffix, ifsubDir=True):  # 查找根目录,文件后缀
    res = []
    for root, directory, files in os.walk(dir):  # =>当前根,根下目录,目录下的文件
        for filename in files:
            name, suf = os.path.splitext(filename)  # =>文件名,文件后缀
            if suf.upper() == suffix.upper():
                res.append(os.path.join(root, filename))  # =>吧一串字符串组合成路径
        if False is ifsubDir:
            break
    return res


class pptTrans:
    def __init__(self, infoDict, filePath):
        self.infoDict = infoDict
        self.filePath = filePath
        self.powerpoint = None

        self.init_powerpoint()
        self.convert_files_in_folder(self.filePath)
        self.quit()
        os.system('pause')

    def quit(self):
        if None is not self.powerpoint:
            self.powerpoint.Quit()

    def init_powerpoint(self):
        try:
            self.powerpoint = win32com.client.DispatchEx("Powerpoint.Application")
            self.powerpoint.Visible = 2
        except Exception as e:
            logger.error(str(e))

    def ppt_trans(self, inputFileName):
        # https://docs.microsoft.com/en-us/office/vba/api/powerpoint.ppsaveasfiletype

        infoDict = self.infoDict
        formatType = infoDict['formatType']
        outputFileName = self.getNewFileName(infoDict['name'], inputFileName)

        if '' == outputFileName:
            return
        inputFileName = inputFileName.replace('/', '\\')
        outputFileName = outputFileName.replace('/', '\\')
        if '' == outputFileName:
            return
        if None is self.powerpoint:
            return
        powerpoint = self.powerpoint
        logger.info('开始转换:[{0}]'.format(inputFileName))
        deck = powerpoint.Presentations.Open(inputFileName)

        try:
            deck.SaveAs(outputFileName, formatType)  # formatType = 32 for ppt to pdf
            logger.info('转换完成:[{0}]'.format(outputFileName))
        except Exception as e:
            logger.error(str(e))
        deck.Close()

    def convert_files_in_folder(self, filePath):
        if True is os.path.isdir(filePath):
            dirPath = filePath
            files = os.listdir(dirPath)
            pptfiles = [f for f in files if f.endswith((".ppt", ".pptx"))]
        elif True is os.path.isfile(filePath):
            pptfiles = [filePath]
        else:
            self.logError('不是文件夹,也不是文件')
            return

        for pptfile in pptfiles:
            fullpath = os.path.join(filePath, pptfile)
            self.ppt_trans(fullpath)

    def getNewFileName(self, newType, filePath):
        try:
            dirPath = os.path.dirname(filePath)
            baseName = os.path.basename(filePath)
            dirPath += "/pptx"
            fileName = baseName.rsplit('.', 1)[0]
            suffix = baseName.rsplit('.', 1)[1]
            if newType == suffix:
                logger.warning('文档[{filePath}]类型和需要转换的类型[{newType}]相同'.format(filePath=filePath, newType=newType))
                return ''
            newFileName = '{dir}/{fileName}.{suffix}'.format(dir=dirPath, fileName=fileName, suffix=newType)
            if os.path.exists(newFileName):
                newFileName = '{dir}/{fileName}_new.{suffix}'.format(dir=dirPath, fileName=fileName, suffix=newType)
            return newFileName
        except Exception as e:
            logger.error(str(e))
            return ''


class pngstoPdf:
    def __init__(self, infoDict, filePath):
        self.infoDict = infoDict
        self.powerpoint = None

        self.init_powerpoint()
        self.convert_files_in_folder(filePath)
        self.quit()
        os.system('pause')

    def quit(self):
        if None is not self.powerpoint:
            self.powerpoint.Quit()

    def init_powerpoint(self):
        try:
            self.powerpoint = win32com.client.DispatchEx("Powerpoint.Application")
            self.powerpoint.Visible = 2
        except Exception as e:
            logger.error(str(e))

    def ppt_trans(self, inputFileName):
        # https://docs.microsoft.com/en-us/office/vba/api/powerpoint.ppsaveasfiletype
        infoDict = self.infoDict
        formatType = infoDict['formatType']
        outputFileName = self.getNewFolderName(inputFileName)

        if '' == outputFileName:
            return ''
        inputFileName = inputFileName.replace('/', '\\')
        outputFileName = outputFileName.replace('/', '\\')
        if '' == outputFileName:
            return ''
        if None is self.powerpoint:
            return ''
        powerpoint = self.powerpoint
        logger.info('开始转换:[{0}]'.format(inputFileName))
        deck = powerpoint.Presentations.Open(inputFileName)

        try:
            deck.SaveAs(outputFileName, formatType)
            logger.info('转换完成:[{0}]'.format(outputFileName))
        except Exception as e:
            logger.error(str(e))
            return ''
        deck.Close()
        return outputFileName

    def convert_files_in_folder(self, filePath):
        if True is os.path.isdir(filePath):
            dirPath = filePath
            files = os.listdir(dirPath)
            pptfiles = [f for f in files if f.endswith((".ppt", ".pptx"))]
        elif True is os.path.isfile(filePath):
            pptfiles = [filePath]
        else:
            self.logError('不是文件夹,也不是文件')
            return

        for pptfile in pptfiles:
            fullpath = os.path.join(filePath, pptfile)
            folderName = self.ppt_trans(fullpath)
            try:
                self.png_to_pdf(folderName)
            except Exception as e:
                logger.error(str(e))
            for file in os.listdir(folderName):
                os.remove('{0}\\{1}'.format(folderName, file))
            os.rmdir(folderName)

    def png_to_pdf(self, folderName):
        picFiles = getFiles(folderName, '.png')
        pdfName = self.getFileName(folderName)

        '''多个图片合成一个pdf文件'''
        (w, h) = landscape(A4)  #
        cv = canvas.Canvas(pdfName, pagesize=landscape(A4))
        for imagePath in picFiles:
            cv.drawImage(imagePath, 0, 0, w, h)
            cv.showPage()
        cv.save()

    def getFileName(self, folderName):
        dirName = os.path.dirname(folderName)
        folder = os.path.basename(folderName)
        return '{0}\\{1}.pdf'.format(dirName, folder)

    def getNewFolderName(self, filePath):
        index = 0
        try:
            dirPath = os.path.dirname(filePath)
            baseName = os.path.basename(filePath)
            fileName = baseName.rsplit('.', 1)[0]

            newFileName = '{dir}/{fileName}'.format(dir=dirPath, fileName=fileName)
            while True:
                if os.path.exists(newFileName):
                    newFileName = '{dir}/{fileName}({index})'.format(dir=dirPath, fileName=fileName, index=index)
                    index = index + 1
                else:
                    break
            return newFileName
        except Exception as e:
            logger.error(str(e))
            return ''

if __name__ == "__main__":
    transDict = {}
    transDict.update({1: {'name': 'pptx', 'formatType': 11}})
    transDict.update({2: {'name': 'ppt', 'formatType': 1}})
    transDict.update({3: {'name': 'pdf', 'formatType': 32}})
    transDict.update({4: {'name': 'png', 'formatType': 18}})
    transDict.update({5: {'name': 'pdf(不可编辑)', 'formatType': 18}})

    hintStr = ''
    for key in transDict:
        hintStr = '{src}{key}:->{type}\n'.format(src=hintStr, key=key, type=transDict[key]['name'])

    while True:
        print(hintStr)
        transFerType = int(input("转换类型:"))
        if None is transDict.get(transFerType):
            logger.error('未知类型')
        else:
            infoDict = transDict[transFerType]
            path = input("文件路径:")
            if 5 == transFerType:
                pngstoPdf(infoDict, path)
            else:
                op = pptTrans(infoDict, path)

4、运行Py文件

第一种:cmd运行

找到文件目录输入:python pptToPptx.py

第二种:VSCode软件,配置python环境,运行

5、选择序号,输入文件夹路径即可。

6、到所输入文件夹路径下的pptx文件下查看所有转换成功的文件

7、完成,有帮助,记得点赞,感谢!

感谢借鉴文章作者:https://developer.aliyun.com/...

行之稳,为之楠!

124 声望
23 粉丝
0 条评论
推荐阅读
【亲妈版】FTP连接Linux服务器一站式步骤
一、搭建linux服务器1、安装 vsftpd登录 Linux 服务器,执行以下命令,安装 vsftpd。yum install vsftpd -y2、启动服务执行以下命令,启动服务。systemctl start vsftpd3、验证vsftpd服务是否启动netstat -tunlp...

稳之楠阅读 401

MongoDB 插入时间与更新时间(create_time/update_time)
MongoDB 在数据库层面不能像 MySQL 一样设置自动创建 create_time/update_time,自动更新 update_time

qbit阅读 13.8k评论 2

LiteFlow PPT 2.0发布!PPT我们也是在认真迭代的
上次的PPT是基于2.8.5版本,而在之后,LiteFlow又随即发了2.9.0的大版本,进行了诸多特性的增加。而PPT一直未进行相应的更新。

铂赛东阅读 732

封面图
Python3 全能安装详解
小编今天折腾了一天,整个Python3 人工智能开发包。卡在pip 包管理器上大半天。找遍大部分资料,就搞不懂为嘛每篇文章就只写一个片面的知识点就不能汇总一下嘛。下面来啦,小编来整理一下,避免下次找不到了。微...

叶剑飞雪阅读 675

python3调用 prometheus API
{代码...}

台湾省委书记阅读 615

封面图
Linux下Python3.9任意目录快速编译安装和配置上手实用指南
本文叙述在Linux Centos7系统下,在任意非标准目录(意味着不需要root或sudo权限)通过官方源码包编译安装Python3.9的快速安装指南。

apollo008阅读 541

2022 年度推荐工具-表格转换瑞士军刀
在工作或学习中,有时我们需要将表格数据转换为其他格式,以便于进一步处理或分享。这时,我们就需要一款能够快速完成这些转换的工具。这款表格转换工具正是这样一款实用的工具。它支持8 种导入格式,包括 Excel...

raosz阅读 477

封面图

行之稳,为之楠!

124 声望
23 粉丝
宣传栏