Skip to content

Commit 1f90e09

Browse files
committed
Adding PowerPoint program examples
1 parent ce340ee commit 1f90e09

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed

code/analyze_ppt.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"""
2+
See http://pbpython.com/creating-powerpoint.html for details on this script
3+
Requires https://python-pptx.readthedocs.org/en/latest/index.html
4+
5+
Program takes a PowerPoint input file and generates a marked up version that
6+
shows the various layouts and placeholders in the template.
7+
"""
8+
9+
from __future__ import print_function
10+
from pptx import Presentation
11+
import argparse
12+
13+
14+
def parse_args():
15+
""" Setup the input and output arguments for the script
16+
Return the parsed input and output files
17+
"""
18+
parser = argparse.ArgumentParser(description='Analyze powerpoint file structure')
19+
parser.add_argument('infile',
20+
type=argparse.FileType('r'),
21+
help='Powerpoint file to be analyzed')
22+
parser.add_argument('outfile',
23+
type=argparse.FileType('w'),
24+
help='Output powerpoint')
25+
return parser.parse_args()
26+
27+
28+
def analyze_ppt(input, output):
29+
""" Take the input file and analyze the structure.
30+
The output file contains marked up information to make it easier
31+
for generating future powerpoint templates.
32+
"""
33+
prs = Presentation(input)
34+
# Each powerpoint file has multiple layouts
35+
# Loop through them all and see where the various elements are
36+
for index, _ in enumerate(prs.slide_layouts):
37+
slide = prs.slides.add_slide(prs.slide_layouts[index])
38+
# Not every slide has to have a title
39+
try:
40+
title = slide.shapes.title
41+
title.text = 'Title for Layout {}'.format(index)
42+
except AttributeError:
43+
print("No Title for Layout {}".format(index))
44+
# Go through all the placeholders and identify them by index and type
45+
for shape in slide.placeholders:
46+
if shape.is_placeholder:
47+
phf = shape.placeholder_format
48+
# Do not overwrite the title which is just a special placeholder
49+
try:
50+
if 'Title' not in shape.text:
51+
shape.text = 'Placeholder index:{} type:{}'.format(phf.idx, shape.name)
52+
except AttributeError:
53+
print("{} has no text attribute".format(phf.type))
54+
print('{} {}'.format(phf.idx, shape.name))
55+
prs.save(output)
56+
57+
58+
if __name__ == "__main__":
59+
args = parse_args()
60+
analyze_ppt(args.infile.name, args.outfile.name)

