用Python的python-pptx库,PPT自动化制作效率提升40%!

举报
忆愿 发表于 2025/02/13 12:53:22 2025/02/13
130 0 0
【摘要】 你好,我是忆愿,全网4w+粉丝,《遂愿盈创》社群主理人。副业启航① | 遂愿盈创(对副业感兴趣免费可入,多种赚钱实战项目等你来,一起探寻副业快速变现的途径;以及对接互联网大厂商务合作,一起来搞点小外快,认识更多互联网大咖)目前群里已经带很多小伙伴(大部分大学生)变现几百块啦,程序员搞副业有额外加成~ 对副业感兴趣可+V : suiyuan2ying 拉你进群。文章目录python-pptx是...

在这里插入图片描述

你好,我是忆愿,全网4w+粉丝,《遂愿盈创》社群主理人。
副业启航① | 遂愿盈创(对副业感兴趣免费可入,多种赚钱实战项目等你来,一起探寻副业快速变现的途径;以及对接互联网大厂商务合作,一起来搞点小外快,认识更多互联网大咖)
目前群里已经带很多小伙伴(大部分大学生)变现几百块啦,程序员搞副业有额外加成~ 对副业感兴趣可+V : suiyuan2ying 拉你进群。

做了这么多年技术,PPT还真是躲不开。每次开会前熬夜做PPT,改来改去烦死人。

不是字体对不齐,就是配色不统一,搞得人焦头烂额。

有时候明明内容都准备好了,光调整格式就得花上大半天。

直到我发现了python-pptx这个宝藏库,整个人都轻松了。

一个脚本搞定的事儿,干嘛要手动点来点去?

写好代码一键生成,不仅省时省力,而且格式统一,看着特别专业。

说真的,我刚开始也不信这玩意能这么厉害。

但是当我用它处理了一个真实项目,把原来要忙活一下午的工作缩短到十来分钟,我就知道这东西真没吹牛。

关键是不会出错,格式统一,看着特别专业。

这个库最大的优势就是自动化程度高。

你想想看,手动做PPT的时候要点多少次鼠标?要调整多少次格式?

用代码的话,写一次模板,以后就可以一键生成,而且格式永远统一,不会出现字体大小不一致的尴尬。

python-pptx是啥?

说白了就是用Python代码来操作PPT的工具库。

它能让你用代码来创建、修改和自动化处理PPT文件,比手动操作效率高出几十倍。

装起来贼简单,一行命令就搞定:

pip install python-pptx

装好就能用,不用管什么Office啊WPS的,跨平台也没问题。

在Windows、Mac还是Linux上都能完美运行,这就避免了很多环境配置的麻烦。

不过要记得,这个库只支持.pptx格式,老版本的.ppt得先另存为新格式。

这是因为.pptx采用了更现代的XML格式,便于程序读写和处理。

如果你手上有老版本的PPT文件,记得先用Office或WPS另存为.pptx格式再处理。

python-pptx的功能相当强大,从简单的文本编辑到复杂的图表制作都能搞定。

它不仅能处理文字、图片、形状这些基本元素,还能创建各种图表,设置动画效果,甚至能处理母版和布局。

对于需要批量处理PPT或者经常制作格式统一的PPT的人来说,这简直就是一个神器。

从零开始搞个PPT

来看看最基础的PPT制作:

from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.dml.color import RGBColor

class PPTCreator:
    def __init__(self):
        self.prs = Presentation()
        
    def add_title_slide(self, title, subtitle=None):
        """添加标题页"""
        slide = self.prs.slides.add_slide(self.prs.slide_layouts[0])
        title_shape = slide.shapes.title
        subtitle_shape = slide.placeholders[1]
        
        # 设置标题
        title_shape.text = title
        title_shape.text_frame.paragraphs[0].font.size = Pt(44)
        title_shape.text_frame.paragraphs[0].font.bold = True
        title_shape.text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER
        
        # 设置副标题
        if subtitle:
            subtitle_shape.text = subtitle
            subtitle_shape.text_frame.paragraphs[0].font.size = Pt(32)
            
        return slide
        
    def save(self, filename):
        """保存PPT文件"""
        self.prs.save(filename)

