python-pptx生成PPT报告

文章目录

  • 前言
  • 一、python-pptx是什么?
  • 二、生成PPT的解决方案
  • 三、修改文本框的文本内容
  • 四、修改统计图表的数据
  • 五、删除元素
  • 六、删除某一页PPT
  • 总结


前言

存在这样一个需求,需要使用数据渲染生成一个PPT报告。经过一番查询,笔者决定使用python-pptx来完成这个需求。python-pptx作为一个功能强大的第三方库,完全可以满足笔者的需求。


一、python-pptx是什么?

python-pptx是一个强大的python类库,可以操作PPT的各种元素(表格、图片、统计图表、表格等)从无到有生成PPT。python-pptx中的方法大都是add开头的,意味着可以很容易新增各种PPT元素。于是,笔者决定按照文档给出的用法,生成各种PPT元素,最终生成一个完整的PPT。然而,笔者很快就遇到了问题:PPT的布局十分复杂和繁琐,笔者需要确定模板中每个元素的位置、大小、颜色等属性,然后通过python-pptx提供的接口来生成这些元素。这样子也太过繁琐了。

python-pptx的文档:https://python-pptx.readthedocs.io/en/latest

二、生成PPT的解决方案

那么我们该怎么做呢?最直接的想法就是,只修改一下需要渲染的文本数据,而不是从头生成元素。为了实现这样的想法,还需要解决一些问题:

  1. 如何定位修改的文本元素?
  2. 如何修改文本框中的文本?
  3. 如何修改统计图表的数据?
  4. 如何删除没有数据渲染的元素?
  5. 如何删除没有数据渲染的PPT页面?

第一个问题很简单,我们可以为PPT中的元素设置特殊的标记id,比如图表就有标题元素,我们可以将标题的文本设置为{chart},然后设置一个字典将这个id和需要填充的数据匹配即可。在修改图表数据时,搜索页面中所有元素的标题文本,根据这个id就可以修改图表的数据。

三、修改文本框的文本内容

代码如下(示例):

from pptx import Presentation

prs = Presentation(path_to_presentation)

for slide in prs.slides:
    for shape in slide.shapes:
        if not shape.has_text_frame:
            continue
        # 方法一
        # shape.text_frame.text = "update"
        # 方法二
        for paragraph in shape.text_frame.paragraphs:
            for run in paragraph.runs:
                run.text = "update"
                

上述代码中存在两种方法可以将文本框的元素改为update,二者的不同之处在于,第一种方法改动后,模板的字体格式以及颜色都会消失,不符合我们的要求。第二种方法则可以在保留模板字体的格式

四、修改统计图表的数据

生成一个直方图代码如下(示例):

from pptx import Presentation
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Inches

# create presentation with 1 slide ------
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[5])

# define chart data ---------------------
chart_data = CategoryChartData()
chart_data.categories = ['East', 'West', 'Midwest']
chart_data.add_series('Series 1', (19.2, 21.4, 16.7))

# add chart to slide --------------------
x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4.5)
slide.shapes.add_chart(
    XL_CHART_TYPE.COLUMN_CLUSTERED, x, y, cx, cy, chart_data
)

prs.save('chart-01.pptx')

修改刚才生成的直方图的数据。

from pptx import Presentation
from pptx.chart.data import CategoryChartData

prs = Presentation("chart-01.pptx")

# define chart data ---------------------
chart_data = CategoryChartData()
chart_data.categories = ['A', 'B', 'C']
chart_data.add_series('Series 1', (2, 4, 6))

for slide in prs.slides:
    for shape in slide.shapes:
        if not shape.has_chart:
            continue

        shape.chart.replace_data(chart_data)

prs.save('chart-02.pptx')

上述代码的核心就是replace_data方法,需要注意的是,不同的图表类型其char_data的类型(CategoryChartData、XyChartData)也不相同,修改数据的时候需要注意这个问题,不能用折线图的数据替换直方图中的数据。

五、删除元素

代码如下(示例):

presentation = Presentation("your_presentation.pptx") 

slide = presentation.slides[0] 

for shape in slide.shapes: 
	# 方法一:如果组合图形中元素存在文本以{开头的的元素,那么删除这个组合图形元素
	# MSO_SHAPE_TYPE.GROUP 表示组合图形 
	if shape.shape_type == MSO_SHAPE_TYPE.GROUP: # 获取组合图形中的元素 
		for element in shape.shapes: 
			if element.has_text_frame and element.text_frame.text.startswith("{"): 				
				slide.shapes._spTree.remove(shape._element) 
				break
	# 方法二:删除PPT页面中文本{开头的的元素
	if shape.has_text_frame and shape.text_frame.text.startswith("{"): 				
				slide.shapes._spTree.remove(shape._element) 
				break
		

组合图形指的是将PPT中的多个元素组合成一个整体,我们就可以移动这个组合元素但不改变组合元素子元素的相对位置。
python-pptx生成PPT报告_第1张图片

六、删除某一页PPT

代码如下(示例):

class PresentationBuilder(object): 
	presentation = Presentation("your_presentation.pptx") 
						
	@property 
	def xml_slides(self): 
		return self.presentation.slides._sldIdLst # pylint: disable=protected-access 
		
	def move_slide(self, old_index, new_index): 
		# 将PPT页面移动位置,结合python-pptx只提供了PPT末尾添加页面的功能,即可实现生成新的页面然后插入指定位置的功能
		slides = list(self.xml_slides) 
		self.xml_slides.remove(slides[old_index]) 
		self.xml_slides.insert(new_index, slides[old_index]) # also works for deleting slides 
		
	def delete_slide(self, index): 
		# index指的是PPT页面在整个PPT中位置,比如第一页PPT的index就是0
		slides = list(self.xml_slides) 
		self.xml_slides.remove(slides[index])

python-pptx中没有提供删除PPT页面的方法,原因是删除页面的操作比较复杂,容易出错。上述的代码也只是不让这个页面在PPT中的展示,而非真正删除了这一页PPT。当然,这个已经足够满足我的需要了。


总结

以上就是今天要讲的内容,本文给出了生成PPT的一个解决方案,可以通过替换元素数据内容的方式生成一个PPT。

你可能感兴趣的:(python模块使用心得,python,powerpoint)