PDF转PPTX

从PPTX转PDF的方式很多,通过ppt自带的工具即可实现快速而精确的转换。但从PDF转PPTX的转换却缺乏简单便捷的方式。

该问题的需求在于:

  • ppt编辑公式比较繁琐,且需要花费大量的时间用来调节字体等格式,且不美观

  • latex编辑公式较为方便,但生成的PDF与课堂白板sewoo并不兼容,无法很好地利用画笔在课件上进行标记,给授课带来不遍。

一个简单的想法是看看有无现有的工具将PDF直接导出为PPTX,但发现无论是adobe acrobat还是foxit pdf reader,亦或者PDF24 tools均喜欢做额外的工作,进行OCR识别,效果还不甚理想。直接转化为图片再拼接成PPTX不香么!多此一举!

好在PDF24 tools可以将PDF拆分成图片,而PPT又可以很方便地导入图片。

image
image

这种方式可以有效地解决我的需求。但我想更简单点,有没有一键完成的可能?

最初的想法是使用VBA,随后导出为exe可执行程序。但缺乏现有的教程指导。随后查询Github,找到了几个pdf转png的项目,结合网上的部分资源,耗时一个晚上,实现了一键tex->pdf->pngs->pptx的工作流。


# python

# windows

# pyinstaller -i pdf2pptx.ico --add-data=".\default.pptx;." -F -w pdf2pptx.py

# macOS

# pyinstaller -i pdf2pptx.ico --add-data=".\default.pptx:." -F  pdf2pptx.py

# pipenv 下打包缩小体积

# pip install pyinstaller pymupdf python-pptx PyPDF2

import fitz # pip install  pymupdf

import os

import sys

import shutil

import pptx #pip install python-pptx

import PyPDF2

#生成资源文件目录访问路径

def resource_path(relative_path):

    if getattr(sys, 'frozen', False): #是否Bundle Resource

        base_path = sys._MEIPASS

    else:

        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

def pdf2pptx(pdf_name,zoom):

    # pdf2pngs

    pdf_name=os.path.abspath(pdf_name)

    if pdf_name[-4:].lower() == '.pdf':

        dir_name = os.path.dirname(pdf_name) # 获得地址的父链接

        base_name = os.path.basename(pdf_name)[0:-4] # 获得地址的文件名

        path = dir_name + os.sep + base_name

        if not os.path.exists(path):

            os.makedirs(path)

        with open(pdf_name,'rb') as f:

            pdfwidth=PyPDF2.PdfFileReader(f).getPage(0).mediaBox[2]

            pdfheight=PyPDF2.PdfFileReader(f).getPage(0).mediaBox[3]

        pdfscale=pdfheight/pdfwidth

        pdfmode = 0

        if pdfscale > 0.74 and pdfscale < 0.76:

            pdfmode = 0

        elif pdfscale > 0.5 and pdfscale < 0.6:

            pdfmode = 1

        else:

            pdfmode = -1

        pdf = fitz.open(pdf_name)

        # pdfwidth=pdf[0].get_images()[0][2]

        # pdfheight=pdf[0].get_images()[0][3]

        # pdfscale=pdfheight/pdfwidth

        # pdfmode = 0

        # if pdfscale > 0.74 and pdfscale < 0.76:

        #    pdfmode = 0

        # elif pdfscale > 0.5 and pdfscale < 0.6:

        #    pdfmode = 1

        # else:

        #    pdfmode = -1

        for pg in range(0, pdf.pageCount):

            page = pdf[pg]  # 获得每一页的对象

            trans = fitz.Matrix(zoom, zoom).preRotate(0)

            pm = page.getPixmap(matrix=trans, alpha=False)  # 获得每一页的流对象

            pm.writePNG(path + os.sep + base_name + '_' + '{:0>3d}.{}'.format(pg+1, 'png'))  # 保存图片

        pdf.close()

        print('PDF转PNG成功!')

    # pngs2pptx

        pngs=os.listdir(path+os.sep)

        template=resource_path(os.path.join("default.pptx"))

        prs=pptx.Presentation(template)

        if pdfmode == 0:

            prs.slide_width = pptx.util.Inches(4)

            prs.slide_height = pptx.util.Inches(3)

        elif pdfmode == 1:

            prs.slide_width = pptx.util.Inches(16)

            prs.slide_height = pptx.util.Inches(9)

        else:

            print('请采用标准格式!')

            prs.slide_width = pptx.util.Inches(4)

            prs.slide_height = pptx.util.Inches(3)

        layout=prs.slide_layouts[6]

        for png in pngs:

            slide=prs.slides.add_slide(layout)

            slide.shapes.add_picture(path + os.sep + png,0,0,height=prs.slide_height)

        prs.save(path + '.pptx')

        print('PNG转PPTX成功!')

        shutil.rmtree(path)

    else:

        print('警告! 文件类型错误,请打开pdf文件类型!')

if __name__=="__main__":

    if len(sys.argv) == 2:

        pdf2pptx(sys.argv[1],5)

    elif len(sys.argv) > 2:

        pdf2pptx(sys.argv[1],int(sys.argv[2]))

    else:

        print('请输入要转化的文件名')

在此过程中,又研究了如何将python源文件编译为独立的exe文件。

中途遇到了几个问题,列如下:

  • 相对路径和绝对路径的问题。为了避免前后不一致,在程序运行前段将文件地址设定为绝对路径。

  • 获取PDF文件的长宽比。PPT文件有16:9和4:3两种比例,通过或许原PDF的长宽比,可以设定PPTX的长宽。最初的方案直接利用fitz库即可提取,但部分PDF会发生错误。因而改用现有PyPDF2库来提取该特征。此外,最初的想法是将长宽比作为参数输入,但后来觉得太蠢,还是通过上述方法来实现,更能体现自动化。

  • 将python源文件编译为exe后,找不到模板文件"default.pptx"。这一点经常出现在pyinstaller编译中,由于脱离了原python运行环境,部分资源无法找到,会出现这种错误。因而需要将"default.pptx"文件拷贝到工作目录,并通过''pptx.Presentation("default.pptx")''的方式来调用。但这种方式会导致需要将该模板与exe文件绑定,既不方便,也不优雅。随后查阅pyinstaller手册,可以通过''--add-data''参数,将该文件内嵌到exe文件内部。

  • 程序运行期间,会出现cmd窗口。 编译命令中添加''-w''参数解决。

  • 编译生成的exe文件较大。可以考虑使用pipenv环境进行编译,可以降低空间占用。

  • 环境配置。安装fitz库,直接安装pymupdf包即可。安装pptx库,直接安装python-pptx包。

完成以上步骤之后,将pdf文件用该可执行文件打开,便可以转化为pptx文件。

为了进一步自动化,每次在tex编译生成pdf之后,自动将pdf转为pptx,查阅了vscode插件Latex Workshop的手册。

image

注意到适当调整占位符,即可完成自动将pdf转为pptx的过程。

随后修改配置文件:


"latex-workshop.latex.tools": [

      {

              "name": "pdf2pptx",

              "command": "pdf2pptx",

              "args": [

              "%DOCFILE%.pdf"

              ]

      }

],

"latex-workshop.latex.recipes": [

      {

              "name": "xelatex",

              "tools": [

              "xelatex",

              "pdf2pptx"

          ]

      }

] 

其中latex-workshop.latex.tools对应latex-workshop.latex.recipes中的tools键.

至此,编辑tex文件之后,只需保存一下,即可自动生成pdf和pptx文件。

程序:pdf2pptx.exe

Github项目地址:mission-young/PDF2PPTX (github.com)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容