# 使用示例
ppt = PPTCreator()
ppt.add_title_slide("超级厉害的PPT", "powered by Python")
ppt.save('demo.pptx')

这就整出来一个PPT了,是不是比手动点点点快多了?

而且格式统一,不会出现字体大小不一致的尴尬。

用代码生成的PPT,每个标题、每个段落的字体大小都完全一致,不会出现手动调整时可能产生的细微差异。

特别是在做系列PPT的时候,这种统一性显得尤为重要,能让整个作品看起来更专业、更有质感。

花式玩法

光整个标题页太基础了,来点花活:

class FancyPPTCreator(PPTCreator):
    def add_content_slide(self, title, content_list, layout_idx=1):
        """添加内容页"""
        slide = self.prs.slides.add_slide(self.prs.slide_layouts[layout_idx])
        
        # 设置标题
        title_shape = slide.shapes.title
        title_shape.text = title
        title_shape.text_frame.paragraphs[0].font.size = Pt(36)
        
        # 设置内容
        body_shape = slide.shapes.placeholders[1]
        tf = body_shape.text_frame
        
        # 添加项目符号
        for idx, item in enumerate(content_list):
            p = tf.add_paragraph()
            p.text = item
            p.font.size = Pt(18)
            p.font.name = '微软雅黑'
            
            # 设置不同层级的缩进
            level = 0 if idx == 0 else 1
            p.level = level
            
        return slide
        
    def add_two_column_slide(self, title, left_content, right_content):
        """添加双栏内容页"""
        slide = self.prs.slides.add_slide(self.prs.slide_layouts[3])
        
        # 设置标题
        title_shape = slide.shapes.title
        title_shape.text = title
        
        # 左侧内容
        left_shape = slide.shapes.add_textbox(
            Inches(1), Inches(1.5),
            Inches(3.5), Inches(5)
        )
        left_tf = left_shape.text_frame
        left_tf.text = left_content
        
        # 右侧内容
        right_shape = slide.shapes.add_textbox(
            Inches(5), Inches(1.5),
            Inches(3.5), Inches(5)
        )
        right_tf = right_shape.text_frame
        right_tf.text = right_content
        
        return slide

温馨提示:字体得是系统里有的,不然会用默认字体替代哦!

图表绘制大法

数据展示少不了图表,来整个漂亮的:

class ChartPPTCreator(FancyPPTCreator):
    def add_chart_slide(self, title, chart_data, chart_type=None):
        """添加图表页"""
        slide = self.prs.slides.add_slide(self.prs.slide_layouts[6])
        
        # 设置标题
        title_shape = slide.shapes.title
        title_shape.text = title
        
        # 创建图表数据
        chart_data = CategoryChartData()
        
        # 添加类别
        categories = chart_data['categories']
        values = chart_data['values']
        series_name = chart_data.get('series_name', '数据')
        
        chart_data.categories = categories
        chart_data.add_series(series_name, values)
        
        # 设置图表类型
        if chart_type is None:
            chart_type = XL_CHART_TYPE.COLUMN_CLUSTERED
            
        # 添加图表
        x, y = Inches(2), Inches(2)
        cx, cy = Inches(6), Inches(4.5)
        chart = slide.shapes.add_chart(
            chart_type, x, y, cx, cy, chart_data
        ).chart
        
        # 设置图表样式
        self._style_chart(chart)
        
        return slide
        
    def _style_chart(self, chart):
        """设置图表样式"""
        # 设置标题
        chart.has_title = True
        chart.chart_title.text_frame.paragraphs[0].font.size = Pt(18)
        
        # 设置图例
        chart.has_legend = True
        chart.legend.position = XL_LEGEND_POSITION.BOTTOM
        
        # 设置网格线
        chart.value_axis.has_major_gridlines = True
        chart.value_axis.major_gridlines.format.line.color.rgb = RGBColor(200, 200, 200)
        
    def add_multi_series_chart(self, title, data_dict):
        """添加多系列图表"""
        slide = self.prs.slides.add_slide(self.prs.slide_layouts[6])
        
        chart_data = CategoryChartData()
        chart_data.categories = data_dict['categories']
        
        # 添加多个系列
        for series_name, values in data_dict['series'].items():
            chart_data.add_series(series_name, values)
            
        # 添加图表
        x, y = Inches(2), Inches(2)
        cx, cy = Inches(6), Inches(4.5)
        chart = slide.shapes.add_chart(
            XL_CHART_TYPE.LINE, x, y, cx, cy, chart_data
        ).chart
        
        self._style_chart(chart)
        return slide

