• 《Python趣味工具》——ppt的操作(1)


    前面我们学习了如何利用turtle模块制作emoji,今天来看看PPT的相关操作:


    在这里插入图片描述


    小L想要把 PPT 中的文本全部粘贴到 Word 文档中,该怎么办,一页一页的复制粘贴么,emmm,想想都很麻烦,还是交给Python吧!

    即要把 PPT 中的文本内容读取出来,再写入 Word 文档中。

    我们想要使用 Python 读取 PPT 中的文字,首先应该清楚 PPT 的基础结构,这样对之后代码的编写很有帮助。

    此处我们以 PowerPoint 软件为例,进行讲解和演示。


    一、PPT的基础结构:

    1️⃣一个 PPT 就是一个演示文稿(Presentation)。

    2️⃣演示文稿由页组成,每一页叫做幻灯片页(Slide)。

    3️⃣幻灯片页由形状(Shape)组成。

    • PPT 中提供了各种样式的形状,线条、箭头、矩形、基本形状、共识形状等。

    4️⃣通过是否含有文本(text),形状可以分为两类:

    • 一类是含有文本框的形状
    • 另一类是无文本框的形状(纯图片)

    5️⃣一个文本框可以看作是小的 Word 文档,其中的每一段内容叫段落(Paragraph)。

    注意哦,空行也是段落。

    段落之中的内容可以具有不同的样式。

    • 常见的样式有:字体、字形、字号、字体颜色、下划线、删除线、上标和下标等。

    6️⃣我们把具有相同样式的基本单元可称为一个样式块(Run)。

    例如,在段落中有一个高亮的字,那么这个字就形成了一个样式块。字的左右两边被分割成了新的样式块。所以,段落中就有三个样式块。

    将 PPT 中的结构按照层级关系来排列是这样的:

    幻灯片页 -> 形状 -> 文本框 -> 段落 -> 样式块


    二、PPT的相关操作:

    1. 导入pptx模块

    在了解了 PPT 文件的基础结构后,接下来就要使用 Python 读取内容。

    首先,我们要安装 python-pptx 模块,它可以读取和修改 .pptx 文件,不支持.ppt文件。

    python-pptx 不是一个内置模块,所以在使用前要先通过代码
    pip install python-pptx 在终端上进行安装。

    如果在自己电脑上安装不上或安装缓慢,可在命令后添加
    pip install python-pptx -i https://pypi.tuna.tsinghua.edu.cn/simple/
    进行加速。

    安装完成后,下一步就是导入这个模块;

    我们只需要使用 python-pptx 模块中的 Presentation 类,这里要用到 from...import...

    需要注意的是,这里是 from pptx import Presentation,而不是
    from python-pptx import Presentation。

    # 使用from...import从pptx模块中导入Presentation
    from pptx import Presentation
    
    • 1
    • 2

    2. ppt的基本操作:

    由于 PPT 有多级结构,想要得到所有的文字内容,那就要从头开始层层读取。

    第一步,读取文件;
    第二步,读取指定幻灯片页;
    第三步,读取指定形状;
    第四步,读取文本框内的文本内容。


    1️⃣调用 Presentation() 函数,读取指定路径,相当于打开了一份 .pptx 文件,并返回一个 Presentation 对象。

    from pptx import Presentation
    path = "/Users/shop.pptx"
    pptxFile = Presentation(path)
    print(pptxFile)
    
    • 1
    • 2
    • 3
    • 4

    本例中,将 .pptx 文件的绝对路径以字符串格式赋值给变量 path,再将变量 path 作为参数传入 Presentation() 函数中。


    2️⃣读取 .pptx 文件后,我们可以访问 Presentation 中的 .slides 属性,获取幻灯片页序列。

    slide = pptxFile.slides
    
    • 1

    幻灯片页序列中包含所有幻灯片页对象,可以使用索引定位到单个幻灯片页对象;

    1. 获取PPT第一张幻灯片页对象:
    slide = pptxFile.slides[0]
    
    • 1
    1. 也可以使用 for 循环读取所有幻灯片页对象。
    # for循环遍历pptxFile中.slides属性,并赋值给slide
    for slide in pptxFile.slides:
        # print()输出slide
        print(slide)
    
    • 1
    • 2
    • 3
    • 4

    使用 for 循环遍历 Presentation 对象中 .slides 属性,并赋值给变量 slide,这样就可以读取到 .pptx 文件中每个幻灯片页对象。


    3️⃣在获取了全部幻灯片页对象后,接下来就要读取其中的形状。

    我们可以访问幻灯片页对象中的 .shapes 属性,获取形状序列。

    案例中的代码,只读取了第一页幻灯片中的所有形状。

    slide = pptxFile.slides[0]
    shape = slide.shapes
    
    • 1
    • 2

    由于形状包含在幻灯片页中,在这里我们需要使用嵌套循环,读取每一页幻灯片中的每一个形状。

    # for循环遍历pptxFile中.slides属性,并赋值给slide
    for slide in pptxFile.slides:
        # for循环遍历slide中.shapes属性,赋值给变量shape
        for shape in slide.shapes:
            # print()输出shape
            print(shape)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4️⃣我们通过代码读取到每个幻灯片页中的每一个形状,接下来要获取其中的文本框。

    思考一下,是不是每个形状中都有文本框呢?
    在这里插入图片描述
    哈哈!并不是哒哒哒哒哒哒哒哒哒哒哒哒dadadada!!!

    在这里插入图片描述

    形状可以按照是否含有文本分为两类,一类是含有文本框的形状,另一类是纯图片的形状。

    所以,我们要将纯图片的形状排除,再从文本框中提取文字内容。

    这段代码可以判断形状内是否有文本框,然后读取文本框对象。

    if shape.has_text_frame == True:
        texts = shape.text_frame
    
    • 1
    • 2

    访问形状对象中的 .has_text_frame 属性,判断形状中是否存在文本框,返回布尔数。

    与 if 语句相结合,如果形状中存在文本框,就执行接下来的操作。


    5️⃣在获取了文本框对象后,要读取文本框内的文本内容,需要通过 .text 属性访问。

    访问形状中的 .text_frame 属性,获得文本框对象。

      # print()输出textFrame.text
                print(textFrame.text)
    
    • 1
    • 2

    终于把 .pptx 文件中的文本内容提取出来了,不错不错🎉


    6️⃣接下来,就应该把文本内容全部写入 Word 文档中。

    在这里,我们需要知道一个小规则,就是写入 Word 文档的内容样式要保持一致。

    也就是说,一段文本内容为一个样式块,就可以写入 Word 文档。如果一段文本内容包含多个样式块,写入 Word 文档时,就可能发生报错。

    由于我们以文本框为单位提取文本内容,文本框内有段落,段落中含有不同的样式块,就这样写入 Word 文档,程序会报错。

    在这里,要以样式块为最小单位提取文本内容,再把每个样式块写入 Word 文档中。

    刚才我们获取了文本框对象,再往下一层读取,需要访问 .paragraphs 属性,返回文本框中的段落序列。

    案例中的代码,读取了第一页幻灯片第一个文本框中的所有段落。

    textFrame = shape.text_frame
    paragraphs = textFrame.paragraphs
    
    • 1
    • 2

    要获取每个文本框内的每个段落,就需要使用 for 循环遍历文本框的 .paragraphs 属性。

     # for循环遍历slide中.shapes属性,赋值给变量shape
        for shape in slide.shapes:
            # 判断形状中是否有文本框
            if shape.has_text_frame == True:
                # 读取形状中的文本框,并赋值给变量textFrame
                textFrame = shape.text_frame
            
                # for循环遍历文本框内的所有段落
                # 赋值给变量paragraph
                for paragraph in textFrame.paragraphs:
                    # print()输出paragraph
                    print(paragraph)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    7️⃣获取了所有段落对象后,接下来就访问段落对象的 .runs 属性,就可以获得段落中的样式块序列。

    在案例中,读取了第一页幻灯片第一个文本框第一个段落中的所有样式块。

    from pptx import Presentation
    
    path = "/Users/shop.pptx"
    pptxFile = Presentation(path)
    
    slide = pptxFile.slides[0]
    shape = slide.shapes[0]
    textFrame = shape.text_frame
    paragraph = textFrame.paragraphs[0]
    
    runs = paragraph.runs
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    接下来,for 循环遍历段落的 .runs 属性,赋值给变量 run;访问段落对象的 .runs 属性,就可以获得段落中的样式块序列。


    8️⃣使用 .text 属性读取出样式块对象的文本内容。

      # for循环遍历段落中的所有样式块
                    # 赋值给变量run
                    for run in paragraph.runs:
                        # 读取样式块中的文本内容,并赋值给变量texts
                        texts = run.text
                        # print()输出texts
                        print(texts)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    太好了,终于通过层层读取,获得了每个样式块中的文本内容<( ̄︶ ̄)>
    在这里插入图片描述


    三、总结:

    今天我们通过读取样式块,访问其 .text 属性,获得了以样式块为单位的文本内容。

    这不是提取 .pptx 文件中的文本内容的唯一方式,我们要根据不同的需求采取不同的操作。

    层层读取 .pptx 文件需要嵌套循环,理清楚 PPT 的结构,就可以避免出 bug 啦~

    小提示:复数结尾的属性,例如 .slides,获取的都是序列,我们可以通过索引和遍历,得到单个对象。

    在这里插入图片描述


    四、 完整源码:

    # 使用from...import从pptx模块中导入Presentation
    from pptx import Presentation
    
    # 将.pptx文件路径赋值给变量path
    path = "/Users/xiaohe/statistics.pptx"
    
    # 读取path并赋值给变量pptxFile
    pptxFile = Presentation(path)
    
    # for循环遍历pptxFile中的.slides属性,赋值给slide
    for slide in pptxFile.slides:
    
        # for循环遍历slide中.shapes属性,赋值给变量shape
        for shape in slide.shapes:
            # TODO 判断形状中是否有文本框
            if shape.has_text_frame==True:
                # TODO 读取形状中的文本框,并赋值给变量textFrame
                textFrame=shape.text_frame
                
            
                # TODO for循环遍历文本框内的所有段落
                # 赋值给变量paragraph
                for paragraph in textFrame.paragraphs:
                    
                
                    # TODO for循环遍历段落中的所有样式块
                    # 赋值给变量run
                    for run in paragraph.runs:
                        # TODO 读取样式块中的文本内容,并赋值给变量texts
                        texts=run.text
                        print(texts)
                        # TODO print()输出texts
                        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    呜呜~ 本周就这样了,最近没时间写了~ ~ ~😢😢😢
    在这里插入图片描述

  • 相关阅读:
    4.2.2 设置VMware虚拟机
    Linux inotify 文件监控
    【存储RAID】存储RAID常见模式及其特点
    【JAVA】Retrofit详解和使用
    【数据结构】单链表的特点
    正睿OI补题(搜索)
    【算法练习Day15】平衡二叉树&&二叉树的所有路径&&左叶子之和
    使用fvm切换flutter版本
    #硬件电路设计VL817-Q7(B0)芯片拓展USB3.0一转四调试心得
    对话张璐:硅谷正在追逐两大赛道创新,融资降温但技术商业化更快了
  • 原文地址:https://blog.csdn.net/weixin_73453526/article/details/132725574