code/create_ppt.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
from __future__ import print_function
2+
from pptx import Presentation
3+
from pptx.util import Inches
4+
import argparse
5+
import pandas as pd
6+
import numpy as np
7+
from datetime import date
8+
import matplotlib.pyplot as plt
9+
import seaborn as sns
10+
11+
12+
def df_to_table(slide, df, left, top, width, height, colnames=None):
13+
"""Converts a Pandas DataFrame to a PowerPoint table on the given
14+
Slide of a PowerPoint presentation.
15+
The table is a standard Powerpoint table, and can easily be modified with the Powerpoint tools,
16+
for example: resizing columns, changing formatting etc.
17+
Arguments:
18+
- slide: slide object from the python-pptx library containing the slide on which you want the table to appear
19+
- df: Pandas DataFrame with the data
20+
Optional arguments:
21+
- colnames
22+
https://github.com/robintw/PandasToPowerpoint/blob/master/PandasToPowerpoint.py
23+
"""
24+
rows, cols = df.shape
25+
res = slide.shapes.add_table(rows + 1, cols, left, top, width, height)
26+
27+
if colnames is None:
28+
colnames = list(df.columns)
29+
30+
# Insert the column names
31+
for col_index, col_name in enumerate(colnames):
32+
# Column names can be tuples
33+
if not isinstance(col_name, str):
34+
col_name = " ".join(col_name)
35+
res.table.cell(0, col_index).text = col_name
36+
37+
m = df.as_matrix()
38+
39+
for row in range(rows):
40+
for col in range(cols):
41+
val = m[row, col]
42+
text = str(val)
43+
res.table.cell(row + 1, col).text = text
44+
45+
46+
def parse_args():
47+
""" Setup the input and output arguments for the script
48+
Return the parsed input and output files
49+
"""
50+
parser = argparse.ArgumentParser(description='Create ppt report')
51+
parser.add_argument('infile',
52+
type=argparse.FileType('r'),
53+
help='Powerpoint file used as the template')
54+
parser.add_argument('report',
55+
type=argparse.FileType('r'),
56+
help='Excel file containing the raw report data')
57+
parser.add_argument('outfile',
58+
type=argparse.FileType('w'),
59+
help='Output powerpoint report file')
60+
return parser.parse_args()
61+
62+
63+
def create_pivot(df, index_list=["Manager", "Rep", "Product"],
64+
value_list=["Price", "Quantity"]):
65+
"""
66+
Take a DataFrame and create a pivot table
67+
Return it as a DataFrame pivot table
68+
"""
69+
table = pd.pivot_table(df, index=index_list,
70+
values=value_list,
71+
aggfunc=[np.sum, np.mean], fill_value=0)
72+
return table
73+
74+
75+
def create_chart(df, filename):
76+
""" Create a simple bar chart saved to the filename based on the dataframe
77+
passed to the function
78+
"""
79+
df['total'] = df['Quantity'] * df['Price']
80+
final_plot = df.groupby('Name')['total'].sum().order().plot(kind='barh')
81+
fig = final_plot.get_figure()
82+
fig.set_size_inches(6, 4.5)
83+
fig.savefig(filename, bbox_inches='tight', dpi=600)
84+
85+
86+
def create_ppt(input, output, report_data, chart):
87+
""" Take the input powerpoint file and use it as the template for the output
88+
file.
89+
"""
90+
prs = Presentation(input)
91+
# Use the output from analyze_ppt to understand which layouts and placeholders
92+
# to use
93+
# Create a title slide first
94+
title_slide_layout = prs.slide_layouts[0]
95+
slide = prs.slides.add_slide(title_slide_layout)
96+
title = slide.shapes.title
97+
subtitle = slide.placeholders[1]
98+
title.text = "Quarterly Report"
99+
subtitle.text = "Generated on {:%m-%d-%Y}".format(date.today())
100+
# Create the summary graph
101+
graph_slide_layout = prs.slide_layouts[8]
102+
slide = prs.slides.add_slide(graph_slide_layout)
103+
title = slide.shapes.title
104+
title.text = "Sales by account"
105+
placeholder = slide.placeholders[1]
106+
pic = placeholder.insert_picture(chart)
107+
subtitle = slide.placeholders[2]
108+
subtitle.text = "Results consistent with last quarter"
109+
# Create a slide for each manager
110+
for manager in report_data.index.get_level_values(0).unique():
111+
#print(report_data.xs(manager, level=0).reset_index())
112+
slide = prs.slides.add_slide(prs.slide_layouts[2])
113+
title = slide.shapes.title
114+
title.text = "Report for {}".format(manager)
115+
top = Inches(1.5)
116+
left = Inches(0.25)
117+
width = Inches(9.25)
118+
height = Inches(5.0)
119+
# Flatten the pivot table by resetting the index
120+
# Create a table on the slide
121+
df_to_table(slide, report_data.xs(manager, level=0).reset_index(),
122+
left, top, width, height)
123+
prs.save(output)
124+
125+
126+
if __name__ == "__main__":
127+
args = parse_args()
128+
df = pd.read_excel(args.report.name)
129+
report_data = create_pivot(df)
130+
create_chart(df, "report-image.png")
131+
create_ppt(args.infile.name, args.outfile.name, report_data, "report-image.png")

0 commit comments

Comments
 (0)