高级图片处理

PPT里插图片是常事,来看看怎么玩:

class ImagePPTCreator(ChartPPTCreator):
    def add_image_slide(self, title, image_path, position=None):
        """添加图片页"""
        slide = self.prs.slides.add_slide(self.prs.slide_layouts[6])
        
        # 设置标题
        title_shape = slide.shapes.title
        title_shape.text = title
        
        # 处理图片
        img_path = self._process_image(image_path)
        
        # 设置图片位置
        if position is None:
            position = {
                'left': Inches(2),
                'top': Inches(2),
                'width': Inches(6),
                'height': Inches(4.5)
            }
            
        # 添加图片
        slide.shapes.add_picture(
            img_path,
            position['left'],
            position['top'],
            position['width'],
            position['height']
        )
        
        return slide
        
    def _process_image(self, image_path, max_size_mb=2):
        """处理图片尺寸和大小"""
        from PIL import Image
        import os
        
        # 创建临时文件夹
        if not os.path.exists('temp'):
            os.makedirs('temp')
            
        # 复制图片到临时文件
        temp_path = os.path.join('temp', os.path.basename(image_path))
        img = Image.open(image_path)
        
        # 压缩图片直到小于指定大小
        while os.path.getsize(image_path) > max_size_mb * 1024 * 1024:
            width, height = img.size
            img = img.resize((int(width*0.8), int(height*0.8)))
            img.save(temp_path)
            
        return temp_path

批量制作神器

要是要做一堆类似的PPT,手动改不得累死?整个批量处理:

class BatchPPTCreator(ImagePPTCreator):
    def batch_create(self, data_list, template_path=None):
        """批量创建PPT"""
        for item in data_list:
            # 使用模板或创建新PPT
            if template_path:
                self.prs = Presentation(template_path)
            else:
                self.prs = Presentation()
                
            try:
                # 创建标题页
                self.add_title_slide(
                    item['title'],
                    item.get('subtitle')
                )
                
                # 创建内容页
                if 'content' in item:
                    self.add_content_slide(
                        "主要内容",
                        item['content']
                    )
                    
                # 创建图表页
                if 'chart_data' in item:
                    self.add_chart_slide(
                        "数据分析",
                        item['chart_data']
                    )
                    
                # 创建图片页
                if 'images' in item:
                    for img in item['images']:
                        self.add_image_slide(
                            img['title'],
                            img['path']
                        )
                        
                # 保存文件
                output_path = f"output/{item['title']}.pptx"
                self.save(output_path)
                print(f"创建成功:{output_path}")
                
            except Exception as e:
                print(f"处理 {item['title']} 时出错:{str(e)}")
                continue

模板套用大法

每次从零开始太麻烦?用模板啊:

class TemplatePPTCreator(BatchPPTCreator):
    def apply_template(self, template_path, data):
        """应用模板"""
        self.prs = Presentation(template_path)
        
        # 遍历所有页面
        for slide_idx, slide in enumerate(self.prs.slides):
            # 遍历页面中的所有形状
            for shape in slide.shapes:
                if not shape.has_text_frame:
                    continue
                    
                # 替换文本中的占位符
                text_frame = shape.text_frame
                for paragraph in text_frame.paragraphs:
                    for run in paragraph.runs:
                        for key, value in data.items():
                            placeholder = f'{{{key}}}'
                            if placeholder in run.text:
                                run.text = run.text.replace(
                                    placeholder,
                                    str(value)
                                )
                                
    def create_from_template(self, template_path, data_list):
        """批量使用模板创建PPT"""
        for item in data_list:
            try:
                # 应用模板
                self.apply_template(template_path, item)
                
                # 保存文件
                output_path = f"output/{item['title']}.pptx"
                self.save(output_path)
                print(f"创建成功:{output_path}")
                
            except Exception as e:
                print(f"处理 {item['title']} 时出错:{str(e)}")
                continue

实用工具函数

来点实用小工具:

class PPTUtils:
    @staticmethod
    def check_font(font_name):
        """检查字体是否可用"""
        from matplotlib.font_manager import FontManager
        fm = FontManager()
        font_list = [f.name for f in fm.ttflist]
        return font_name in font_list
        
    @staticmethod
    def convert_to_pdf(pptx_path):
        """转换PPT为PDF"""
        import comtypes.client
        
        powerpoint = comtypes.client.CreateObject("Powerpoint.Application")
        powerpoint.Visible = True
        
        ppt = powerpoint.Presentations.Open(pptx_path)
        pdf_path = pptx_path.replace('.pptx', '.pdf')
        ppt.SaveAs(pdf_path, 32)  # 32 是PDF格式
        
        ppt.Close()
        powerpoint.Quit()
        
    @staticmethod
    def merge_ppts(ppt_list, output_path):
        """合并多个PPT"""
        merged_ppt = Presentation()
        
        for ppt_path in ppt_list:
            ppt = Presentation(ppt_path)
            
            for slide in ppt.slides:
                # 复制页面
                new_slide = merged_ppt.slides.add_slide(
                    merged_ppt.slide_layouts[
                        slide.slide_layout.index
                    ]
                )
                
                # 复制所有形状
                for shape in slide.shapes:
                    el = shape.element
                    new_el = deepcopy(el)
                    new_slide.shapes._spTree.insert_element_before(
                        new_el,
                        'p:extLst'
                    )
                    
        merged_ppt.save(output_path)

使用示例

来个完整的使用示例:

def main():
    # 创建PPT生成器
    creator = TemplatePPTCreator()
    
    # 准备数据
    data_list = [
        {
            'title': '2023年度报告',
            'subtitle': '技术部',
            'content': [
                '项目完成情况',
                '技术创新',
                '团队建设',
                '未来规划'
            ],
            'chart_data': {
                'categories': ['Q1', 'Q2', 'Q3', 'Q4'],
                'series': {
                    '项目数': [10, 15, 12, 18],
                    '完成率': [0.8, 0.85, 0.9, 0.95]
                }
            },
            'images': [
                {
                    'title': '团队照片',
                    'path': 'images/team.jpg'
                }
            ]
        }
    ]
    
    # 批量生成PPT
    creator.batch_create(data_list)
    
    # 转换为PDF
    PPTUtils.convert_to_pdf('output/2023年度报告.pptx')

if __name__ == '__main__':
    main()

这些代码够你玩一阵子了。

不过记住啊,代码写完得测试,别一上来就真实PPT,要是把老板的报告搞坏了可就尴尬了。

还有个事儿,这些代码我都实际用过,不同Python版本可能会有点差异,用的时候记得看看版本兼容性。

要是遇到问题,就打印下错误信息,基本都能解决。

写代码也要讲究性价比,能用简单方法解决的问题,咱就别上重型武器了。

毕竟,能跑起来的代码才是好代码!

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。