Python Office Automation with PPT — How to use python-pptx part2
1. Introduction
The previous article briefly introduced the document structure of PPT and used the python-pptx dependency library to perform the most basic operations on PPT documents. As the second article in the PPT series, this piece will cover the following content:
- Tables
- Images (including static images and GIF animated images)
- Videos
2. Tables
After instantiating a Slide object, you can use the following method to insert a table:
Method: slide.shapes.add_table(rows, cols, left, top, width, height)
Parameters:
rows: Number of table rowscols: Number of table columnsleft: Left margintop: Top marginwidth: Table widthheight: Table height
Return type: pptx.shapes.graphfrm.GraphicFrame
Its table property is a table object: pptx.table.Table
python
def insert_table(slide, rows, cols, left, top, width, height, unit=Cm):
"""
Insert a table into a slide
:param unit: Default unit is centimeters
:param slide: Slide object
:param rows: Number of rows
:param cols: Number of columns
:param left: Left margin
:param top: Top margin
:param width: Width
:param height: Height
:return:
"""
# Insert a table
table = slide.shapes.add_table(rows, cols, unit(left), unit(top), unit(width), unit(height))
# Return table object
return table.table
# 1. Create a Slide object (blank style)
slide = add_slide(self.presentation, 6)
# 2. Insert a table
# Parameters: slide object, rows, columns, left margin, top margin, width, height
table = insert_table(slide, 3, 3, 3, 5, 13.6, 5)
2.1 Adjusting Row Height and Column Width
For aesthetic table generation, adjusting row height and column width is necessary. The table object’s columns and rows properties are used to get all column and row objects respectively.
python
def set_table_column_width(table, column_index, width, unit=Cm):
"""
Set width of a specific column in table
:param table:
:param column_index:
:param width:
:param unit: Unit defaults to centimeters
:return:
"""
table.columns[column_index].width = unit(width)
def set_table_row_height(table, row_index, height, unit=Cm):
"""
Set height of a specific row in table
:param table:
:param row_index:
:param height:
:param unit:
:return:
"""
table.rows[row_index].height = unit(height)
# 3. Reset table width and height
# 3.1 Set column widths for columns 1-3
set_table_column_width(table, 0, 5)
set_table_column_width(table, 1, 5)
set_table_column_width(table, 2, 5)
# 3.2 Set row heights
set_table_row_height(table, 0, 1.5)
set_table_row_height(table, 1, 1.2)
set_table_row_height(table, 2, 1.2)
2.2 Setting Cell Data
First, get the corresponding cell object using row and column indices:
python
# Get a specific cell object # Note: Index starts from 0 # Example: Get cell object at first row, first column cell = table.cell(0, 0)
Then, set the cell object’s text property to the specified content:
python
# Set cell value cell.text = "Content displayed in cell"
This way, we can define a set of data and insert it into the table:
python
# 4. Set table data
datas = [
["Student", "Name", "Age"],
["", "Xing An Guo", 23],
["", "AirPython", 18]]
# Iterate and set data into cells
for row_index in range(len(table.rows)):
for column_index in range(len(table.columns)):
# Get cell object
cell_temp = table.cell(row_index, column_index)
# Set data
cell_temp.text = str(datas[row_index][column_index])
2.3 Cell Style Adjustment
Adjusting cell styles involves these 3 steps:
- Get the cell text object
- Get the paragraph object of the text object
- Specify paragraph alignment and text style through the paragraph
Example: Set first row header cell text to bold and center-aligned:
python
# 5. Set first row header cell text to bold and center-aligned
for column_index in range(len(table.columns)):
# 1. Cell object
cell = table.cell(0, column_index)
# 2. Paragraph of text control
paragraph = cell.text_frame.paragraphs[0]
# 3. Set paragraph style
set_parg_font_style(paragraph, font_name='Microsoft YaHei', font_size=23, font_color=[255, 0, 0],
font_bold=True)
Note: Besides using the default paragraph, text controls in cells can also add new paragraphs with different content and styles.
2.4 Cell Background Color
The method for setting text box background color from the previous article also applies to cells:
python
def set_widget_bg(widget, bg_rgb_color=None):
"""
Set background color for [textbox/cell/shape]
:param widget: Textbox, cell, shape
:param bg_rgb_color: Background color value
:return:
"""
if bg_rgb_color and len(bg_rgb_color) == 3:
# 1. Set shape fill type to solid
widget.fill.solid()
# 2. Set background color
widget.fill.fore_color.rgb = RGBColor(bg_rgb_color[0], bg_rgb_color[1], bg_rgb_color[2])
# Set cell background color
set_widget_bg(cell, [204, 217, 225])
2.5 Merging Cells
Syntax:
python
# Merge cells start_cell.merge(end_cell)
Example: Merge cells and center-align the content:
python
from pptx.enum.text import MSO_VERTICAL_ANCHOR, MSO_ANCHOR
def set_cell_center(cell):
"""
Set cell text to center alignment
:param cell:
:return:
"""
paragraph = cell.text_frame.paragraphs[0]
paragraph.alignment = PP_ALIGN.CENTER
cell.vertical_anchor = MSO_ANCHOR.MIDDLE
# 6. Cell merging
# Merge cells and center-align display
table.cell(1, 0).merge(table.cell(2, 0))
table.cell(1, 0).text = "Merged"
set_cell_center(table.cell(1, 0))
3. Images
Both static images and GIF animated images are inserted into slides in the same way.
Method: slide.shapes.add_picture(image_file, left, top, width, height)
Parameters:
image_file: Image pathleft: Left margintop: Top marginwidth: Image display widthheight: Image display height
python
def insert_image(slide, pic_path, left, top, width=None, height=None, unit=Inches):
"""
Add image to slide (including static and animated images)
:param unit: Unit defaults to Inches
:param pic_path: File path
:param slide: Slide object
:param left: Left margin
:param top: Top margin
:param width: Width
:param height: Height
:return:
"""
# Note: If both width and height are None, display with original image size
width = unit(width) if width else None
height = unit(height) if height else None
pic_obj = slide.shapes.add_picture(image_file=pic_path,
left=unit(left),
top=unit(top),
width=width,
height=height)
return pic_obj
def image_manage(self):
"""
Image management
:return:
"""
# Insert a static image
slide = add_slide(self.presentation, 6)
# Image path
image_path = './1.jpeg'
# Insert local image
insert_image(slide, image_path, 6, 6, unit=Cm)
Note: When width and height are not explicitly specified (default None), the image displays at its actual size. When the image is very large, it may not display completely.
Therefore, in actual projects, we should first get the image’s aspect ratio, then set width and height parameters proportionally:
python
from PIL import Image
def get_image_aspect_ratio(image_path):
"""
Get image aspect ratio
:param image_path:
:return:
"""
img = Image.open(image_path)
# Image type: GIF
image_format = img.format
# Image width, height
width, height = img.size
# Image aspect ratio
aspect_ratio = width / height
return aspect_ratio
# Get width/height ratio
aspect_ratio = get_image_aspect_ratio(image_path)
# Insert image into PPT proportionally
insert_image(slide, image_path, 6, 6, 6, 6 / aspect_ratio, unit=Cm)
4. Videos
The method for inserting videos into PPT documents is:
python
slide.shapes.add_movie(video_path, left, top, width, height, poster_frame_image)
Parameters:
video_path: Video pathleft: Left margintop: Top marginwidth: Video display widthheight: Video display heightposter_frame_image: Video thumbnail path
4.1 Getting Video Aspect Ratio
To ensure videos display completely in PPT, we need to first get the video’s width/height ratio. It’s recommended to install the moviepy dependency library to get video basic information:
python
# Install dependency pip3 install moviepy
Then, create a VideoFileClip object and get the video’s width and height from it:
python
from moviepy.editor import VideoFileClip
def get_video_aspect_ratio_and_thumbnail_path(video_path, frame_index):
"""
Get video width/height ratio
:param video_path: Video path
:param frame_index: Frame index
:return:
"""
clip = VideoFileClip(video_path)
# Video width, height
width, height = clip.size
# Get width/height ratio
aspect_ratio = width / height
4.2 Getting Video Frames
For video thumbnails, we can select a frame from the video and save it locally:
python
def get_video_frame(clip, frame_index):
"""
Get a specific frame from video
:param clip:
:param frame_index:
:return:
"""
# Number of frames
frame_count = math.floor(clip.fps * clip.duration)
# print('Number of video frames:', frame_count)
# Ensure parameter input is valid
if frame_index < 0 or frame_index > frame_count:
frame_index = 1
# All video frames
frames = clip.iter_frames()
# clip.get_frame()
# Define output image path
thumbnail_path = "{}/temp/{}.jpg".format(os.path.abspath(os.path.dirname(__file__)), random_str(10))
# Iterate to find corresponding frame, save locally
for index, frame in enumerate(frames):
if frame_index == index:
# Save frame image locally
im = Image.fromarray(frame)
im.save(thumbnail_path)
break
return thumbnail_path
4.3 Inserting Videos
Finally, encapsulate the video insertion operation. Pass in the video thumbnail, left margin, top margin, and display width to complete video insertion:
python
def insert_video(self):
"""
Insert video
:return:
"""
slide = add_slide(self.presentation, 6)
video_path = './1.mp4'
# Get image aspect ratio and save a temporary thumbnail locally
aspect_ratio, thumbnail_path = get_video_aspect_ratio_and_thumbnail_path(video_path, 120)
# Insert video into PPT
insert_video(slide, video_path, thumbnail_path, 3, 3, 4, 4 / aspect_ratio)
# Insert video into PPT
insert_video(slide, video_path, thumbnail_path, 3, 3, 4, 4 / aspect_ratio)
5. Conclusion
This article covered operations for three common types of content in PPT documents: tables, images, and videos.
Related articles