> 技术文档 > 项目工坊 | 高效自动化:Python-pptx生成ppt全流程详解(呕心沥血版)

项目工坊 | 高效自动化:Python-pptx生成ppt全流程详解(呕心沥血版)

目录

1摘要

2目的:python-pptx设计模板

2模块安装

3PPT结构与python接口关系

4初认识python-pptx

4.1新建一个PPT文件,并重命名

4.1.1简单示例

4.1.2扩展封装成函数

4.2查看PPT总页数

4.2.1简单示例

4.2.2扩展封装成函数

4.3项目开始-python新建PPT

4.3.1创建项目

4.3.2项目结构说明

4.3.3完善office_ppt_ser.py

4.3.4完善main.py

5文本框

5.1函数-插入文本框

5.1.1导入模块

5.1.2定义titlebox函数

5.1.3打开PPT文件并选择幻灯片

5.1.4添加文本框

5.1.5写入文本内容

5.1.6设置文本颜色

5.1.7设置文本对齐方式

5.1.8设置字体样式

5.1.9保存PPT文件

5.1.10调用函数

5.2项目新增文本框

5.2.1完善office_ppt_ser.

5.2.2完善main.py

5.2.3项目效果

6形状

6.1函数-插入长方形

6.1.1导入库

6.1.2定义 shape_rectangle 函数

6.1.3打开 PPT 文件并选择幻灯片

6.1.4 添加矩形框

6.1.5设置矩形框的旋转角度

6.1.6设置矩形框的填充颜色

6.1.7设置矩形框为背景(可选)

6.1.8设置矩形框的边框宽度

6.1.9保存 PPT 文件

6.1.10调用函数

6.2项目新增形状

6.2.1完善office_ppt_ser.py

6.2.2完善main.py

6.2.3项目效果

7图片

7.1函数-插入图片

7.1.1导入模块

7.1.2定义 add_picture 函数

7.1.3加载 PowerPoint 文件

7.1.4获取指定幻灯片

7.1.5设置图片的位置和大小

7.1.6插入图片

7.1.7保存 PowerPoint 文件

7.1.8调用函数

7.2项目新增图片

7.2.1完善office_ppt_ser.py

7.2.2完善main.py

7.2.3效果展示

8表格

8.1函数-插入表格

8.1.1导入库

8.1.2定义函数 table_Nrows_17cols

8.1.3打开 PPT 文件并选择幻灯片

8.1.4确定表格的行数和列数

8.1.5计算表格的总宽度和高度

8.1.6添加表格到幻灯片

8.1.7填充表头和数据

8.1.8设置行高

8.1.9修改表格样式

8.1.10保存 PPT 文件

8.1.11调用函数

8.2项目新增表格

8.2.1完善office_ppt_ser.py

8.2.2完善main.py

8.2.3效果展示

9图表

9.1函数-插入柱状图

9.1.1导入库

9.1.2定义颜色集合

9.1.3定义函数 chart_clustered_bar_self_color

9.1.4调用函数

9.2项目新增柱状图

9.2.1完善office_ppt_ser.py

9.2.2完善main.py

9.3.4效果展示

10项目代码main.py升级

10.1提取函数参数

10.2数据参数化

10.3封装为函数

10.4调用函数

11总结


1摘要

本文详细介绍了如何利用 Python 的 python-pptx 模块来自动化生成 PowerPoint 报告。文章通过一个具体的案例,展示了如何从零开始构建一个自动化生成 PPT 的工具,涵盖了从安装模块、PPT 结构分析、基础操作(如新建 PPT、添加幻灯片、插入文本框、形状、图片、表格和图表)到最终生成完整报告的整个过程。

2目的:python-pptx设计模板

场景:张三接到领导的任务,负责每周整理销售周报,格式如下图所示。这项工作繁琐且耗时:他需要从多个 Excel 表格中提取并整理数据,最终生成完整的周报。起初尚能应付,但随着时间的推移,他发现每次都是重复性操作。这种低效且机械的工作方式不仅耗费精力,还容易出错,给张三带来了巨大压力。

为了实现张三工作的全面自动化,可以分以下三个步骤完成:

  1. 第一步:利用 Python 设计 PPT 模板,并在模板中预留数据接口,确保数据能够动态填充到指定位置。

  2. 第二步:通过 Python 爬虫技术从指定数据源(如网页或数据库)爬取数据,或从 Excel 表格中收集数据,并使用 Pandas 模块对数据进行分析,生成 PPT 所需的结构化数据。

  3. 第三步:将第一步和第二步整合为一个完整的自动化脚本,实现从数据收集到 PPT 生成的全程自动化。

本文将从 Python-pptx 模块的底层原理入手,结合 PPT 的核心结构,重点讲解第1个步骤的实现方法

2模块安装

模块的安装方法与常规安装一致,使用以下命令即可:

pip install python-pptx

如不会安装可以参考另一篇文章《PyCharm 与 Anaconda 下载安装及 PyCharm 新建项目指南》

3PPT结构与python接口关系

通过对上述 PPT 模板的分析,其核心设计主要包含以下 6 个要素,以及与 python-pptx 接口的对应关系:

  1. 母版设计(幻灯片布局),功能:定义幻灯片的整体结构和布局。对应接口:SlideLayout 类

  2. 文本框,功能:用于填充标题、正文等文本内容。对应接口:TextFrame 类

  3. 形状,功能:包括矩形、圆形等图形元素,用于装饰或强调信息。对应接口:Shape 类

  4. 图片,功能:插入图像以增强视觉效果。对应接口:Picture 类

  5. 表格,功能:用于展示结构化数据。对应接口:Table 类

  6. 图表,功能:通过可视化形式呈现数据趋势或对比。对应接口:Chart 类

PPT 的结构与 python-pptx 接口的对应关系如下图所示。

此外,python-pptx 还提供了其他接口,例如:幻灯片母版:SlideMaster 类,备注:NotesSlide 类,超链接:Hyperlink 类。由于本次模板设计中未涉及这些功能,因此不再展开讲解。本文将重点围绕上述 6 种核心接口进行详细说明。

4初认识python-pptx

在日常制作PPT时,我们通常会进行一些基础操作,例如新建一个PPT文件对文件进行重命名,以及查看当前PPT的总页数。这些操作虽然简单,但却是PPT制作过程中不可或缺的步骤。接下来,我们将使用 python-pptx 库,通过代码逐一实现这些功能,展示如何用编程的方式高效完成这些常规任务,涉及Presentation类、SlideLayout类、Slide类。

4.1新建一个PPT文件,并重命名

4.1.1简单示例

from pptx import Presentation # 引入python-pptx中的Presentation类template = r\'F:\\070_Digitize数字化\\ppt自动化测试\\模版.pptx\'prs = Presentation(template) # 用Presentation读取PPT模板prs.slides.add_slide(prs.slide_layouts[0]) # 模板template中增加幻灯片,引用prs.slide_layouts[0]代表母版第1个幻灯片new_ppt_path = r\'F:\\070_Digitize数字化\\ppt自动化测试\\新建PPT.pptx\'prs.save(new_ppt_path) # 对ppt保存

运行效果在那个文件夹下会有1个PPT,名叫《新建PPT.pptx》,如下:

代码解读

 1、引入 Presentation 类

from pptx import Presentation # 引入python-pptx中的Presentation类
  • python-pptx 是一个用于创建和更新 PowerPoint (.pptx) 文件的 Python 库。

  • Presentation 类是 python-pptx 中的核心类,用于表示一个 PowerPoint 文件。

2、定义模板文件路径

template = r\'F:\\070_Digitize数字化\\ppt自动化测试\\模版.pptx\'
  • template 变量存储了模板文件的路径。r 前缀表示原始字符串,避免转义字符的影响。

  • 这个路径指向一个现有的 PowerPoint 模板文件。

3、读取模板文件

prs = Presentation(template) # 用Presentation读取PPT模板
  • Presentation(template) 使用 Presentation 类加载指定路径的 PowerPoint 文件。

  • prs 是一个 Presentation 对象,代表整个 PowerPoint 文件。

4、添加新幻灯片

prs.slides.add_slide(prs.slide_layouts[0]) # 模板template中增加幻灯片,引用prs.slide_layouts[0]代表母版第1个幻灯片
  • prs.slide_layouts 是一个列表,包含了模板中定义的所有幻灯片布局(母版幻灯片)。

  • prs.slides.add_slide() 方法使用指定的布局向 PowerPoint 文件中添加一张新的幻灯片。

  • prs.slide_layouts[0] 表示使用模板中的第一个幻灯片布局。引用prs.slide_layouts[0]代表母版第1个幻灯片,给的测试模版PPT-《模版.pptx》(附件已上传文件),里面的模板有三页如下图,若是改写成prs.slides.add_slide(prs.slide_layouts[3])是会报错的,意思:尝试访问一个不存在的幻灯片布局索引

4.1.2扩展封装成函数

将上述代码封装为函数,便于复用。如果不清楚如何将代码重构为函数或类,可以参考上一篇文章《Python代码变形记:一个简单案例的N次重构,函数与类的华丽转身》,以下代码定义了一个函数 new_ppt_add_slide,用于基于指定的 PowerPoint 模板创建新的 PPT 文件,并添加指定布局的幻灯片。

import os # 文件类模块from pptx import Presentation # 引入python-pptx中的Presentation类def new_ppt_add_slide(template, page_num=[0], PPT_Name=\'新建 Microsoft PowerPoint 演示文稿.pptx\',save_path=\'C:\\\\Users\\\\XXXX\\\\Desktop\'): \"\"\" :param template: PPT模板 :param page_num: 列表,代表PPT模板里面的幻灯片序号,从0开始 :param PPT_Name: PPT名字 :param save_path: 保存路径 :return:返回新的PPT路径 \"\"\" if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起 else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接 prs = Presentation(template) # 用Presentation读取PPT模板 for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 模板template中增加幻灯片 prs.save(new_ppt_path) # 对ppt保存 return new_ppt_path

值得注意的是

①这边增加一个判定“检查保存路径”

if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接
  • 如果 save_path 是一个有效的目录路径,则将 PPT_Name 拼接到 save_path 后面,形成完整的新PPT文件路径。

  • 如果 save_path 不是一个有效的目录路径,则直接将 PPT_Name 作为新PPT文件的路径。

②通过 page_num 参数(列表形式),支持一次性添加多张幻灯片。

for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 添加幻灯片

4.2查看PPT总页数

4.2.1简单示例

from pptx import Presentation # 引入python-pptx中的Presentation类template = r\'F:\\070_Digitize数字化\\ppt自动化测试\\模版.pptx\'prs = Presentation(template) # 用Presentation读取PPT模板slide_number = len(prs.slides)#利用slides属性,用len读取当前有多少PPTprint(slide_number)

运行结果:0(说明模版里面没有1页PPT)

代码解读:

1、统计幻灯片数量

slide_number = len(prs.slides) # 利用slides属性,用len读取当前有多少PPT
  • prs.slides 是 Presentation 对象的一个属性,表示当前 PowerPoint 文件中的所有幻灯片。

  • len(prs.slides) 返回幻灯片的数量,并将其赋值给 slide_number

2、打印幻灯片数量

print(slide_number)
  • 使用 print() 函数输出幻灯片数量。

4.2.2扩展封装成函数

将上述代码封装为函数,便于复用。

from pptx import Presentation # 引入python-pptx中的Presentation类def ppt_slide_number(ppt_script): prs = Presentation(ppt_script) slide_number = len(prs.slides) return slide_number

这个函数的作用是读取一个PPT文件,并返回该文件中幻灯片的数量。它的核心步骤是:使用 Presentation 类加载PPT文件;通过 prs.slides 获取所有幻灯片的列表;使用 len() 函数计算幻灯片的数量并返回。

4.3项目开始-python新建PPT

项目启动指南:创建《销售周报.pptx》报告

4.3.1创建项目

  • 项目初始化,请新建一个Python项目(项目名称可自定义), 可以参考另一篇文章《PyCharm 与 Anaconda 下载安装及 PyCharm 新建项目指南》
  • 获取项目资源,PPT模板素材已准备就绪,通过网盘分享的文件:素材链接: https://pan.baidu.com/s/1sZcvVHkJzQkMGeaEv_I6Hg?pwd=ia6w 提取码: ia6w

  • 模板说明,下载的PPT模板包含以下特点:

pycharm新建项目如下图

将下载的《PPT模板.pptx》放在该项目下,如下图

新建py文件office_ppt_ser.py

4.3.2项目结构说明

 项目文件结构如下,PPT模板文件:用于存储预设的PPT模板样式。main.py:主程序入口文件,包含程序的主要执行逻辑。office_ppt_ser.py:PPT服务模块,封装了所有与PPT操作相关的功能函数。main.py引用了office_ppt_series.py的函数,关于函数之间相互引用可以参考文章《Python 中文件夹、包、模块定义及函数或类模块引用》,在接下来的开发中,将集中精力对 main.py 和 office_ppt_ser.py 进行功能完善和代码优化。

4.3.3完善office_ppt_ser.py

完善office_ppt_ser.py,将上述写的函数ppt_slide_number和new_ppt_add_slide均复制到office_ppt_ser.py文件中

import os # 文件类模块from pptx import Presentation # 引入python-pptx中的Presentation类def new_ppt_add_slide(template, page_num=[0], PPT_Name=\'新建 Microsoft PowerPoint 演示文稿.pptx\',save_path=\'C:\\\\Users\\\\weidong.guo\\\\Desktop\'): \"\"\" :param template: PPT模板 :param page_num: 列表,代表PPT模板里面的幻灯片序号,从0开始 :param PPT_Name: PPT名字 :param save_path: 保存路径 :return:返回新的PPT路径 \"\"\" if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起 else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接 prs = Presentation(template) # 用Presentation读取PPT模板 for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 模板template中增加幻灯片 prs.save(new_ppt_path) # 对ppt保存 return new_ppt_pathdef ppt_slide_number(ppt_script): prs = Presentation(ppt_script) slide_number = len(prs.slides) return slide_number

4.3.4完善main.py

from office_ppt_ser import new_ppt_add_slidefrom office_ppt_ser import ppt_slide_numberdef main(): new_ppt = r\'PPT模版.pptx\' new_ppt_path = new_ppt_add_slide(new_ppt, page_num=[1], PPT_Name=\'销售周报.pptx\') print(new_ppt_path) slide_number = ppt_slide_number(new_ppt_path) print(new_ppt_path)# 按装订区域中的绿色按钮以运行脚本。if __name__ == \'__main__\': main()

运行main.py,结果在该项目文件下会自动生成一个PPT《销售周报.pptx》,里面含有1页空白PPT如下

分享上述完整代码路径:
链接: https://pan.baidu.com/s/1CnUIhopJL7LGojlvfEILVg?pwd=c2t8 提取码: c2t8

