目录
9.1.3定义函数 chart_clustered_bar_self_color
1摘要
本文详细介绍了如何利用 Python 的 python-pptx 模块来自动化生成 PowerPoint 报告。文章通过一个具体的案例,展示了如何从零开始构建一个自动化生成 PPT 的工具,涵盖了从安装模块、PPT 结构分析、基础操作(如新建 PPT、添加幻灯片、插入文本框、形状、图片、表格和图表)到最终生成完整报告的整个过程。
2目的:python-pptx设计模板
场景:张三接到领导的任务,负责每周整理销售周报,格式如下图所示。这项工作繁琐且耗时:他需要从多个 Excel 表格中提取并整理数据,最终生成完整的周报。起初尚能应付,但随着时间的推移,他发现每次都是重复性操作。这种低效且机械的工作方式不仅耗费精力,还容易出错,给张三带来了巨大压力。
为了实现张三工作的全面自动化,可以分以下三个步骤完成:
-
第一步:利用 Python 设计 PPT 模板,并在模板中预留数据接口,确保数据能够动态填充到指定位置。
-
第二步:通过 Python 爬虫技术从指定数据源(如网页或数据库)爬取数据,或从 Excel 表格中收集数据,并使用 Pandas 模块对数据进行分析,生成 PPT 所需的结构化数据。
-
第三步:将第一步和第二步整合为一个完整的自动化脚本,实现从数据收集到 PPT 生成的全程自动化。
本文将从 Python-pptx 模块的底层原理入手,结合 PPT 的核心结构,重点讲解第1个步骤的实现方法。
2模块安装
模块的安装方法与常规安装一致,使用以下命令即可:
pip install python-pptx
如不会安装可以参考另一篇文章《PyCharm 与 Anaconda 下载安装及 PyCharm 新建项目指南》
3PPT结构与python接口关系
通过对上述 PPT 模板的分析,其核心设计主要包含以下 6 个要素,以及与 python-pptx
接口的对应关系:
-
母版设计(幻灯片布局),功能:定义幻灯片的整体结构和布局。对应接口:
SlideLayout
类 -
文本框,功能:用于填充标题、正文等文本内容。对应接口:
TextFrame
类 -
形状,功能:包括矩形、圆形等图形元素,用于装饰或强调信息。对应接口:
Shape
类 -
图片,功能:插入图像以增强视觉效果。对应接口:
Picture
类 -
表格,功能:用于展示结构化数据。对应接口:
Table
类 -
图表,功能:通过可视化形式呈现数据趋势或对比。对应接口:
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读取当前有多少PPT
print(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_path
def 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_slide
from office_ppt_ser import ppt_slide_number
def 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 Presentation
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from pptx.util import Pt
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 (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 Presentation
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from pptx.util import Pt
-
Presentation
:用于创建或打开PPT文件。 -
RGBColor
:用于设置文本颜色。 -
PP_ALIGN
:用于设置文本对齐方式。 -
Cm
和Pt
:用于设置尺寸单位(厘米和磅)。
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磅)。 -
left
和top
:文本框左上角的坐标(默认0.55cm和2.12cm)。 -
width
和height
:文本框的宽度和高度(默认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_frame
tf.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.LEFT
else:
para.alignment = PP_ALIGN.CENTER # 居中
5.1.8设置字体样式
font = para.font
font.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 Presentation
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from pptx.util import Pt
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_path
def ppt_slide_number(ppt_script):
prs = Presentation(ppt_script)
slide_number = len(prs.slides)
return slide_number
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 (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_slide
from office_ppt_ser import ppt_slide_number
from office_ppt_ser import titlebox
def 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.fill
fill.solid()
fill.fore_color.rgb = RGBColor(255, 0, 0) # 红色
接下来将根据一个函数-插入长方形进行详细讲解。
6.1函数-插入长方形
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.util import Cm
from 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 Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.util import Cm
from 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
:在幻灯片上添加一个矩形框,位置和大小由left
、top
、width
和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:爆炸形1 EXPLOSION2:爆炸形2 FLOWCHART_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:标注线1 LINE_CALLOUT_1_ACCENT_BAR:带强调条的标注线1 LINE_CALLOUT_1_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线1 LINE_CALLOUT_1_NO_BORDER:无边框的标注线1 LINE_CALLOUT_2:标注线2 LINE_CALLOUT_2_ACCENT_BAR:带强调条的标注线2 LINE_CALLOUT_2_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线2 LINE_CALLOUT_2_NO_BORDER:无边框的标注线2 LINE_CALLOUT_3:标注线3 LINE_CALLOUT_3_ACCENT_BAR:带强调条的标注线3 LINE_CALLOUT_3_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线3 LINE_CALLOUT_3_NO_BORDER:无边框的标注线3 LINE_CALLOUT_4:标注线4 LINE_CALLOUT_4_ACCENT_BAR:带强调条的标注线4 LINE_CALLOUT_4_BORDER_AND_ACCENT_BAR:带边框和强调条的标注线4 LINE_CALLOUT_4_NO_BORDER:无边框的标注线4 LINE_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.fill
fill.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 = 0
line.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 Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from pptx.util import Pt
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_path
def ppt_slide_number(ppt_script):
prs = Presentation(ppt_script)
slide_number = len(prs.slides)
return slide_number
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 (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_slide
from office_ppt_ser import ppt_slide_number
from office_ppt_ser import titlebox
from office_ppt_ser import shape_rectangle
def 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 os
from pptx import Presentation
from 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 os
from pptx import Presentation
from pptx.util import Cm
-
os
: Python 标准库,用于处理文件路径和操作系统相关功能。 -
pptx
:python-pptx
库,用于创建和修改 PowerPoint 文件。 -
Cm
:pptx.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 os
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from pptx.util import Pt
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_path
def ppt_slide_number(ppt_script):
prs = Presentation(ppt_script)
slide_number = len(prs.slides)
return slide_number
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 (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 os
from office_ppt_ser import add_picture
from office_ppt_ser import new_ppt_add_slide
from office_ppt_ser import ppt_slide_number
from office_ppt_ser import shape_rectangle
from office_ppt_ser import titlebox
def 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 os
import pandas as pd
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.text import MSO_ANCHOR
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from 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 heightx
ppt_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 pd
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.text import MSO_ANCHOR, PP_ALIGN
from pptx.util import Cm, Pt
-
pandas as pd
: 用于处理数据框(DataFrame)。 -
pptx
: 用于操作 PowerPoint 文件。-
Presentation
: 用于创建或打开 PPT 文件。 -
RGBColor
: 用于设置颜色。 -
MSO_ANCHOR
,PP_ALIGN
: 用于设置文本的对齐方式。 -
Cm
,Pt
: 用于设置长度单位(厘米和磅)。
-
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
: 字体大小(单位:磅)。 -
leftx
,topx
: 表格左上角的坐标(单位:厘米)。 -
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 = 0
for 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).table
for 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 os
import pandas as pd
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import MSO_ANCHOR
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from pptx.util import Pt
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_path
def ppt_slide_number(ppt_script):
prs = Presentation(ppt_script)
slide_number = len(prs.slides)
return slide_number
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 (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 os
import pandas as pd
from office_ppt_ser import add_picture
from office_ppt_ser import new_ppt_add_slide
from office_ppt_ser import ppt_slide_number
from office_ppt_ser import shape_rectangle
from office_ppt_ser import table_Nrows_17cols
from office_ppt_ser import titlebox
def 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 pd
from pptx import Presentation
from pptx.chart.data import ChartData
from pptx.dml.color import RGBColor
from pptx.enum.chart import XL_CHART_TYPE
from pptx.enum.chart import XL_DATA_LABEL_POSITION
from pptx.enum.chart import XL_LEGEND_POSITION
from pptx.util import Cm
from pptx.util import Pt
colors_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 pd
from pptx import Presentation
from pptx.chart.data import ChartData
from pptx.dml.color import RGBColor
from pptx.enum.chart import XL_CHART_TYPE
from pptx.enum.chart import XL_DATA_LABEL_POSITION
from pptx.enum.chart import XL_LEGEND_POSITION
from pptx.util import Cm
from 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.columns for 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_legend chart.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 os
import pandas as pd
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.text import MSO_ANCHOR
from pptx.enum.text import PP_ALIGN
from pptx.util import Cm
from pptx.util import Pt
import pandas as pd
from pptx import Presentation
from pptx.chart.data import ChartData
from pptx.dml.color import RGBColor
from pptx.enum.chart import XL_CHART_TYPE
from pptx.enum.chart import XL_DATA_LABEL_POSITION
from pptx.enum.chart import XL_LEGEND_POSITION
from pptx.util import Cm
from pptx.util import Pt
colors_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_path
def ppt_slide_number(ppt_script):
prs = Presentation(ppt_script)
slide_number = len(prs.slides)
return slide_number
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 (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
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保存
9.2.2完善main.py
import os
import pandas as pd
from office_ppt_ser import add_picture
from office_ppt_ser import new_ppt_add_slide
from office_ppt_ser import ppt_slide_number
from office_ppt_ser import shape_rectangle
from office_ppt_ser import table_Nrows_17cols
from office_ppt_ser import titlebox
from office_ppt_ser import table_Nrows_17cols
from office_ppt_ser import chart_clustered_bar_self_color
def 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 报告的职场人士来说,提供了一个非常实用的解决方案,能够显著提高工作效率,减少重复性劳动。