5文本框

在新建的PPT文档中,我们需要使用TextFrame类来插入和编辑文本内容。具体操作如下:首先通过text_frame = shape.text_frame来访问文本框对象,然后使用text_frame.text = \"Some text\"语句即可添加文本内容。在实际应用中,我们通常需要对文本框进行多项格式设置,主要包括:调整文本框位置、设置字体样式、定义字号大小、配置文本颜色、选择对齐方式以及应用加粗效果等排版设计。接下来将根据一个函数-插入文本框进行详细讲解。

5.1函数-插入文本框

from pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Ptdef titlebox(ppt_script, page_num=0, content_text=\'Backup\', font_size=18, left=0.55, top=2.12, width=25.81, height=1.08, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'\', alignment=\'左对齐\', word_wrap=False): \"\"\" 参数: ppt_script (str): PPT文件路径。 page_num (int): 幻灯片页码(从0开始)。 content_text (str): 文本框内容。 font_size (int): 字体大小(单位:磅)。 left (float): 文本框左上角的水平位置(单位:厘米)。 top (float): 文本框左上角的垂直位置(单位:厘米)。 width (float): 文本框宽度(单位:厘米)。 height (float): 文本框高度(单位:厘米)。 font_bold (bool): 是否加粗。 font_name (str): 字体名称。 font_color (str): 字体颜色(支持\'blue\', \'green\', \'red\', \'yellow\', \'orange\', \'white\', \'gray1\', \'black\')。 alignment (str): 对齐方式(支持\'左对齐\', \'居中\')。 word_wrap (bool): 是否自动换行。 return: \"\"\" # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加文本框 textbox = slide.shapes.add_textbox(Cm(left), Cm(top), Cm(width), Cm(height)) tf = textbox.text_frame tf.word_wrap = word_wrap # 在文本框中写入文字 # 题目 para = tf.paragraphs[0] # 新增段落 para.text = content_text # 向段落写入文字 if font_color == \'blue\': para.font.color.rgb = RGBColor(0, 30, 80) # 蓝色 elif font_color == \'green\': para.font.color.rgb = RGBColor(0, 176, 80) # 绿色 elif font_color == \'red\': para.font.color.rgb = RGBColor(255, 0, 0) # 红色 elif font_color == \'yellow\': para.font.color.rgb = RGBColor(255, 255, 0) # 红色 elif font_color == \'orange\': para.font.color.rgb = RGBColor(255, 192, 0) # 红色 elif font_color == \'white\': para.font.color.rgb = RGBColor(255, 255, 255) # 红色 elif font_color == \'gray1\': para.font.color.rgb = RGBColor(182, 191, 197) # 红色 else: para.font.color.rgb = RGBColor(0, 0, 0) # 黑色 if alignment == \'左对齐\': para.alignment = PP_ALIGN.LEFT else: para.alignment = PP_ALIGN.CENTER # 居中 # 设置字体 font = para.font font.name = font_name # 字体类型 font.bold = font_bold # 加粗 font.size = Pt(font_size) # 大小 prs.save(ppt_script) # 对ppt保存ppt_script = \'销售周报.pptx\'titlebox(ppt_script)

接下来对上述函数一一解读

5.1.1导入模块

from pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Pt
  • Presentation:用于创建或打开PPT文件。

  • RGBColor:用于设置文本颜色。

  • PP_ALIGN:用于设置文本对齐方式。

  • CmPt:用于设置尺寸单位(厘米和磅)。

5.1.2定义titlebox函数

def titlebox(ppt_script, page_num=0, content_text=\'Backup\', font_size=18, left=0.55, top=2.12, width=25.81, height=1.08, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'\', alignment=\'左对齐\', word_wrap=False):
  • 参数说明:

    • ppt_script:PPT文件路径。

    • page_num:幻灯片页码(默认第1页)。

    • content_text:文本框内容(默认\'Backup\')。

    • font_size:字体大小(默认18磅)。

    • lefttop:文本框左上角的坐标(默认0.55cm和2.12cm)。

    • widthheight:文本框的宽度和高度(默认25.81cm和1.08cm)。

    • font_bold:是否加粗(默认True)。

    • font_name:字体名称(默认\'方正兰亭黑_GBK\')。

    • font_color:字体颜色(默认黑色)。

    • alignment:对齐方式(默认左对齐)。

    • word_wrap:是否自动换行(默认False)。

5.1.3打开PPT文件并选择幻灯片

prs = Presentation(ppt_script)slide = prs.slides[page_num]
  • 打开指定路径的PPT文件,并选择指定页码的幻灯片。

5.1.4添加文本框

textbox = slide.shapes.add_textbox(Cm(left), Cm(top), Cm(width), Cm(height))tf = textbox.text_frametf.word_wrap = word_wrap
  • word_wrap控制文本是否自动换行。

  • 在幻灯片上添加一个文本框,并设置其位置和大小。如何查看文本框的位置和大小如下

5.1.5写入文本内容

para = tf.paragraphs[0] # 新增段落para.text = content_text # 向段落写入文字
  • 在文本框中写入指定的文本内容。

5.1.6设置文本颜色

if font_color == \'blue\': para.font.color.rgb = RGBColor(0, 30, 80) # 蓝色elif font_color == \'green\': para.font.color.rgb = RGBColor(0, 176, 80) # 绿色elif font_color == \'red\': para.font.color.rgb = RGBColor(255, 0, 0) # 红色elif font_color == \'yellow\': para.font.color.rgb = RGBColor(255, 255, 0) # 黄色elif font_color == \'orange\': para.font.color.rgb = RGBColor(255, 192, 0) # 橙色elif font_color == \'white\': para.font.color.rgb = RGBColor(255, 255, 255) # 白色elif font_color == \'gray1\': para.font.color.rgb = RGBColor(182, 191, 197) # 灰色else: para.font.color.rgb = RGBColor(0, 0, 0) # 黑色
  • 根据font_color参数设置文本颜色。

5.1.7设置文本对齐方式

if alignment == \'左对齐\': para.alignment = PP_ALIGN.LEFTelse: para.alignment = PP_ALIGN.CENTER # 居中

5.1.8设置字体样式

font = para.fontfont.name = font_name # 字体类型font.bold = font_bold # 加粗font.size = Pt(font_size) # 大小
  • 设置字体名称、加粗状态和字体大小。

5.1.9保存PPT文件

prs.save(ppt_script) # 对ppt保存
  • 保存修改后的PPT文件。

5.1.10调用函数

ppt_script = \'销售周报.pptx\'titlebox(ppt_script)
  • 调用titlebox函数,在销售周报.pptx中插入默认样式的文本框。

效果如下

5.2项目新增文本框

5.2.1完善office_ppt_ser.

项目将在 4.3节项目开始的基础上继续推进,进一步完善代码,增加新增文本框的功能。具体实现方式是将上述函数迁移至 office_ppt_ser.py 文件中。将上述函数迁移至 office_ppt_ser.py 文件中。

office_ppt_ser.py如下

import os # 文件类模块from pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Ptdef new_ppt_add_slide(template, page_num=[0], PPT_Name=\'新建 Microsoft PowerPoint 演示文稿.pptx\',save_path=\'C:\\\\Users\\\\weidong.guo\\\\Desktop\'): \"\"\" :param template: PPT模板 :param page_num: 列表,代表PPT模板里面的幻灯片序号,从0开始 :param PPT_Name: PPT名字 :param save_path: 保存路径 :return:返回新的PPT路径 \"\"\" if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起 else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接 prs = Presentation(template) # 用Presentation读取PPT模板 for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 模板template中增加幻灯片 prs.save(new_ppt_path) # 对ppt保存 return new_ppt_pathdef ppt_slide_number(ppt_script): prs = Presentation(ppt_script) slide_number = len(prs.slides) return slide_numberdef titlebox(ppt_script, page_num=0, content_text=\'Backup\', font_size=18, left=0.55, top=2.12, width=25.81, height=1.08, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'\', alignment=\'左对齐\', word_wrap=False): \"\"\" 参数: ppt_script (str): PPT文件路径。 page_num (int): 幻灯片页码(从0开始)。 content_text (str): 文本框内容。 font_size (int): 字体大小(单位:磅)。 left (float): 文本框左上角的水平位置(单位:厘米)。 top (float): 文本框左上角的垂直位置(单位:厘米)。 width (float): 文本框宽度(单位:厘米)。 height (float): 文本框高度(单位:厘米)。 font_bold (bool): 是否加粗。 font_name (str): 字体名称。 font_color (str): 字体颜色(支持\'blue\', \'green\', \'red\', \'yellow\', \'orange\', \'white\', \'gray1\', \'black\')。 alignment (str): 对齐方式(支持\'左对齐\', \'居中\')。 word_wrap (bool): 是否自动换行。 return: \"\"\" # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加文本框 textbox = slide.shapes.add_textbox(Cm(left), Cm(top), Cm(width), Cm(height)) tf = textbox.text_frame tf.word_wrap = word_wrap # 在文本框中写入文字 # 题目 para = tf.paragraphs[0] # 新增段落 para.text = content_text # 向段落写入文字 if font_color == \'blue\': para.font.color.rgb = RGBColor(0, 30, 80) # 蓝色 elif font_color == \'green\': para.font.color.rgb = RGBColor(0, 176, 80) # 绿色 elif font_color == \'red\': para.font.color.rgb = RGBColor(255, 0, 0) # 红色 elif font_color == \'yellow\': para.font.color.rgb = RGBColor(255, 255, 0) # 红色 elif font_color == \'orange\': para.font.color.rgb = RGBColor(255, 192, 0) # 红色 elif font_color == \'white\': para.font.color.rgb = RGBColor(255, 255, 255) # 红色 elif font_color == \'gray1\': para.font.color.rgb = RGBColor(182, 191, 197) # 红色 else: para.font.color.rgb = RGBColor(0, 0, 0) # 黑色 if alignment == \'左对齐\': para.alignment = PP_ALIGN.LEFT else: para.alignment = PP_ALIGN.CENTER # 居中 # 设置字体 font = para.font font.name = font_name # 字体类型 font.bold = font_bold # 加粗 font.size = Pt(font_size) # 大小 prs.save(ppt_script) # 对ppt保存

5.2.2完善main.py

先看看我们的样板,可以发现有7处文字,要依此了解这7处文字设置的字体样式、字体大小、字体颜色、字体位置、是否加粗等,并把相应参数更改即可

具体main.py代码如下

from office_ppt_ser import new_ppt_add_slidefrom office_ppt_ser import ppt_slide_numberfrom office_ppt_ser import titleboxdef main(): new_ppt = r\'PPT模版.pptx\' new_ppt_path = new_ppt_add_slide(new_ppt, page_num=[1], PPT_Name=\'销售周报.pptx\') print(new_ppt_path) slide_number = ppt_slide_number(new_ppt_path) print(new_ppt_path) # 部门报告 titlebox(new_ppt_path, page_num=0, content_text=\'部门报告\', font_size=20, left=0.55, top=0.94, width=3.36, height=1.11, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'blue\', alignment=\'左对齐\', word_wrap=False) # ■部门商品库存记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品库存记录\', font_size=12, left=0.58, top=2.14, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■部门商品销售记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品销售记录\', font_size=12, left=0.58, top=6.34, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■总结 titlebox(new_ppt_path, page_num=0, content_text=\'■总结\', font_size=12, left=0.58, top=11.65, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000 titlebox(new_ppt_path, page_num=0, content_text=\'2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000\', font_size=12, left=0.58, top=12.58, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 红灯 titlebox(new_ppt_path, page_num=0, content_text=\'红灯\', font_size=18, left=16.68, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 绿灯 titlebox(new_ppt_path, page_num=0, content_text=\'绿灯\', font_size=18, left=20.32, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False)# 按装订区域中的绿色按钮以运行脚本。if __name__ == \'__main__\': main()

5.2.3项目效果

方便展示效果,我把“红灯”“绿灯”的颜色均调成黑色:

分享上述完整代码路径:
链接: https://pan.baidu.com/s/1Gas4UeIXRvcH71lWBfD5cQ?pwd=dgy7 提取码: dgy7

6形状

在 PowerPoint 中,形状(Shape)是幻灯片上的一个可视化元素。每个形状都有一个类型(如文本框、矩形、椭圆等),并且可以具有各种属性,如位置、大小、颜色、边框、填充等。python-pptx 提供了 Shape 类来表示 PowerPoint 中的形状。可以通过 Slide.shapes 属性来访问幻灯片上的形状。

  • 获取形状
from pptx import Presentation# 打开一个演示文稿prs = Presentation(\'example.pptx\')# 获取第一张幻灯片slide = prs.slides[0]# 获取幻灯片上的所有形状for shape in slide.shapes: print(shape.shape_type)
  • 添加形状

from pptx.enum.shapes import MSO_SHAPE# 添加一个矩形left = top = width = height = Inches(1.0)shape = slide.shapes.add_shape(MSO_SHAPE.RECTANGLE, left, top, width, height)# 设置形状的填充颜色fill = shape.fillfill.solid()fill.fore_color.rgb = RGBColor(255, 0, 0) # 红色

接下来将根据一个函数-插入长方形进行详细讲解。

6.1函数-插入长方形

from pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.shapes import MSO_SHAPEfrom pptx.util import Cmfrom pptx.util import Pt# 在PPT中添加矩形框def shape_rectangle(ppt_script, page_num=0, Left=0.96, Top=3.2, Width=12.5, Height=5.87, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加矩形 shape = slide.shapes.add_shape(autoshape_type_id=MSO_SHAPE.RECTANGLE, left=Cm(Left), top=Cm(Top), width=Cm(Width), height=Cm(Height)) # 调整角度 shape.rotation = rotation # 填充背景色 fill = shape.fill fill.solid() # 调整线宽 line = shape.line if fore_color == \'gray\': fill.fore_color.rgb = RGBColor(242, 242, 242) line.color.rgb = RGBColor(242, 242, 242) elif fore_color == \'gray1\': fill.fore_color.rgb = RGBColor(127, 127, 127) line.color.rgb = RGBColor(127, 127, 127) elif fore_color == \'blue\': fill.fore_color.rgb = RGBColor(0, 30, 80) line.color.rgb = RGBColor(0, 30, 80) elif fore_color == \'red\': fill.fore_color.rgb = RGBColor(192, 0, 0) line.color.rgb = RGBColor(192, 0, 0) elif fore_color == \'yellow\': fill.fore_color.rgb = RGBColor(255, 255, 0) line.color.rgb = RGBColor(255, 255, 0) elif fore_color == \'white\': fill.fore_color.rgb = RGBColor(255, 255, 255) line.color.rgb = RGBColor(255, 255, 255) elif fore_color == \'lightblue\': fill.fore_color.rgb = RGBColor(212, 228, 255) line.color.rgb = RGBColor(212, 228, 255) # fill.fore_color.brightness = 0 # 设为透明 if shape_is_background == True: shape.fill.background() # fill.background() # fill.back_color.rgb = RGBColor(255, 255, 255) line.color.brightness = 0 line.width = Pt(line_width) line.fill.background() # 调成背景色 prs.save(ppt_script) # 对ppt保存ppt_script = \'销售周报.pptx\'shape_rectangle(ppt_script)

这段代码的主要功能是在 PowerPoint 文件的指定幻灯片上添加一个矩形框,并可以自定义矩形框的位置、大小、颜色、边框宽度、旋转角度等属性。通过调用 shape_rectangle 函数,可以轻松地在 PPT 中添加自定义的矩形框。

6.1.1导入库

from pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.shapes import MSO_SHAPEfrom pptx.util import Cmfrom pptx.util import Pt
  • Presentation:用于创建或打开 PowerPoint 文件。

  • RGBColor:用于定义颜色。

  • MSO_SHAPE:定义了 PowerPoint 中的各种形状类型。

  • Cm 和 Pt:用于设置长度单位(厘米和磅)。

6.1.2定义 shape_rectangle 函数

def shape_rectangle(ppt_script, page_num=0, Left=0.96, Top=3.2, Width=12.5, Height=5.87, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False):
  • ppt_script:PPT 文件的路径。

  • page_num:要操作的幻灯片页码,默认为第 0 页(第一页)。

  • Left 和 Top:矩形框左上角的坐标,单位为厘米。

  • Width 和 Height:矩形框的宽度和高度,单位为厘米。

  • fore_color:矩形框的填充颜色,默认为灰色。

  • line_width:矩形框边框的宽度,单位为磅。

  • rotation:矩形框的旋转角度。

  • shape_is_background:是否将矩形框设置为背景。

6.1.3打开 PPT 文件并选择幻灯片

prs = Presentation(ppt_script)slide = prs.slides[page_num]
  • prs:打开指定的 PowerPoint 文件。

  • slide:选择要操作的幻灯片。

6.1.4 添加矩形框

shape = slide.shapes.add_shape(autoshape_type_id=MSO_SHAPE.RECTANGLE, left=Cm(Left), top=Cm(Top), width=Cm(Width), height=Cm(Height))
  • add_shape:在幻灯片上添加一个矩形框,位置和大小由 lefttopwidth 和 height 参数决定。

  • autoshape_type_id=MSO_SHAPE.RECTANGLE这一句是设置为长方形,要查看所有可用的形状类型,可以查阅 python-pptx 的官方文档MSO_AUTO_SHAPE_TYPE或直接查看 pptx.enum.shapes.MSO_SHAPE 的源代码如下

    ​from pptx.enum.shapes import MSO_SHAPE# 打印所有 MSO_SHAPE 的成员for shape_name in dir(MSO_SHAPE): if not shape_name.startswith(\'__\'): # 过滤掉内置方法 print(shape_name)​
  • 罗列所有形状的参数,需要的小伙伴可以看看

    ACTION_BUTTON_BACK_OR_PREVIOUS:后退或上一项动作按钮ACTION_BUTTON_BEGINNING:开始动作按钮ACTION_BUTTON_CUSTOM:自定义动作按钮ACTION_BUTTON_DOCUMENT:文档动作按钮ACTION_BUTTON_END:结束动作按钮ACTION_BUTTON_FORWARD_OR_NEXT:前进或下一项动作按钮ACTION_BUTTON_HELP:帮助动作按钮ACTION_BUTTON_HOME:主页动作按钮ACTION_BUTTON_INFORMATION:信息动作按钮ACTION_BUTTON_MOVIE:影片动作按钮ACTION_BUTTON_RETURN:返回动作按钮ACTION_BUTTON_SOUND:声音动作按钮ARC:弧形BALLOON:气球BENT_ARROW:弯曲箭头BENT_UP_ARROW:向上弯曲箭头BEVEL:斜角BLOCK_ARC:块弧形CAN:罐形CHART_PLUS:图表加号CHART_STAR:图表星形CHART_X:图表叉号CHEVRON:V形标志CHORD:弦形CIRCULAR_ARROW:环形箭头CLOUD:云形CLOUD_CALLOUT:云形标注CORNER:角落CORNER_TABS:角落标签CROSS:十字形CUBE:立方体CURVED_DOWN_ARROW:向下弯曲箭头CURVED_DOWN_RIBBON:向下弯曲丝带CURVED_LEFT_ARROW:向左弯曲箭头CURVED_RIGHT_ARROW:向右弯曲箭头CURVED_UP_ARROW:向上弯曲箭头CURVED_UP_RIBBON:向上弯曲丝带DECAGON:十边形DIAGONAL_STRIPE:对角条纹DIAMOND:菱形DODECAGON:十二边形DONUT:圆环DOUBLE_BRACE:双大括号DOUBLE_BRACKET:双方括号DOUBLE_WAVE:双波浪形DOWN_ARROW:向下箭头DOWN_ARROW_CALLOUT:向下箭头标注DOWN_RIBBON:向下丝带EXPLOSION1:爆炸形1EXPLOSION2:爆炸形2FLOWCHART_ALTERNATE_PROCESS:流程图交替过程FLOWCHART_CARD:流程图卡片FLOWCHART_COLLATE:流程图校对FLOWCHART_CONNECTOR:流程图连接器FLOWCHART_DATA:流程图数据FLOWCHART_DECISION:流程图决策FLOWCHART_DELAY:流程图延迟FLOWCHART_DIRECT_ACCESS_STORAGE:流程图直接访问存储FLOWCHART_DISPLAY:流程图显示FLOWCHART_DOCUMENT:流程图文档FLOWCHART_EXTRACT:流程图提取FLOWCHART_INTERNAL_STORAGE:流程图内部存储FLOWCHART_MAGNETIC_DISK:流程图磁盘FLOWCHART_MANUAL_INPUT:流程图手动输入FLOWCHART_MANUAL_OPERATION:流程图手动操作FLOWCHART_MERGE:流程图合并FLOWCHART_MULTIDOCUMENT:流程图多文档FLOWCHART_OFFLINE_STORAGE:流程图离线存储FLOWCHART_OFFPAGE_CONNECTOR:流程图离页连接器FLOWCHART_OR:流程图或FLOWCHART_PREDEFINED_PROCESS:流程图预定义过程FLOWCHART_PREPARATION:流程图准备FLOWCHART_PROCESS:流程图过程FLOWCHART_PUNCHED_TAPE:流程图穿孔纸带FLOWCHART_SEQUENTIAL_ACCESS_STORAGE:流程图顺序访问存储FLOWCHART_SORT:流程图排序FLOWCHART_STORED_DATA:流程图存储数据FLOWCHART_SUMMING_JUNCTION:流程图求和连接点FLOWCHART_TERMINATOR:流程图终止符FOLDED_CORNER:折角FRAME:框架FUNNEL:漏斗GEAR_6:6齿齿轮GEAR_9:9齿齿轮HALF_FRAME:半框架HEART:心形HEPTAGON:七边形HEXAGON:六边形HORIZONTAL_SCROLL:水平卷轴ISOSCELES_TRIANGLE:等腰三角形LEFT_ARROW:向左箭头LEFT_ARROW_CALLOUT:向左箭头标注LEFT_BRACE:左大括号LEFT_BRACKET:左方括号LEFT_CIRCULAR_ARROW:向左环形箭头LEFT_RIGHT_ARROW:左右箭头LEFT_RIGHT_ARROW_CALLOUT:左右箭头标注LEFT_RIGHT_CIRCULAR_ARROW:左右环形箭头LEFT_RIGHT_RIBBON:左右丝带LEFT_RIGHT_UP_ARROW:左右上箭头LEFT_UP_ARROW:左上箭头LIGHTNING_BOLT:闪电LINE_CALLOUT_1:标注线1LINE_CALLOUT_1_ACCENT_BAR:带强调条的标注线1LINE_CALLOUT_1_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线1LINE_CALLOUT_1_NO_BORDER:无边框的标注线1LINE_CALLOUT_2:标注线2LINE_CALLOUT_2_ACCENT_BAR:带强调条的标注线2LINE_CALLOUT_2_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线2LINE_CALLOUT_2_NO_BORDER:无边框的标注线2LINE_CALLOUT_3:标注线3LINE_CALLOUT_3_ACCENT_BAR:带强调条的标注线3LINE_CALLOUT_3_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线3LINE_CALLOUT_3_NO_BORDER:无边框的标注线3LINE_CALLOUT_4:标注线4LINE_CALLOUT_4_ACCENT_BAR:带强调条的标注线4LINE_CALLOUT_4_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线4LINE_CALLOUT_4_NO_BORDER:无边框的标注线4LINE_INVERSE:反直线MATH_DIVIDE:除号MATH_EQUAL:等号MATH_MINUS:减号MATH_MULTIPLY:乘号MATH_NOT_EQUAL:不等号MATH_PLUS:加号MOON:月亮NON_ISOSCELES_TRAPEZOID:非等腰梯形NOTCHED_RIGHT_ARROW:缺口向右箭头NO_SYMBOL:无符号OCTAGON:八边形OVAL:椭圆形OVAL_CALLOUT:椭圆形标注PARALLELOGRAM:平行四边形PENTAGON:五边形PIE:饼形PIE_WEDGE:饼形楔子PLAQUE:徽章PLAQUE_TABS:徽章标签QUAD_ARROW:四向箭头QUAD_ARROW_CALLOUT:四向箭头标注RECTANGLE:长方形RECTANGULAR_CALLOUT:长方形标注REGULAR_PENTAGON:正五边形RIGHT_ARROW:向右箭头RIGHT_ARROW_CALLOUT:向右箭头标注RIGHT_BRACE:右大括号RIGHT_BRACKET:右方括号RIGHT_TRIANGLE:直角三角形ROUNDED_RECTANGLE:圆角长方形ROUNDED_RECTANGULAR_CALLOUT:圆角长方形标注ROUND_1_RECTANGLE:单圆角长方形ROUND_2_DIAG_RECTANGLE:双对角圆角长方形ROUND_2_SAME_RECTANGLE:双同侧圆角长方形SMILEY_FACE:笑脸SNIP_1_RECTANGLE:单切角长方形SNIP_2_DIAG_RECTANGLE:双对角切角长方形SNIP_2_SAME_RECTANGLE:双同侧切角长方形SNIP_ROUND_RECTANGLE:切角圆角长方形SQUARE_TABS:方形标签STAR_10_POINT:10角星STAR_12_POINT:12角星STAR_16_POINT:16角星STAR_24_POINT:24角星STAR_32_POINT:32角星STAR_4_POINT:4角星STAR_5_POINT:5角星STAR_6_POINT:6角星STAR_7_POINT:7角星STAR_8_POINT:8角星STRIPED_RIGHT_ARROW:条纹向右箭头SUN:太阳SWOOSH_ARROW:嗖嗖箭头TEAR:泪滴形TRAPEZOID:梯形UP_ARROW:向上箭头UP_ARROW_CALLOUT:向上箭头标注UP_DOWN_ARROW:上下箭头UP_DOWN_ARROW_CALLOUT:上下箭头标注UP_RIBBON:向上丝带U_TURN_ARROW:U形转弯箭头VERTICAL_SCROLL:垂直卷轴WAVE:波浪形as_integer_ratio:转换为整数比bit_count:比特计数bit_length:比特长度conjugate:共轭denominator:分母from_bytes:从字节转换imag:虚部is_integer:是否为整数numerator:分子real:实部to_bytes:转换为字节

6.1.5设置矩形框的旋转角度

shape.rotation = rotation

6.1.6设置矩形框的填充颜色

fill = shape.fillfill.solid()
  • fill.solid():将矩形框的填充设置为纯色。

根据 fore_color 参数的不同,设置不同的颜色,使用if语句,若没有需求颜色可自行添加:

if fore_color == \'gray\': fill.fore_color.rgb = RGBColor(242, 242, 242) line.color.rgb = RGBColor(242, 242, 242)elif fore_color == \'gray1\': fill.fore_color.rgb = RGBColor(127, 127, 127) line.color.rgb = RGBColor(127, 127, 127)elif fore_color == \'blue\': fill.fore_color.rgb = RGBColor(0, 30, 80) line.color.rgb = RGBColor(0, 30, 80)elif fore_color == \'red\': fill.fore_color.rgb = RGBColor(192, 0, 0) line.color.rgb = RGBColor(192, 0, 0)elif fore_color == \'yellow\': fill.fore_color.rgb = RGBColor(255, 255, 0) line.color.rgb = RGBColor(255, 255, 0)elif fore_color == \'white\': fill.fore_color.rgb = RGBColor(255, 255, 255) line.color.rgb = RGBColor(255, 255, 255)elif fore_color == \'lightblue\': fill.fore_color.rgb = RGBColor(212, 228, 255) line.color.rgb = RGBColor(212, 228, 255)
  • fill.fore_color.rgb:设置矩形框的填充颜色。

  • line.color.rgb:设置矩形框边框的颜色。

6.1.7设置矩形框为背景(可选)

if shape_is_background == True: shape.fill.background()
  • shape.fill.background():将矩形框设置为背景。

6.1.8设置矩形框的边框宽度

line.color.brightness = 0line.width = Pt(line_width)line.fill.background() # 调成背景色
  • line.width:设置矩形框边框的宽度。

  • line.fill.background():将边框颜色设置为背景色。

6.1.9保存 PPT 文件

prs.save(ppt_script)
  • prs.save(ppt_script):保存对 PPT 文件的修改。

6.1.10调用函数

ppt_script = \'销售周报.pptx\'shape_rectangle(ppt_script)
  • 调用 shape_rectangle 函数,在 销售周报.pptx 的第一页添加一个默认样式的矩形框。

6.2项目新增形状

6.2.1完善office_ppt_ser.py

项目将在 5.2节项目新增文本框的基础上继续推进,进一步完善代码,增加形状的功能。具体实现方式是将上述函数迁移至 office_ppt_ser.py 文件中。

import os # 文件类模块from pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.shapes import MSO_SHAPEfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Ptdef new_ppt_add_slide(template, page_num=[0], PPT_Name=\'新建 Microsoft PowerPoint 演示文稿.pptx\',save_path=\'C:\\\\Users\\\\weidong.guo\\\\Desktop\'): \"\"\" :param template: PPT模板 :param page_num: 列表,代表PPT模板里面的幻灯片序号,从0开始 :param PPT_Name: PPT名字 :param save_path: 保存路径 :return:返回新的PPT路径 \"\"\" if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起 else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接 prs = Presentation(template) # 用Presentation读取PPT模板 for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 模板template中增加幻灯片 prs.save(new_ppt_path) # 对ppt保存 return new_ppt_pathdef ppt_slide_number(ppt_script): prs = Presentation(ppt_script) slide_number = len(prs.slides) return slide_numberdef titlebox(ppt_script, page_num=0, content_text=\'Backup\', font_size=18, left=0.55, top=2.12, width=25.81, height=1.08, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'\', alignment=\'左对齐\', word_wrap=False): \"\"\" 参数: ppt_script (str): PPT文件路径。 page_num (int): 幻灯片页码(从0开始)。 content_text (str): 文本框内容。 font_size (int): 字体大小(单位:磅)。 left (float): 文本框左上角的水平位置(单位:厘米)。 top (float): 文本框左上角的垂直位置(单位:厘米)。 width (float): 文本框宽度(单位:厘米)。 height (float): 文本框高度(单位:厘米)。 font_bold (bool): 是否加粗。 font_name (str): 字体名称。 font_color (str): 字体颜色(支持\'blue\', \'green\', \'red\', \'yellow\', \'orange\', \'white\', \'gray1\', \'black\')。 alignment (str): 对齐方式(支持\'左对齐\', \'居中\')。 word_wrap (bool): 是否自动换行。 return: \"\"\" # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加文本框 textbox = slide.shapes.add_textbox(Cm(left), Cm(top), Cm(width), Cm(height)) tf = textbox.text_frame tf.word_wrap = word_wrap # 在文本框中写入文字 # 题目 para = tf.paragraphs[0] # 新增段落 para.text = content_text # 向段落写入文字 if font_color == \'blue\': para.font.color.rgb = RGBColor(0, 30, 80) # 蓝色 elif font_color == \'green\': para.font.color.rgb = RGBColor(0, 176, 80) # 绿色 elif font_color == \'red\': para.font.color.rgb = RGBColor(255, 0, 0) # 红色 elif font_color == \'yellow\': para.font.color.rgb = RGBColor(255, 255, 0) # 红色 elif font_color == \'orange\': para.font.color.rgb = RGBColor(255, 192, 0) # 红色 elif font_color == \'white\': para.font.color.rgb = RGBColor(255, 255, 255) # 红色 elif font_color == \'gray1\': para.font.color.rgb = RGBColor(182, 191, 197) # 红色 else: para.font.color.rgb = RGBColor(0, 0, 0) # 黑色 if alignment == \'左对齐\': para.alignment = PP_ALIGN.LEFT else: para.alignment = PP_ALIGN.CENTER # 居中 # 设置字体 font = para.font font.name = font_name # 字体类型 font.bold = font_bold # 加粗 font.size = Pt(font_size) # 大小 prs.save(ppt_script) # 对ppt保存# 在PPT中添加矩形框def shape_rectangle(ppt_script, page_num=0, Left=0.96, Top=3.2, Width=12.5, Height=5.87, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加矩形 shape = slide.shapes.add_shape(autoshape_type_id=MSO_SHAPE.RECTANGLE, left=Cm(Left), top=Cm(Top), width=Cm(Width), height=Cm(Height)) # 调整角度 shape.rotation = rotation # 填充背景色 fill = shape.fill fill.solid() # 调整线宽 line = shape.line if fore_color == \'gray\': fill.fore_color.rgb = RGBColor(242, 242, 242) line.color.rgb = RGBColor(242, 242, 242) elif fore_color == \'gray1\': fill.fore_color.rgb = RGBColor(127, 127, 127) line.color.rgb = RGBColor(127, 127, 127) elif fore_color == \'blue\': fill.fore_color.rgb = RGBColor(0, 30, 80) line.color.rgb = RGBColor(0, 30, 80) elif fore_color == \'red\': fill.fore_color.rgb = RGBColor(192, 0, 0) line.color.rgb = RGBColor(192, 0, 0) elif fore_color == \'yellow\': fill.fore_color.rgb = RGBColor(255, 255, 0) line.color.rgb = RGBColor(255, 255, 0) elif fore_color == \'white\': fill.fore_color.rgb = RGBColor(255, 255, 255) line.color.rgb = RGBColor(255, 255, 255) elif fore_color == \'lightblue\': fill.fore_color.rgb = RGBColor(212, 228, 255) line.color.rgb = RGBColor(212, 228, 255) # fill.fore_color.brightness = 0 # 设为透明 if shape_is_background == True: shape.fill.background() # fill.background() # fill.back_color.rgb = RGBColor(255, 255, 255) line.color.brightness = 0 line.width = Pt(line_width) line.fill.background() # 调成背景色 prs.save(ppt_script) # 对ppt保存

6.2.2完善main.py

先看看我们的样板,可以发现有2处是长方形框,要依此了解这2处文字设置的位置、背景色等,并把相应参数更改即可

main.py代码如下

from office_ppt_ser import new_ppt_add_slidefrom office_ppt_ser import ppt_slide_numberfrom office_ppt_ser import titleboxfrom office_ppt_ser import shape_rectangledef main(): new_ppt = r\'PPT模版.pptx\' new_ppt_path = new_ppt_add_slide(new_ppt, page_num=[1], PPT_Name=\'销售周报.pptx\') print(new_ppt_path) slide_number = ppt_slide_number(new_ppt_path) print(new_ppt_path) # 部门报告 titlebox(new_ppt_path, page_num=0, content_text=\'部门报告\', font_size=20, left=0.55, top=0.94, width=3.36, height=1.11, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'blue\', alignment=\'左对齐\', word_wrap=False) # ■部门商品库存记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品库存记录\', font_size=12, left=0.58, top=2.14, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■部门商品销售记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品销售记录\', font_size=12, left=0.58, top=6.34, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■总结 titlebox(new_ppt_path, page_num=0, content_text=\'■总结\', font_size=12, left=0.58, top=11.65, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000 titlebox(new_ppt_path, page_num=0, content_text=\'2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000\', font_size=12, left=0.58, top=12.58, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 方框1 shape_rectangle(new_ppt_path, page_num=0, Left=15.89, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 方框2 shape_rectangle(new_ppt_path, page_num=0, Left=19.54, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 红灯 titlebox(new_ppt_path, page_num=0, content_text=\'红灯\', font_size=18, left=16.68, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 绿灯 titlebox(new_ppt_path, page_num=0, content_text=\'绿灯\', font_size=18, left=20.32, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False)# 按装订区域中的绿色按钮以运行脚本。if __name__ == \'__main__\': main()

6.2.3项目效果

分享上述完整代码路径:
链接: https://pan.baidu.com/s/1-FtAfU0okSl0nFXgqqdL7g?pwd=g796 提取码: g796

7图片

在 python-pptx 库中,图片(Image)是 PowerPoint 幻灯片中的一种特殊形状。在python-pptx中使用 slide.shapes.add_picture() 方法可以在幻灯片中插入图片。该方法需要指定图片文件的路径以及图片的位置和大小。接下来将根据一个函数-插入图片进行详细讲解。

7.1函数-插入图片

import osfrom pptx import Presentationfrom pptx.util import Cm# 在PPT中添加矩形框def add_picture(img_path, ppt_script, page_num=0, left=0, top=0, width=4): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # Left, Top, Width, Height = Cm(left), Cm(top), Cm(width), Cm(height) # 预设位置及大小 # slide.shapes.add_picture(img_path, Left, Top, Width, Height) # 在指定位置按预设值添加图片 Left, Top, Width = Cm(left), Cm(top), Cm(width) # 预设位置及大小 slide.shapes.add_picture(img_path, Left, Top, Width) # 在指定位置按预设值添加图片 prs.save(ppt_script) # 对ppt保存ppt_script = \'销售周报.pptx\'img_path = os.path.abspath(r\'.\\icon\\logo.png\')add_picture(img_path, ppt_script)

代码解读

7.1.1导入模块

import osfrom pptx import Presentationfrom pptx.util import Cm
  • os: Python 标准库,用于处理文件路径和操作系统相关功能。

  • pptxpython-pptx 库,用于创建和修改 PowerPoint 文件。

  • Cmpptx.util 中的工具函数,用于将厘米转换为 python-pptx 所需的单位。

7.1.2定义 add_picture 函数

def add_picture(img_path, ppt_script, page_num=0, left=0, top=0, width=4):
  • 功能: 在指定的 PowerPoint 文件的某一页幻灯片中插入图片。

  • 参数:

    • img_path: 图片的路径。

    • ppt_script: PowerPoint 文件的路径。

    • page_num: 要插入图片的幻灯片页码(默认是第一页,索引为 0)。

    • left: 图片左侧距离幻灯片左侧的距离(默认 0 厘米)。

    • top: 图片顶部距离幻灯片顶部的距离(默认 0 厘米)。

    • width: 图片的宽度(默认 4 厘米)。

7.1.3加载 PowerPoint 文件

prs = Presentation(ppt_script)
  • 使用 Presentation(ppt_script) 加载指定的 PowerPoint 文件(ppt_script 是文件路径)。

7.1.4获取指定幻灯片

slide = prs.slides[page_num]
  • 通过 prs.slides[page_num] 获取指定页码的幻灯片对象(page_num 是幻灯片的索引,从 0 开始)。

7.1.5设置图片的位置和大小

Left, Top, Width = Cm(left), Cm(top), Cm(width)
  • 使用 Cm() 函数将厘米转换为 python-pptx 所需的单位。

  • Left: 图片左侧距离幻灯片左侧的距离。

  • Top: 图片顶部距离幻灯片顶部的距离。

  • Width: 图片的宽度(高度会根据宽度自动调整,保持图片的原始宽高比)。

7.1.6插入图片

slide.shapes.add_picture(img_path, Left, Top, Width)
  • 使用 slide.shapes.add_picture() 方法将图片插入到幻灯片中。

  • 参数:

    • img_path: 图片路径。

    • Left: 图片的左侧位置。

    • Top: 图片的顶部位置。

    • Width: 图片的宽度。

7.1.7保存 PowerPoint 文件

prs.save(ppt_script)
  • 使用 prs.save() 方法保存修改后的 PowerPoint 文件(覆盖原文件)。

7.1.8调用函数

ppt_script = \'销售周报.pptx\'img_path = os.path.abspath(r\'.\\icon\\logo.png\')add_picture(img_path, ppt_script)
  • ppt_script: PowerPoint 文件的路径(销售周报.pptx)。

  • img_path: 图片的路径(使用 os.path.abspath() 将相对路径转换为绝对路径)。

  • add_picture(): 调用函数,将图片插入到 PowerPoint 文件的第一页幻灯片中。

7.2项目新增图片

7.2.1完善office_ppt_ser.py

项目将在 6.2节‘项目新增形状’的基础上继续推进,进一步完善代码,增加图片的功能。具体实现方式是将上述函数迁移至 office_ppt_ser.py 文件中。

import osfrom pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.shapes import MSO_SHAPEfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Ptdef new_ppt_add_slide(template, page_num=[0], PPT_Name=\'新建 Microsoft PowerPoint 演示文稿.pptx\',save_path=\'C:\\\\Users\\\\weidong.guo\\\\Desktop\'): \"\"\" :param template: PPT模板 :param page_num: 列表,代表PPT模板里面的幻灯片序号,从0开始 :param PPT_Name: PPT名字 :param save_path: 保存路径 :return:返回新的PPT路径 \"\"\" if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起 else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接 prs = Presentation(template) # 用Presentation读取PPT模板 for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 模板template中增加幻灯片 prs.save(new_ppt_path) # 对ppt保存 return new_ppt_pathdef ppt_slide_number(ppt_script): prs = Presentation(ppt_script) slide_number = len(prs.slides) return slide_numberdef titlebox(ppt_script, page_num=0, content_text=\'Backup\', font_size=18, left=0.55, top=2.12, width=25.81, height=1.08, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'\', alignment=\'左对齐\', word_wrap=False): \"\"\" 参数: ppt_script (str): PPT文件路径。 page_num (int): 幻灯片页码(从0开始)。 content_text (str): 文本框内容。 font_size (int): 字体大小(单位:磅)。 left (float): 文本框左上角的水平位置(单位:厘米)。 top (float): 文本框左上角的垂直位置(单位:厘米)。 width (float): 文本框宽度(单位:厘米)。 height (float): 文本框高度(单位:厘米)。 font_bold (bool): 是否加粗。 font_name (str): 字体名称。 font_color (str): 字体颜色(支持\'blue\', \'green\', \'red\', \'yellow\', \'orange\', \'white\', \'gray1\', \'black\')。 alignment (str): 对齐方式(支持\'左对齐\', \'居中\')。 word_wrap (bool): 是否自动换行。 return: \"\"\" # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加文本框 textbox = slide.shapes.add_textbox(Cm(left), Cm(top), Cm(width), Cm(height)) tf = textbox.text_frame tf.word_wrap = word_wrap # 在文本框中写入文字 # 题目 para = tf.paragraphs[0] # 新增段落 para.text = content_text # 向段落写入文字 if font_color == \'blue\': para.font.color.rgb = RGBColor(0, 30, 80) # 蓝色 elif font_color == \'green\': para.font.color.rgb = RGBColor(0, 176, 80) # 绿色 elif font_color == \'red\': para.font.color.rgb = RGBColor(255, 0, 0) # 红色 elif font_color == \'yellow\': para.font.color.rgb = RGBColor(255, 255, 0) # 红色 elif font_color == \'orange\': para.font.color.rgb = RGBColor(255, 192, 0) # 红色 elif font_color == \'white\': para.font.color.rgb = RGBColor(255, 255, 255) # 红色 elif font_color == \'gray1\': para.font.color.rgb = RGBColor(182, 191, 197) # 红色 else: para.font.color.rgb = RGBColor(0, 0, 0) # 黑色 if alignment == \'左对齐\': para.alignment = PP_ALIGN.LEFT else: para.alignment = PP_ALIGN.CENTER # 居中 # 设置字体 font = para.font font.name = font_name # 字体类型 font.bold = font_bold # 加粗 font.size = Pt(font_size) # 大小 prs.save(ppt_script) # 对ppt保存# 在PPT中添加矩形框def shape_rectangle(ppt_script, page_num=0, Left=0.96, Top=3.2, Width=12.5, Height=5.87, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加矩形 shape = slide.shapes.add_shape(autoshape_type_id=MSO_SHAPE.RECTANGLE, left=Cm(Left), top=Cm(Top), width=Cm(Width), height=Cm(Height)) # 调整角度 shape.rotation = rotation # 填充背景色 fill = shape.fill fill.solid() # 调整线宽 line = shape.line if fore_color == \'gray\': fill.fore_color.rgb = RGBColor(242, 242, 242) line.color.rgb = RGBColor(242, 242, 242) elif fore_color == \'gray1\': fill.fore_color.rgb = RGBColor(127, 127, 127) line.color.rgb = RGBColor(127, 127, 127) elif fore_color == \'blue\': fill.fore_color.rgb = RGBColor(0, 30, 80) line.color.rgb = RGBColor(0, 30, 80) elif fore_color == \'red\': fill.fore_color.rgb = RGBColor(192, 0, 0) line.color.rgb = RGBColor(192, 0, 0) elif fore_color == \'yellow\': fill.fore_color.rgb = RGBColor(255, 255, 0) line.color.rgb = RGBColor(255, 255, 0) elif fore_color == \'white\': fill.fore_color.rgb = RGBColor(255, 255, 255) line.color.rgb = RGBColor(255, 255, 255) elif fore_color == \'lightblue\': fill.fore_color.rgb = RGBColor(212, 228, 255) line.color.rgb = RGBColor(212, 228, 255) # fill.fore_color.brightness = 0 # 设为透明 if shape_is_background == True: shape.fill.background() # fill.background() # fill.back_color.rgb = RGBColor(255, 255, 255) line.color.brightness = 0 line.width = Pt(line_width) line.fill.background() # 调成背景色 prs.save(ppt_script) # 对ppt保存def add_picture(img_path, ppt_script, page_num=0, left=0, top=0, width=4): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # Left, Top, Width, Height = Cm(left), Cm(top), Cm(width), Cm(height) # 预设位置及大小 # slide.shapes.add_picture(img_path, Left, Top, Width, Height) # 在指定位置按预设值添加图片 Left, Top, Width = Cm(left), Cm(top), Cm(width) # 预设位置及大小 slide.shapes.add_picture(img_path, Left, Top, Width) # 在指定位置按预设值添加图片 prs.save(ppt_script) # 对ppt保存

7.2.2完善main.py

import osfrom office_ppt_ser import add_picturefrom office_ppt_ser import new_ppt_add_slidefrom office_ppt_ser import ppt_slide_numberfrom office_ppt_ser import shape_rectanglefrom office_ppt_ser import titleboxdef main(): new_ppt = r\'PPT模版.pptx\' new_ppt_path = new_ppt_add_slide(new_ppt, page_num=[1], PPT_Name=\'销售周报.pptx\') print(new_ppt_path) slide_number = ppt_slide_number(new_ppt_path) print(new_ppt_path) # 部门报告 titlebox(new_ppt_path, page_num=0, content_text=\'部门报告\', font_size=20, left=0.55, top=0.94, width=3.36, height=1.11, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'blue\', alignment=\'左对齐\', word_wrap=False) # ■部门商品库存记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品库存记录\', font_size=12, left=0.58, top=2.14, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■部门商品销售记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品销售记录\', font_size=12, left=0.58, top=6.34, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■总结 titlebox(new_ppt_path, page_num=0, content_text=\'■总结\', font_size=12, left=0.58, top=11.65, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000 titlebox(new_ppt_path, page_num=0, content_text=\'2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000\', font_size=12, left=0.58, top=12.58, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 方框1 shape_rectangle(new_ppt_path, page_num=0, Left=15.89, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 方框2 shape_rectangle(new_ppt_path, page_num=0, Left=19.54, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 红灯 titlebox(new_ppt_path, page_num=0, content_text=\'红灯\', font_size=18, left=16.68, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 绿灯 titlebox(new_ppt_path, page_num=0, content_text=\'绿灯\', font_size=18, left=20.32, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 增加图片 img_path = os.path.abspath(r\'.\\icon\\logo.png\') add_picture(img_path, new_ppt_path, page_num=0, left=23.25, top=0.12, width=1.7)# 按装订区域中的绿色按钮以运行脚本。if __name__ == \'__main__\': main()

7.2.3效果展示

需要注意的是增加图片素材

分享上述完整代码路径:
链接: https://pan.baidu.com/s/1Au0sqXcPA6--GA9WBZWvGg?pwd=paxm 提取码: paxm

8表格

在 python-pptx 库中,表格(Table)是 PowerPoint 幻灯片中的一种特殊形状,在python-pptx中使用 slide.shapes.add_table() 方法可以在幻灯片中插入表格。该方法需要指定表格的行数、列数以及表格的位置和大小。接下来将根据一个函数-插入表格(N行17列)进行详细讲解。

8.1函数-插入表格

import osimport pandas as pdfrom pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.text import MSO_ANCHORfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Pt# 在PPT中添加矩形框def table_Nrows_17cols(ppt_script, page_num=0, title_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], col_width=[1.15, 2, 5.2, 1, 1.4, 1.4, 1, 1, 1, 1, 1.4, 1, 1, 1, 1, 1, 1], row_height=0.56, fontname=\'方正兰亭黑_GBK\', fontsize=6, leftx=0.55, topx=2.85, df=pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4 })): prs = Presentation(ppt_script) slide = prs.slides[page_num] if df.shape[0] > 13: rows, cols = 14, 17 # 设定5行 14列 else: rows = df.shape[0] + 1 cols = 17 print(\'>>>>>>>>>>>>>\') print(rows, cols) left = Cm(leftx) top = Cm(topx) col_temp = 0 # 计算表格总列宽 for i in range(cols): col_temp += col_width[i] width = Cm(col_temp) # 计算表格总行宽 height = Cm(row_height * rows) heightx = row_height * rows table = slide.shapes.add_table(rows, cols, left, top, width, height).table for i in range(cols): table.columns[i].width = Cm(col_width[i]) # 列高 # 填写表格表头 for j in range(cols): table.cell(0, j).text = str(title_list[j]) # 填写表格内容 if df.shape[0] > 13: for i in range(rows - 1): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j]) else: for i in range(df.shape[0]): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j]) # 行宽 for i in range(0, rows): table.rows[i].heigth = Cm(row_height) # 修改表格样式 for row in range(rows): for col in range(cols): # Write column titles new = table.cell(row, col).text_frame.paragraphs[0] new.font.name = fontname if row == 0: # 设置文字大小 table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) # 设置文字颜色 table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255) # 设置文字左右对齐 table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER # 设置文字上下对齐 table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE # 设置背景为填充 table.cell(row, col).fill.solid() # 设置背景颜色 table.cell(row, col).fill.fore_color.rgb = RGBColor(0, 30, 80) else: table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE table.cell(row, col).fill.solid() if row % 2 == 0:  table.cell(row, col).fill.fore_color.rgb = RGBColor(231, 231, 233) else:  table.cell(row, col).fill.fore_color.rgb = RGBColor(203, 204, 208) prs.save(ppt_script) # 对ppt保存 return heightxppt_script = \'销售周报.pptx\'img_path = os.path.abspath(r\'.\\icon\\logo.png\')table_Nrows_17cols(ppt_script)

代码解读

这段代码的主要功能是通过 python-pptx 库在 PowerPoint 文件中自动生成一个表格,并将 Pandas 数据框中的数据填充到表格中。以下是代码的详细解读:

8.1.1导入库

import pandas as pdfrom pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.text import MSO_ANCHOR, PP_ALIGNfrom pptx.util import Cm, Pt
  • pandas as pd: 用于处理数据框(DataFrame)。

  • pptx: 用于操作 PowerPoint 文件。

    • Presentation: 用于创建或打开 PPT 文件。

    • RGBColor: 用于设置颜色。

    • MSO_ANCHORPP_ALIGN: 用于设置文本的对齐方式。

    • CmPt: 用于设置长度单位(厘米和磅)。

8.1.2定义函数 table_Nrows_17cols

def table_Nrows_17cols(ppt_script, page_num=0, title_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], col_width=[1.15, 2, 5.2, 1, 1.4, 1.4, 1, 1, 1, 1, 1.4, 1, 1, 1, 1, 1, 1], row_height=0.56, fontname=\'方正兰亭黑_GBK\', fontsize=6, leftx=0.55, topx=2.85, df=pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4 })):
  • 参数说明:

    • ppt_script: PPT 文件路径。

    • page_num: 操作的幻灯片页码(默认第 0 页)。

    • title_list: 表格的表头内容(默认 17 列)。

    • col_width: 每列的宽度(单位:厘米)。

    • row_height: 每行的高度(单位:厘米)。

    • fontname: 字体名称。

    • fontsize: 字体大小(单位:磅)。

    • leftxtopx: 表格左上角的坐标(单位:厘米)。

    • df: 要填充到表格中的数据框(默认生成一个 5 行 17 列的 DataFrame)。

8.1.3打开 PPT 文件并选择幻灯片

prs = Presentation(ppt_script)slide = prs.slides[page_num]
  • 打开指定的 PPT 文件,并选择要操作的幻灯片。

8.1.4确定表格的行数和列数

if df.shape[0] > 13: rows, cols = 14, 17 # 设定5行 14列else: rows = df.shape[0] + 1 cols = 17
  • 如果数据框的行数超过 13 行,则表格设置为 14 行(包括表头);否则,表格行数为数据框行数加 1(表头)。

  • 列数固定为 17 列。

8.1.5计算表格的总宽度和高度

left = Cm(leftx)top = Cm(topx)col_temp = 0for i in range(cols): col_temp += col_width[i]width = Cm(col_temp)height = Cm(row_height * rows)heightx = row_height * rows
  • left 和 top 是表格左上角的坐标。

  • col_temp 是表格的总宽度(各列宽度之和)。

  • width 和 height 是表格的总宽度和高度(单位:厘米)。

  • heightx 是表格的总高度(单位:厘米),用于返回值。

8.1.6添加表格到幻灯片

table = slide.shapes.add_table(rows, cols, left, top, width, height).tablefor i in range(cols): table.columns[i].width = Cm(col_width[i]) # 列高
  • 在幻灯片中添加一个表格,并设置每列的宽度。

8.1.7填充表头和数据

# 填写表格表头for j in range(cols): table.cell(0, j).text = str(title_list[j])# 填写表格内容if df.shape[0] > 13: for i in range(rows - 1): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j])else: for i in range(df.shape[0]): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j])
  • 表头填充:将 title_list 的内容写入表格的第一行。

  • 数据填充:将数据框 df 的内容写入表格的其余行。

8.1.8设置行高

for i in range(0, rows): table.rows[i].heigth = Cm(row_height)
  • 设置每行的高度。

8.1.9修改表格样式

for row in range(rows): for col in range(cols): new = table.cell(row, col).text_frame.paragraphs[0] new.font.name = fontname if row == 0: # 设置表头样式 table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255) table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE table.cell(row, col).fill.solid() table.cell(row, col).fill.fore_color.rgb = RGBColor(0, 30, 80) else: # 设置数据行样式 table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE table.cell(row, col).fill.solid() if row % 2 == 0: table.cell(row, col).fill.fore_color.rgb = RGBColor(231, 231, 233) else: table.cell(row, col).fill.fore_color.rgb = RGBColor(203, 204, 208)
  • 设置表格的样式:

    • 表头:白色文字、深蓝色背景、居中对齐。

    • 数据行:黑色文字、交替浅灰色背景、居中对齐。

8.1.10保存 PPT 文件

prs.save(ppt_script) # 对ppt保存return heightx
  • 保存修改后的 PPT 文件,并返回表格的总高度。

8.1.11调用函数

ppt_script = \'销售周报.pptx\'table_Nrows_17cols(ppt_script)
  • 调用函数,在指定的 PPT 文件中生成表格。

8.2项目新增表格

8.2.1完善office_ppt_ser.py

项目将在 7.2节‘项目新增图片’的基础上继续推进,进一步完善代码,增加表格的功能。具体实现方式是将上述函数迁移至 office_ppt_ser.py 文件中。

import osimport pandas as pdfrom pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.shapes import MSO_SHAPEfrom pptx.enum.text import MSO_ANCHORfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Ptdef new_ppt_add_slide(template, page_num=[0], PPT_Name=\'新建 Microsoft PowerPoint 演示文稿.pptx\',save_path=\'C:\\\\Users\\\\weidong.guo\\\\Desktop\'): \"\"\" :param template: PPT模板 :param page_num: 列表,代表PPT模板里面的幻灯片序号,从0开始 :param PPT_Name: PPT名字 :param save_path: 保存路径 :return:返回新的PPT路径 \"\"\" if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起 else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接 prs = Presentation(template) # 用Presentation读取PPT模板 for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 模板template中增加幻灯片 prs.save(new_ppt_path) # 对ppt保存 return new_ppt_pathdef ppt_slide_number(ppt_script): prs = Presentation(ppt_script) slide_number = len(prs.slides) return slide_numberdef titlebox(ppt_script, page_num=0, content_text=\'Backup\', font_size=18, left=0.55, top=2.12, width=25.81, height=1.08, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'\', alignment=\'左对齐\', word_wrap=False): \"\"\" 参数: ppt_script (str): PPT文件路径。 page_num (int): 幻灯片页码(从0开始)。 content_text (str): 文本框内容。 font_size (int): 字体大小(单位:磅)。 left (float): 文本框左上角的水平位置(单位:厘米)。 top (float): 文本框左上角的垂直位置(单位:厘米)。 width (float): 文本框宽度(单位:厘米)。 height (float): 文本框高度(单位:厘米)。 font_bold (bool): 是否加粗。 font_name (str): 字体名称。 font_color (str): 字体颜色(支持\'blue\', \'green\', \'red\', \'yellow\', \'orange\', \'white\', \'gray1\', \'black\')。 alignment (str): 对齐方式(支持\'左对齐\', \'居中\')。 word_wrap (bool): 是否自动换行。 return: \"\"\" # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加文本框 textbox = slide.shapes.add_textbox(Cm(left), Cm(top), Cm(width), Cm(height)) tf = textbox.text_frame tf.word_wrap = word_wrap # 在文本框中写入文字 # 题目 para = tf.paragraphs[0] # 新增段落 para.text = content_text # 向段落写入文字 if font_color == \'blue\': para.font.color.rgb = RGBColor(0, 30, 80) # 蓝色 elif font_color == \'green\': para.font.color.rgb = RGBColor(0, 176, 80) # 绿色 elif font_color == \'red\': para.font.color.rgb = RGBColor(255, 0, 0) # 红色 elif font_color == \'yellow\': para.font.color.rgb = RGBColor(255, 255, 0) # 红色 elif font_color == \'orange\': para.font.color.rgb = RGBColor(255, 192, 0) # 红色 elif font_color == \'white\': para.font.color.rgb = RGBColor(255, 255, 255) # 红色 elif font_color == \'gray1\': para.font.color.rgb = RGBColor(182, 191, 197) # 红色 else: para.font.color.rgb = RGBColor(0, 0, 0) # 黑色 if alignment == \'左对齐\': para.alignment = PP_ALIGN.LEFT else: para.alignment = PP_ALIGN.CENTER # 居中 # 设置字体 font = para.font font.name = font_name # 字体类型 font.bold = font_bold # 加粗 font.size = Pt(font_size) # 大小 prs.save(ppt_script) # 对ppt保存# 在PPT中添加矩形框def shape_rectangle(ppt_script, page_num=0, Left=0.96, Top=3.2, Width=12.5, Height=5.87, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加矩形 shape = slide.shapes.add_shape(autoshape_type_id=MSO_SHAPE.RECTANGLE, left=Cm(Left), top=Cm(Top), width=Cm(Width), height=Cm(Height)) # 调整角度 shape.rotation = rotation # 填充背景色 fill = shape.fill fill.solid() # 调整线宽 line = shape.line if fore_color == \'gray\': fill.fore_color.rgb = RGBColor(242, 242, 242) line.color.rgb = RGBColor(242, 242, 242) elif fore_color == \'gray1\': fill.fore_color.rgb = RGBColor(127, 127, 127) line.color.rgb = RGBColor(127, 127, 127) elif fore_color == \'blue\': fill.fore_color.rgb = RGBColor(0, 30, 80) line.color.rgb = RGBColor(0, 30, 80) elif fore_color == \'red\': fill.fore_color.rgb = RGBColor(192, 0, 0) line.color.rgb = RGBColor(192, 0, 0) elif fore_color == \'yellow\': fill.fore_color.rgb = RGBColor(255, 255, 0) line.color.rgb = RGBColor(255, 255, 0) elif fore_color == \'white\': fill.fore_color.rgb = RGBColor(255, 255, 255) line.color.rgb = RGBColor(255, 255, 255) elif fore_color == \'lightblue\': fill.fore_color.rgb = RGBColor(212, 228, 255) line.color.rgb = RGBColor(212, 228, 255) # fill.fore_color.brightness = 0 # 设为透明 if shape_is_background == True: shape.fill.background() # fill.background() # fill.back_color.rgb = RGBColor(255, 255, 255) line.color.brightness = 0 line.width = Pt(line_width) line.fill.background() # 调成背景色 prs.save(ppt_script) # 对ppt保存def add_picture(img_path, ppt_script, page_num=0, left=0, top=0, width=4): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # Left, Top, Width, Height = Cm(left), Cm(top), Cm(width), Cm(height) # 预设位置及大小 # slide.shapes.add_picture(img_path, Left, Top, Width, Height) # 在指定位置按预设值添加图片 Left, Top, Width = Cm(left), Cm(top), Cm(width) # 预设位置及大小 slide.shapes.add_picture(img_path, Left, Top, Width) # 在指定位置按预设值添加图片 prs.save(ppt_script) # 对ppt保存# 在PPT中表格def table_Nrows_17cols(ppt_script, page_num=0, title_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], col_width=[1.15, 2, 5.2, 1, 1.4, 1.4, 1, 1, 1, 1, 1.4, 1, 1, 1, 1, 1, 1], row_height=0.56, fontname=\'方正兰亭黑_GBK\', fontsize=6, leftx=0.55, topx=2.85, df=pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4 })): prs = Presentation(ppt_script) slide = prs.slides[page_num] if df.shape[0] > 13: rows, cols = 14, 17 # 设定5行 14列 else: rows = df.shape[0] + 1 cols = 17 print(\'>>>>>>>>>>>>>\') print(rows, cols) left = Cm(leftx) top = Cm(topx) col_temp = 0 # 计算表格总列宽 for i in range(cols): col_temp += col_width[i] width = Cm(col_temp) # 计算表格总行宽 height = Cm(row_height * rows) heightx = row_height * rows table = slide.shapes.add_table(rows, cols, left, top, width, height).table for i in range(cols): table.columns[i].width = Cm(col_width[i]) # 列高 # 填写表格表头 for j in range(cols): table.cell(0, j).text = str(title_list[j]) # 填写表格内容 if df.shape[0] > 13: for i in range(rows - 1): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j]) else: for i in range(df.shape[0]): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j]) # 行宽 for i in range(0, rows): table.rows[i].heigth = Cm(row_height) # 修改表格样式 for row in range(rows): for col in range(cols): # Write column titles new = table.cell(row, col).text_frame.paragraphs[0] new.font.name = fontname if row == 0: # 设置文字大小 table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) # 设置文字颜色 table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255) # 设置文字左右对齐 table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER # 设置文字上下对齐 table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE # 设置背景为填充 table.cell(row, col).fill.solid() # 设置背景颜色 table.cell(row, col).fill.fore_color.rgb = RGBColor(0, 30, 80) else: table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE table.cell(row, col).fill.solid() if row % 2 == 0:  table.cell(row, col).fill.fore_color.rgb = RGBColor(231, 231, 233) else:  table.cell(row, col).fill.fore_color.rgb = RGBColor(203, 204, 208) prs.save(ppt_script) # 对ppt保存 return heightx

8.2.2完善main.py

import osimport pandas as pdfrom office_ppt_ser import add_picturefrom office_ppt_ser import new_ppt_add_slidefrom office_ppt_ser import ppt_slide_numberfrom office_ppt_ser import shape_rectanglefrom office_ppt_ser import table_Nrows_17colsfrom office_ppt_ser import titleboxdef main(): new_ppt = r\'PPT模版.pptx\' new_ppt_path = new_ppt_add_slide(new_ppt, page_num=[1], PPT_Name=\'销售周报.pptx\') print(new_ppt_path) slide_number = ppt_slide_number(new_ppt_path) print(new_ppt_path) # 部门报告 titlebox(new_ppt_path, page_num=0, content_text=\'部门报告\', font_size=20, left=0.55, top=0.94, width=3.36, height=1.11, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'blue\', alignment=\'左对齐\', word_wrap=False) # ■部门商品库存记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品库存记录\', font_size=12, left=0.58, top=2.14, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■部门商品销售记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品销售记录\', font_size=12, left=0.58, top=6.34, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■总结 titlebox(new_ppt_path, page_num=0, content_text=\'■总结\', font_size=12, left=0.58, top=11.65, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000 titlebox(new_ppt_path, page_num=0, content_text=\'2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000\', font_size=12, left=0.58, top=12.58, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 方框1 shape_rectangle(new_ppt_path, page_num=0, Left=15.89, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 方框2 shape_rectangle(new_ppt_path, page_num=0, Left=19.54, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 红灯 titlebox(new_ppt_path, page_num=0, content_text=\'红灯\', font_size=18, left=16.68, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 绿灯 titlebox(new_ppt_path, page_num=0, content_text=\'绿灯\', font_size=18, left=20.32, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 增加图片 img_path = os.path.abspath(r\'.\\icon\\logo.png\') add_picture(img_path, new_ppt_path, page_num=0, left=23.25, top=0.12, width=1.7) # 增加表格 table_Nrows_17cols(new_ppt_path, page_num=0, title_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], col_width=[1.15, 2, 5.2, 1, 1.4, 1.4, 1, 1, 1, 1, 1.4, 1, 1, 1, 1, 1, 1], row_height=0.56, fontname=\'方正兰亭黑_GBK\', fontsize=6, leftx=0.55, topx=2.85, df=pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4 }))# 按装订区域中的绿色按钮以运行脚本。if __name__ == \'__main__\': main()

8.2.3效果展示

分享上述完整代码路径:
链接: https://pan.baidu.com/s/1j1zoYekpNLCJpdJhBbtHfA?pwd=cg72 提取码: cg72

9图表

在 python-pptx 库中,图表(Chart)是 PowerPoint 幻灯片中的一种特殊形状,这python-pptx中使用 slide.shapes.add_chart() 方法可以在幻灯片中插入图表。该方法需要指定图表类型、数据、位置和大小。接下来将根据一个函数-插入柱状图(可以调整颜色)进行详细讲解。

9.1函数-插入柱状图

import pandas as pdfrom pptx import Presentationfrom pptx.chart.data import ChartDatafrom pptx.dml.color import RGBColorfrom pptx.enum.chart import XL_CHART_TYPEfrom pptx.enum.chart import XL_DATA_LABEL_POSITIONfrom pptx.enum.chart import XL_LEGEND_POSITIONfrom pptx.util import Cmfrom pptx.util import Ptcolors_collection = { \'2_orange_green\': [RGBColor(255, 192, 0), RGBColor(0, 176, 80)], \'2_green_orange\': [RGBColor(0, 176, 80), RGBColor(255, 192, 0)], \'2_orange_olive\': [RGBColor(255, 192, 0), RGBColor(0, 176, 180)], \'2_olive_green\': [RGBColor(0, 176, 180), RGBColor(0, 176, 80)], \'2_white_olive\': [RGBColor(255, 255, 255), RGBColor(0, 176, 180)], \'2_blue_lightblue\': [RGBColor(0, 176, 240), RGBColor(169, 227, 255)], \'2_olive_orange\': [RGBColor(0, 176, 180), RGBColor(255, 192, 0)], \'2_gray_lightblue2\': [RGBColor(182, 191, 197), RGBColor(169, 227, 255)], \'1_olive\': [RGBColor(0, 176, 180)], \'1_orange\': [RGBColor(255, 192, 0)], \'1_gray\': [RGBColor(182, 191, 197)], \'1_lightblue\': [RGBColor(0, 176, 240)], \'1_tangerine\': [RGBColor(255, 102, 153)], \'2_tangerine_gray\': [RGBColor(255, 102, 153), RGBColor(182, 191, 197)], \'2_gray_tangerine\': [RGBColor(182, 191, 197), RGBColor(255, 102, 153)], \'2_gray_lightblue\': [RGBColor(182, 191, 197), RGBColor(0, 176, 240)], \'2_green_gray\': [RGBColor(0, 176, 80), RGBColor(182, 191, 197)], \'2_olive_gray\': [RGBColor(0, 176, 180), RGBColor(182, 191, 197)]}def chart_clustered_bar_self_color(ppt_script, page_num=0, left=0.96, top=3.86, width=12.5, height=5.87, font_size=6, has_legend=True, value_axis_maximum_scale=None, data_position=\'居中\', value_axis_minimum_scale=None, has_data_labels=True, df=pd.DataFrame(  {\'区域1\': [\'9\', \'11\'], \'区域2\': [\'6\', \'9\'], \'区域3\': [\'13\', \'7\'],  \'区域4\': [\'9\', \'11\'],  \'区域5\': [\'6\', \'9\'],  \'区域6\': [\'13\', \'7\']},  index=[\'主题1\', \'主题2\']), self_chart_style=\'2_orange_green\', y_axis_visible=True, legend_font_size=\'\', data_labels_font_size=\'\', data_percent=False): prs = Presentation(ppt_script) slide = prs.slides[page_num] # 定义图表数据 chart_data = ChartData() chart_data.categories = df.columns for i in range(df.shape[0]): chart_data.add_series(df.index[i], df.iloc[i]) # 定义图表位置 Left, Top, Width, Height = Cm(left), Cm(top), Cm(width), Cm(height) # 预设位置及大小 print(Left, Top, Width, Height) # 添加图表 graphic_frame = slide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, Left, Top, Width, Height, chart_data) # 将图表美化 chart = graphic_frame.chart # 从生成的图表中取出图表类 # 控制柱状图颜色 if self_chart_style != \'\': colors_collection_dic = colors_collection if self_chart_style in colors_collection: colors = colors_collection_dic[self_chart_style] # 设置颜色列表 if len(colors) == df.shape[0]: for i_x, series in enumerate(chart.series):  fill = series.format.fill  fill.solid()  fill.fore_color.rgb = colors[i_x] else: chart.chart_style = 8 # 图表整体颜色风格 else: chart.chart_style = 8 # 图表整体颜色风格 chart.has_title = False # 不显示标题 category_axis = chart.category_axis # category_axis 为chart的category控制类 category_axis.has_major_gridlines = False # 是否显示纵轴线 category_axis.has_minor_gridlines = False category_axis.tick_labels.font.italic = False # tick_labels为图表下标签,置为斜体 # category_axis.tick_labels.font.name= \'方正兰亭黑_GBK\' category_axis.tick_labels.font.size = Pt(font_size) # 下标签字体大小 category_axis.tick_labels.font.color.rgb = RGBColor(0, 0, 0) # 标签字体颜色 value_axis = chart.value_axis # value_axis 为chart的value控制类 value_axis.visible = y_axis_visible # 是否隐藏y轴 value_axis.has_major_gridlines = False # 是否显示纵轴线 value_axis.has_minor_gridlines = False if value_axis_maximum_scale != None: try: value_axis.maximum_scale = value_axis_maximum_scale # 纵坐标最大值 except: pass if value_axis_minimum_scale != None: value_axis.minimum_scale = value_axis_minimum_scale # 纵坐标最小值 # value_axis.minor_tick_mark = XL_TICK_MARK.CROSS tick_labels = value_axis.tick_labels # tick_labels 为chart的纵轴标签控制类 # tick_labels.number_format = \'0%\' # 标签显示样式 tick_labels.font.bold = False # 字体加粗 # tick_labels.font.name = \'方正兰亭黑_GBK\' tick_labels.font.size = Pt(font_size) # 字体大小 tick_labels.font.color.rgb = RGBColor(0, 0, 0) # 标签颜色 plot = chart.plots[0] # 取图表中第一个plot if has_data_labels == True: plot.has_data_labels = has_data_labels # 是否显示数据标签 data_labels = plot.data_labels # 数据标签控制类 data_labels.font.name = \'方正兰亭黑_GBK\' if data_labels_font_size == \'\': data_labels.font.size = Pt(font_size) # 字体大小 else: data_labels.font.size = Pt(data_labels_font_size) # 字体大小 if data_percent == True: data_labels.number_format = \'0.0%\' # 标签显示样式 data_labels.font.color.rgb = RGBColor(0, 0, 0) # 字体颜色 if data_position == \'居中\': data_labels.position = XL_DATA_LABEL_POSITION.CENTER # 字体位置 chart.has_legend = has_legend # 是否含有下方的说明 if has_legend == True: chart.legend.position = XL_LEGEND_POSITION.TOP chart.legend.horz_offset = 0 # 说明位移量 [-1, 1] 默认为0 # chart.legend.include_in_layout = True # 图例在绘图区之外显示 chart.legend.font.name = \'方正兰亭黑_GBK\' if legend_font_size == \'\': chart.legend.font.size = Pt(font_size) else: chart.legend.font.size = Pt(legend_font_size) prs.save(ppt_script) # 对ppt保存ppt_script = \'销售周报.pptx\'chart_clustered_bar_self_color(ppt_script)

这段代码的主要功能是使用 python-pptx 库在 PowerPoint 中自动生成一个带有自定义颜色的簇状柱状图。以下是对代码的详细解读:

9.1.1导入库

import pandas as pdfrom pptx import Presentationfrom pptx.chart.data import ChartDatafrom pptx.dml.color import RGBColorfrom pptx.enum.chart import XL_CHART_TYPEfrom pptx.enum.chart import XL_DATA_LABEL_POSITIONfrom pptx.enum.chart import XL_LEGEND_POSITIONfrom pptx.util import Cmfrom pptx.util import Pt
  • pandas:用于处理数据,生成图表所需的数据源。

  • pptx:用于创建和操作 PowerPoint 文件。

    • Presentation:表示一个 PowerPoint 文件。

    • ChartData:用于定义图表的数据。

    • RGBColor:用于定义颜色。

    • XL_CHART_TYPE:定义图表类型(如柱状图、饼图等)。

    • XL_DATA_LABEL_POSITION:定义数据标签的位置。

    • XL_LEGEND_POSITION:定义图例的位置。

    • Cm 和 Pt:用于设置尺寸和字体大小的单位。

9.1.2定义颜色集合

colors_collection = { \'2_orange_green\': [RGBColor(255, 192, 0), RGBColor(0, 176, 80)], \'2_green_orange\': [RGBColor(0, 176, 80), RGBColor(255, 192, 0)], ...}
  • 这是一个颜色集合字典,键是颜色方案的名称,值是由 RGBColor 定义的颜色列表。

  • 例如,\'2_orange_green\' 表示两种颜色:橙色和绿色。

9.1.3定义函数 chart_clustered_bar_self_color

这是代码的核心函数,用于在 PowerPoint 中生成簇状柱状图。

9.1.3.1函数参数

def chart_clustered_bar_self_color( ppt_script,  # PowerPoint 文件路径 page_num=0,  # 幻灯片页码(默认第1页) left=0.96, top=3.86, # 图表左上角位置(单位:厘米) width=12.5, height=5.87, # 图表宽度和高度(单位:厘米) font_size=6,  # 字体大小 has_legend=True, # 是否显示图例 value_axis_maximum_scale=None, # 纵坐标最大值 data_position=\'居中\', # 数据标签位置 value_axis_minimum_scale=None, # 纵坐标最小值 has_data_labels=True, # 是否显示数据标签 df=pd.DataFrame(...), # 图表数据(默认提供一个示例数据) self_chart_style=\'2_orange_green\', # 图表颜色方案 y_axis_visible=True, # 是否显示纵轴 legend_font_size=\'\', # 图例字体大小 data_labels_font_size=\'\', # 数据标签字体大小 data_percent=False # 数据标签是否显示为百分比):
  • 参数非常灵活,可以自定义图表的位置、大小、颜色、数据标签等。

9.1.3.2函数实现

  • 加载 PowerPoint 文件

    prs = Presentation(ppt_script)slide = prs.slides[page_num]
    打开指定的 PowerPoint 文件,并选择指定的幻灯片。
  • 定义图表数据

    chart_data = ChartData()chart_data.categories = df.columnsfor i in range(df.shape[0]): chart_data.add_series(df.index[i], df.iloc[i])
    • 使用 ChartData 定义图表的数据。

    • categories 是横轴标签(列名)。

    • add_series 添加数据系列(行数据)。

  • 添加图表到幻灯片

    graphic_frame = slide.shapes.add_chart( XL_CHART_TYPE.COLUMN_CLUSTERED, # 图表类型 Left, Top, Width, Height, # 图表位置和大小 chart_data # 图表数据)
    • 在幻灯片上添加一个簇状柱状图。

  • 美化图表

    • 设置颜色

      if self_chart_style != \'\': colors = colors_collection[self_chart_style] for i_x, series in enumerate(chart.series): fill = series.format.fill fill.solid() fill.fore_color.rgb = colors[i_x]
      • 根据 self_chart_style 设置柱状图的颜色。

    • 设置标题

      chart.has_title = False
      • 不显示图表标题。

    • 设置横轴和纵轴

      category_axis.tick_labels.font.size = Pt(font_size)value_axis.visible = y_axis_visible
      • 调整横轴和纵轴的字体大小、可见性等。

    • 设置数据标签

      if has_data_labels: data_labels.position = XL_DATA_LABEL_POSITION.CENTER
      • 显示数据标签,并设置其位置和格式。

    • 设置图例

      chart.has_legend = has_legendchart.legend.position = XL_LEGEND_POSITION.TOP
      • 显示图例,并设置其位置和字体大小。

  • 保存 PowerPoint 文件

    prs.save(ppt_script)
    • 保存修改后的 PowerPoint 文件。

9.1.4调用函数

ppt_script = \'销售周报.pptx\'chart_clustered_bar_self_color(ppt_script)
  • 指定 PowerPoint 文件路径,并调用函数生成图表。

9.2项目新增柱状图

9.2.1完善office_ppt_ser.py

项目将在 8.2节‘项目新增表格’的基础上继续推进,进一步完善代码,增加柱状图的功能。具体实现方式是将上述函数迁移至 office_ppt_ser.py 文件中。

import osimport pandas as pdfrom pptx import Presentationfrom pptx.dml.color import RGBColorfrom pptx.enum.shapes import MSO_SHAPEfrom pptx.enum.text import MSO_ANCHORfrom pptx.enum.text import PP_ALIGNfrom pptx.util import Cmfrom pptx.util import Ptimport pandas as pdfrom pptx import Presentationfrom pptx.chart.data import ChartDatafrom pptx.dml.color import RGBColorfrom pptx.enum.chart import XL_CHART_TYPEfrom pptx.enum.chart import XL_DATA_LABEL_POSITIONfrom pptx.enum.chart import XL_LEGEND_POSITIONfrom pptx.util import Cmfrom pptx.util import Ptcolors_collection = { \'2_orange_green\': [RGBColor(255, 192, 0), RGBColor(0, 176, 80)], \'2_green_orange\': [RGBColor(0, 176, 80), RGBColor(255, 192, 0)], \'2_orange_olive\': [RGBColor(255, 192, 0), RGBColor(0, 176, 180)], \'2_olive_green\': [RGBColor(0, 176, 180), RGBColor(0, 176, 80)], \'2_white_olive\': [RGBColor(255, 255, 255), RGBColor(0, 176, 180)], \'2_blue_lightblue\': [RGBColor(0, 176, 240), RGBColor(169, 227, 255)], \'2_olive_orange\': [RGBColor(0, 176, 180), RGBColor(255, 192, 0)], \'2_gray_lightblue2\': [RGBColor(182, 191, 197), RGBColor(169, 227, 255)], \'1_olive\': [RGBColor(0, 176, 180)], \'1_orange\': [RGBColor(255, 192, 0)], \'1_gray\': [RGBColor(182, 191, 197)], \'1_lightblue\': [RGBColor(0, 176, 240)], \'1_tangerine\': [RGBColor(255, 102, 153)], \'2_tangerine_gray\': [RGBColor(255, 102, 153), RGBColor(182, 191, 197)], \'2_gray_tangerine\': [RGBColor(182, 191, 197), RGBColor(255, 102, 153)], \'2_gray_lightblue\': [RGBColor(182, 191, 197), RGBColor(0, 176, 240)], \'2_green_gray\': [RGBColor(0, 176, 80), RGBColor(182, 191, 197)], \'2_olive_gray\': [RGBColor(0, 176, 180), RGBColor(182, 191, 197)]}def new_ppt_add_slide(template, page_num=[0], PPT_Name=\'新建 Microsoft PowerPoint 演示文稿.pptx\',save_path=\'C:\\\\Users\\\\weidong.guo\\\\Desktop\'): \"\"\" :param template: PPT模板 :param page_num: 列表,代表PPT模板里面的幻灯片序号,从0开始 :param PPT_Name: PPT名字 :param save_path: 保存路径 :return:返回新的PPT路径 \"\"\" if os.path.isdir(save_path): # save_path是目录 new_ppt_path = os.path.join(save_path, PPT_Name) # 将保存路径和PPT名字拼接在一起 else: new_ppt_path = PPT_Name # save_path不是目录,就不需要拼接 prs = Presentation(template) # 用Presentation读取PPT模板 for i in page_num: # 遍历需要增加的页数 prs.slides.add_slide(prs.slide_layouts[i]) # 模板template中增加幻灯片 prs.save(new_ppt_path) # 对ppt保存 return new_ppt_pathdef ppt_slide_number(ppt_script): prs = Presentation(ppt_script) slide_number = len(prs.slides) return slide_numberdef titlebox(ppt_script, page_num=0, content_text=\'Backup\', font_size=18, left=0.55, top=2.12, width=25.81, height=1.08, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'\', alignment=\'左对齐\', word_wrap=False): \"\"\" 参数: ppt_script (str): PPT文件路径。 page_num (int): 幻灯片页码(从0开始)。 content_text (str): 文本框内容。 font_size (int): 字体大小(单位:磅)。 left (float): 文本框左上角的水平位置(单位:厘米)。 top (float): 文本框左上角的垂直位置(单位:厘米)。 width (float): 文本框宽度(单位:厘米)。 height (float): 文本框高度(单位:厘米)。 font_bold (bool): 是否加粗。 font_name (str): 字体名称。 font_color (str): 字体颜色(支持\'blue\', \'green\', \'red\', \'yellow\', \'orange\', \'white\', \'gray1\', \'black\')。 alignment (str): 对齐方式(支持\'左对齐\', \'居中\')。 word_wrap (bool): 是否自动换行。 return: \"\"\" # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加文本框 textbox = slide.shapes.add_textbox(Cm(left), Cm(top), Cm(width), Cm(height)) tf = textbox.text_frame tf.word_wrap = word_wrap # 在文本框中写入文字 # 题目 para = tf.paragraphs[0] # 新增段落 para.text = content_text # 向段落写入文字 if font_color == \'blue\': para.font.color.rgb = RGBColor(0, 30, 80) # 蓝色 elif font_color == \'green\': para.font.color.rgb = RGBColor(0, 176, 80) # 绿色 elif font_color == \'red\': para.font.color.rgb = RGBColor(255, 0, 0) # 红色 elif font_color == \'yellow\': para.font.color.rgb = RGBColor(255, 255, 0) # 红色 elif font_color == \'orange\': para.font.color.rgb = RGBColor(255, 192, 0) # 红色 elif font_color == \'white\': para.font.color.rgb = RGBColor(255, 255, 255) # 红色 elif font_color == \'gray1\': para.font.color.rgb = RGBColor(182, 191, 197) # 红色 else: para.font.color.rgb = RGBColor(0, 0, 0) # 黑色 if alignment == \'左对齐\': para.alignment = PP_ALIGN.LEFT else: para.alignment = PP_ALIGN.CENTER # 居中 # 设置字体 font = para.font font.name = font_name # 字体类型 font.bold = font_bold # 加粗 font.size = Pt(font_size) # 大小 prs.save(ppt_script) # 对ppt保存# 在PPT中添加矩形框def shape_rectangle(ppt_script, page_num=0, Left=0.96, Top=3.2, Width=12.5, Height=5.87, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # 在指定位置添加矩形 shape = slide.shapes.add_shape(autoshape_type_id=MSO_SHAPE.RECTANGLE, left=Cm(Left), top=Cm(Top), width=Cm(Width), height=Cm(Height)) # 调整角度 shape.rotation = rotation # 填充背景色 fill = shape.fill fill.solid() # 调整线宽 line = shape.line if fore_color == \'gray\': fill.fore_color.rgb = RGBColor(242, 242, 242) line.color.rgb = RGBColor(242, 242, 242) elif fore_color == \'gray1\': fill.fore_color.rgb = RGBColor(127, 127, 127) line.color.rgb = RGBColor(127, 127, 127) elif fore_color == \'blue\': fill.fore_color.rgb = RGBColor(0, 30, 80) line.color.rgb = RGBColor(0, 30, 80) elif fore_color == \'red\': fill.fore_color.rgb = RGBColor(192, 0, 0) line.color.rgb = RGBColor(192, 0, 0) elif fore_color == \'yellow\': fill.fore_color.rgb = RGBColor(255, 255, 0) line.color.rgb = RGBColor(255, 255, 0) elif fore_color == \'white\': fill.fore_color.rgb = RGBColor(255, 255, 255) line.color.rgb = RGBColor(255, 255, 255) elif fore_color == \'lightblue\': fill.fore_color.rgb = RGBColor(212, 228, 255) line.color.rgb = RGBColor(212, 228, 255) # fill.fore_color.brightness = 0 # 设为透明 if shape_is_background == True: shape.fill.background() # fill.background() # fill.back_color.rgb = RGBColor(255, 255, 255) line.color.brightness = 0 line.width = Pt(line_width) line.fill.background() # 调成背景色 prs.save(ppt_script) # 对ppt保存def add_picture(img_path, ppt_script, page_num=0, left=0, top=0, width=4): # ppt_script=r\'C:\\Users\\hp\\Desktop\\汇总拆分\\111.pptx\' prs = Presentation(ppt_script) slide = prs.slides[page_num] # Left, Top, Width, Height = Cm(left), Cm(top), Cm(width), Cm(height) # 预设位置及大小 # slide.shapes.add_picture(img_path, Left, Top, Width, Height) # 在指定位置按预设值添加图片 Left, Top, Width = Cm(left), Cm(top), Cm(width) # 预设位置及大小 slide.shapes.add_picture(img_path, Left, Top, Width) # 在指定位置按预设值添加图片 prs.save(ppt_script) # 对ppt保存# 在PPT中表格def table_Nrows_17cols(ppt_script, page_num=0, title_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], col_width=[1.15, 2, 5.2, 1, 1.4, 1.4, 1, 1, 1, 1, 1.4, 1, 1, 1, 1, 1, 1], row_height=0.56, fontname=\'方正兰亭黑_GBK\', fontsize=6, leftx=0.55, topx=2.85, df=pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4 })): prs = Presentation(ppt_script) slide = prs.slides[page_num] if df.shape[0] > 13: rows, cols = 14, 17 # 设定5行 14列 else: rows = df.shape[0] + 1 cols = 17 print(\'>>>>>>>>>>>>>\') print(rows, cols) left = Cm(leftx) top = Cm(topx) col_temp = 0 # 计算表格总列宽 for i in range(cols): col_temp += col_width[i] width = Cm(col_temp) # 计算表格总行宽 height = Cm(row_height * rows) heightx = row_height * rows table = slide.shapes.add_table(rows, cols, left, top, width, height).table for i in range(cols): table.columns[i].width = Cm(col_width[i]) # 列高 # 填写表格表头 for j in range(cols): table.cell(0, j).text = str(title_list[j]) # 填写表格内容 if df.shape[0] > 13: for i in range(rows - 1): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j]) else: for i in range(df.shape[0]): for j in range(cols): table.cell(i + 1, j).text = str(df.iat[i, j]) # 行宽 for i in range(0, rows): table.rows[i].heigth = Cm(row_height) # 修改表格样式 for row in range(rows): for col in range(cols): # Write column titles new = table.cell(row, col).text_frame.paragraphs[0] new.font.name = fontname if row == 0: # 设置文字大小 table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) # 设置文字颜色 table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(255, 255, 255) # 设置文字左右对齐 table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER # 设置文字上下对齐 table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE # 设置背景为填充 table.cell(row, col).fill.solid() # 设置背景颜色 table.cell(row, col).fill.fore_color.rgb = RGBColor(0, 30, 80) else: table.cell(row, col).text_frame.paragraphs[0].font.size = Pt(fontsize) table.cell(row, col).text_frame.paragraphs[0].font.color.rgb = RGBColor(0, 0, 0) table.cell(row, col).text_frame.paragraphs[0].alignment = PP_ALIGN.CENTER table.cell(row, col).vertical_anchor = MSO_ANCHOR.MIDDLE table.cell(row, col).fill.solid() if row % 2 == 0:  table.cell(row, col).fill.fore_color.rgb = RGBColor(231, 231, 233) else:  table.cell(row, col).fill.fore_color.rgb = RGBColor(203, 204, 208) prs.save(ppt_script) # 对ppt保存 return heightxdef chart_clustered_bar_self_color(ppt_script, page_num=0, left=0.96, top=3.86, width=12.5, height=5.87, font_size=6, has_legend=True, value_axis_maximum_scale=None, data_position=\'居中\', value_axis_minimum_scale=None, has_data_labels=True, df=pd.DataFrame(  {\'区域1\': [\'9\', \'11\'], \'区域2\': [\'6\', \'9\'], \'区域3\': [\'13\', \'7\'],  \'区域4\': [\'9\', \'11\'],  \'区域5\': [\'6\', \'9\'],  \'区域6\': [\'13\', \'7\']},  index=[\'主题1\', \'主题2\']), self_chart_style=\'2_orange_green\', y_axis_visible=True, legend_font_size=\'\', data_labels_font_size=\'\', data_percent=False): prs = Presentation(ppt_script) slide = prs.slides[page_num] # 定义图表数据 chart_data = ChartData() chart_data.categories = df.columns for i in range(df.shape[0]): chart_data.add_series(df.index[i], df.iloc[i]) # 定义图表位置 Left, Top, Width, Height = Cm(left), Cm(top), Cm(width), Cm(height) # 预设位置及大小 print(Left, Top, Width, Height) # 添加图表 graphic_frame = slide.shapes.add_chart(XL_CHART_TYPE.COLUMN_CLUSTERED, Left, Top, Width, Height, chart_data) # 将图表美化 chart = graphic_frame.chart # 从生成的图表中取出图表类 # 控制柱状图颜色 if self_chart_style != \'\': colors_collection_dic = colors_collection if self_chart_style in colors_collection: colors = colors_collection_dic[self_chart_style] # 设置颜色列表 if len(colors) == df.shape[0]: for i_x, series in enumerate(chart.series):  fill = series.format.fill  fill.solid()  fill.fore_color.rgb = colors[i_x] else: chart.chart_style = 8 # 图表整体颜色风格 else: chart.chart_style = 8 # 图表整体颜色风格 chart.has_title = False # 不显示标题 category_axis = chart.category_axis # category_axis 为chart的category控制类 category_axis.has_major_gridlines = False # 是否显示纵轴线 category_axis.has_minor_gridlines = False category_axis.tick_labels.font.italic = False # tick_labels为图表下标签,置为斜体 # category_axis.tick_labels.font.name= \'方正兰亭黑_GBK\' category_axis.tick_labels.font.size = Pt(font_size) # 下标签字体大小 category_axis.tick_labels.font.color.rgb = RGBColor(0, 0, 0) # 标签字体颜色 value_axis = chart.value_axis # value_axis 为chart的value控制类 value_axis.visible = y_axis_visible # 是否隐藏y轴 value_axis.has_major_gridlines = False # 是否显示纵轴线 value_axis.has_minor_gridlines = False if value_axis_maximum_scale != None: try: value_axis.maximum_scale = value_axis_maximum_scale # 纵坐标最大值 except: pass if value_axis_minimum_scale != None: value_axis.minimum_scale = value_axis_minimum_scale # 纵坐标最小值 # value_axis.minor_tick_mark = XL_TICK_MARK.CROSS tick_labels = value_axis.tick_labels # tick_labels 为chart的纵轴标签控制类 # tick_labels.number_format = \'0%\' # 标签显示样式 tick_labels.font.bold = False # 字体加粗 # tick_labels.font.name = \'方正兰亭黑_GBK\' tick_labels.font.size = Pt(font_size) # 字体大小 tick_labels.font.color.rgb = RGBColor(0, 0, 0) # 标签颜色 plot = chart.plots[0] # 取图表中第一个plot if has_data_labels == True: plot.has_data_labels = has_data_labels # 是否显示数据标签 data_labels = plot.data_labels # 数据标签控制类 data_labels.font.name = \'方正兰亭黑_GBK\' if data_labels_font_size == \'\': data_labels.font.size = Pt(font_size) # 字体大小 else: data_labels.font.size = Pt(data_labels_font_size) # 字体大小 if data_percent == True: data_labels.number_format = \'0.0%\' # 标签显示样式 data_labels.font.color.rgb = RGBColor(0, 0, 0) # 字体颜色 if data_position == \'居中\': data_labels.position = XL_DATA_LABEL_POSITION.CENTER # 字体位置 chart.has_legend = has_legend # 是否含有下方的说明 if has_legend == True: chart.legend.position = XL_LEGEND_POSITION.TOP chart.legend.horz_offset = 0 # 说明位移量 [-1, 1] 默认为0 # chart.legend.include_in_layout = True # 图例在绘图区之外显示 chart.legend.font.name = \'方正兰亭黑_GBK\' if legend_font_size == \'\': chart.legend.font.size = Pt(font_size) else: chart.legend.font.size = Pt(legend_font_size) prs.save(ppt_script) # 对ppt保存

9.2.2完善main.py

import osimport pandas as pdfrom office_ppt_ser import add_picturefrom office_ppt_ser import new_ppt_add_slidefrom office_ppt_ser import ppt_slide_numberfrom office_ppt_ser import shape_rectanglefrom office_ppt_ser import table_Nrows_17colsfrom office_ppt_ser import titleboxfrom office_ppt_ser import table_Nrows_17colsfrom office_ppt_ser import chart_clustered_bar_self_colordef main(): new_ppt = r\'PPT模版.pptx\' new_ppt_path = new_ppt_add_slide(new_ppt, page_num=[1], PPT_Name=\'销售周报.pptx\') print(new_ppt_path) slide_number = ppt_slide_number(new_ppt_path) print(new_ppt_path) # 部门报告 titlebox(new_ppt_path, page_num=0, content_text=\'部门报告\', font_size=20, left=0.55, top=0.94, width=3.36, height=1.11, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'blue\', alignment=\'左对齐\', word_wrap=False) # ■部门商品库存记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品库存记录\', font_size=12, left=0.58, top=2.14, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■部门商品销售记录 titlebox(new_ppt_path, page_num=0, content_text=\'■部门商品销售记录\', font_size=12, left=0.58, top=6.34, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■总结 titlebox(new_ppt_path, page_num=0, content_text=\'■总结\', font_size=12, left=0.58, top=11.65, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000 titlebox(new_ppt_path, page_num=0, content_text=\'2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000\', font_size=12, left=0.58, top=12.58, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 方框1 shape_rectangle(new_ppt_path, page_num=0, Left=15.89, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 方框2 shape_rectangle(new_ppt_path, page_num=0, Left=19.54, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 红灯 titlebox(new_ppt_path, page_num=0, content_text=\'红灯\', font_size=18, left=16.68, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 绿灯 titlebox(new_ppt_path, page_num=0, content_text=\'绿灯\', font_size=18, left=20.32, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 增加图片 img_path = os.path.abspath(r\'.\\icon\\logo.png\') add_picture(img_path, new_ppt_path, page_num=0, left=23.25, top=0.12, width=1.7) # 增加表格 table_Nrows_17cols(new_ppt_path, page_num=0, title_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], col_width=[1.15, 2, 5.2, 1, 1.4, 1.4, 1, 1, 1, 1, 1.4, 1, 1, 1, 1, 1, 1], row_height=0.56, fontname=\'方正兰亭黑_GBK\', fontsize=6, leftx=0.55, topx=2.85, df=pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4 })) # 增加柱状图 chart_clustered_bar_self_color(new_ppt_path, page_num=0, left=0.9, top=7.14, width=23.2, height=4.46, font_size=6, has_legend=True, value_axis_maximum_scale=None, data_position=\'居中\', value_axis_minimum_scale=None, has_data_labels=True, df=pd.DataFrame(  {\'区域1\': [\'9\', \'11\'], \'区域2\': [\'6\', \'9\'], \'区域3\': [\'13\', \'7\'],  \'区域4\': [\'9\', \'11\'],  \'区域5\': [\'6\', \'9\'],  \'区域6\': [\'13\', \'7\']},  index=[\'主题1\', \'主题2\']), self_chart_style=\'2_orange_green\', y_axis_visible=True, legend_font_size=\'\', data_labels_font_size=\'\', data_percent=False)# 按装订区域中的绿色按钮以运行脚本。if __name__ == \'__main__\': main()

9.3.4效果展示

分享上述完整代码路径:
链接: https://pan.baidu.com/s/1u3rwNOnZXeqtlnoP_YGZDg?pwd=nhu9 提取码: nhu9

10项目代码main.py升级

对main.py代码通过引入函数参数化,使得生成PPT的过程更加灵活,能够根据不同的输入生成不同的内容

10.1提取函数参数

将main.py代码硬编码文本内容(如“部门报告”、“■部门商品库存记录”等)和数据提取为函数参数。

def generate_ppt(text1, text2, text3, text4, text5, text6, df_table_data, df_chart): # 函数体

10.2数据参数化

将表格和图表的数据提取为参数。

# 表格数据df_table_data = pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4})# 柱状图数据df_chart = pd.DataFrame( {\'区域1\': [\'9\', \'11\'], \'区域2\': [\'6\', \'9\'], \'区域3\': [\'13\', \'7\'], \'区域4\': [\'9\', \'11\'], \'区域5\': [\'6\', \'9\'], \'区域6\': [\'13\', \'7\']}, index=[\'主题1\', \'主题2\'])

10.3封装为函数

将生成PPT的逻辑封装到一个函数中

def generate_ppt(text1, text2, text3, text4, text5, text6, df_table_data, df_chart): new_ppt = r\'PPT模版.pptx\' new_ppt_path = new_ppt_add_slide(new_ppt, page_num=[1], PPT_Name=\'销售周报.pptx\') print(new_ppt_path) slide_number = ppt_slide_number(new_ppt_path) print(new_ppt_path) # 部门报告 titlebox(new_ppt_path, page_num=0, content_text=text1, font_size=20, left=0.55, top=0.94, width=3.36, height=1.11, font_bold=True, font_name=\'方正兰亭黑_GBK\', font_color=\'blue\', alignment=\'左对齐\', word_wrap=False) # ■部门商品库存记录 titlebox(new_ppt_path, page_num=0, content_text=text2, font_size=12, left=0.58, top=2.14, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■部门商品销售记录 titlebox(new_ppt_path, page_num=0, content_text=text3, font_size=12, left=0.58, top=6.34, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # ■总结 titlebox(new_ppt_path, page_num=0, content_text=text4, font_size=12, left=0.58, top=11.65, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000 titlebox(new_ppt_path, page_num=0, content_text=\'2025近期窗帘销售额最高是4000,近期下降最多的是窗帘,下降额是1000\', font_size=12, left=0.58, top=12.58, width=24.24, height=0.77, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'左对齐\', word_wrap=False) # 方框1 shape_rectangle(new_ppt_path, page_num=0, Left=15.89, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 方框2 shape_rectangle(new_ppt_path, page_num=0, Left=19.54, Top=0.79, Width=3.36, Height=1, fore_color=\'gray\',  line_width=0, rotation=0, shape_is_background=False) # 红灯 titlebox(new_ppt_path, page_num=0, content_text=text5, font_size=18, left=16.68, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 绿灯 titlebox(new_ppt_path, page_num=0, content_text=text6, font_size=18, left=20.32, top=0.76, width=1.8, height=1.03, font_bold=False, font_name=\'方正兰亭黑_GBK\', font_color=\'black\', alignment=\'居中\', word_wrap=False) # 增加图片 img_path = os.path.abspath(r\'.\\icon\\logo.png\') add_picture(img_path, new_ppt_path, page_num=0, left=23.25, top=0.12, width=1.7) # 增加表格 table_Nrows_17cols(new_ppt_path, page_num=0, title_list=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], col_width=[1.15, 2, 5.2, 1, 1.4, 1.4, 1, 1, 1, 1, 1.4, 1, 1, 1, 1, 1, 1], row_height=0.56, fontname=\'方正兰亭黑_GBK\', fontsize=6, leftx=0.55, topx=2.85, df=df_table_data.copy() ) # 增加柱状图 chart_clustered_bar_self_color(new_ppt_path, page_num=0, left=0.9, top=7.14, width=23.2, height=4.46, font_size=6, has_legend=True, value_axis_maximum_scale=None, data_position=\'居中\', value_axis_minimum_scale=None, has_data_labels=True, df=df_chart.copy(), self_chart_style=\'2_orange_green\', y_axis_visible=True, legend_font_size=\'\', data_labels_font_size=\'\', data_percent=False)

10.4调用函数

在 if __name__ == \'__main__\': 中调用 generate_ppt 函数,并传入相应的参数:

if __name__ == \'__main__\': text1 = \'部门报告\' text2 = \'■部门商品库存记录\' text3 = \'■部门商品销售记录\' text4 = \'■总结\' text5 = \'红灯\' text6 = \'绿灯\' # 表格数据 df_table_data = pd.DataFrame({ f\'col{i}\': range(5) for i in range(17) # 每列数据为 0 到 4 }) # 柱状图数据 df_chart = pd.DataFrame( {\'区域1\': [\'9\', \'11\'], \'区域2\': [\'6\', \'9\'], \'区域3\': [\'13\', \'7\'], \'区域4\': [\'9\', \'11\'], \'区域5\': [\'6\', \'9\'], \'区域6\': [\'13\', \'7\']}, index=[\'主题1\', \'主题2\']) generate_ppt(text1, text2, text3, text4, text5, text6, df_table_data, df_chart)

分享上述完整代码路径:
链接: https://pan.baidu.com/s/13GpH2zDegOXCsLPBNbQN9g?pwd=et2p 提取码: et2p

11总结

感谢大家看到最后,本文通过一个具体的案例,展示了如何利用 Python 自动化生成 PPT 报告。介绍了 python-pptx 模块的基本用法,还通过一个完整的项目案例,详细讲解了如何从零开始构建一个自动化生成 PPT 的工具。通过模块化的设计和代码封装,文章展示了如何提高代码的复用性和可维护性,最终实现高效、准确的 PPT 报告生成。对于需要频繁生成 PPT 报告的职场人士来说,提供了一个非常实用的解决方案,能够显著提高工作效率,减少重复性劳动。