Creating a PowerPoint Report File
NOTE: Running this example requires installing the pptx Python module
To create a PowerPoint file, we will use the PPTX python module, which is made specifically for manipulating and creating PowerPoint files.
Instead of pages in a PDF, this report is going to show individual slides for each of the turbines from our wind turbine demo.
The best way to start a PowerPoint report is to begin with a template. In this case, we're beginning with a file called Base.pptx.
Setting Up Master Slides
As a shortcut, you can pre-configure some common slide layouts by creating Slide Masters in the template PowerPoint file.
In the example provided, we have two key slides - the first which is a title slide and another which is a chart slide.
The title slide contains two placeholders, one for the title and one for the date. The chart slide contains only one placeholder - a full-page chart.
The Code
import os import sys sys.path.insert(0,os.path.dirname(os.path.dirname(__file__))) import datetime import traceback import ardiapi import mplreport import traceback #Import PPTX from pptx import Presentation from pptx.chart.data import ChartData from pptx.enum.chart import XL_CHART_TYPE from pptx.enum.chart import XL_LEGEND_POSITION from pptx.util import Pt import matplotlib.pyplot as plt @mplreport.ardireport("Oven Temperatures") def CreateReport(report,args): #Figure out the number of samples we are going to need (in this case, 10-second samples). samples = 1000 #Our AQL query goes here query = "('Oven #1') ASSET 'Oven Sequence' RELATIONSHIP 'downi' RELATED ('Temperature - Oven') PROPERTYEX VALUES" #Get the pandas data-frame with the results. df = report.GetHistory(query,samples=samples)
Apart from importing pytx, this is a normal start for a report. It's where we'd normally start drawing our content where things change…
prs = Presentation(os.path.dirname(__file__) + "/Base.pptx") title = prs.slides.add_slide(prs.slide_layouts[0]) title.placeholders[0].text = report.name title.placeholders[1].text = args.localstart.strftime("%c") + " to\n" + args.localend.strftime("%c")
This creates a new PowerPoint presentation, adds a new slide (based on Layout 0, which is our title slide).
We then use the two placeholders to set the title and the range to be displayed on the opening page.
dformat = report.DateFormat() failed = False indx = 0 for col in df.columns: indx += 1 try: #Assemble the X & Y data for the line chart yset = [0] * len(df[col].index) xset = [0] * len(df[col].index) q = -1 for k,v in df[col].items(): q += 1 yset[q] = round(v,0) xset[q] = k.strftime(dformat) #Add a Slide except: traceback.print_exc() failed = True prs.save(args.target + ".pptx")
The code above loops through each of the columns in the dataframe (since in this case we're only getting a single property per turbine).
For each column/turbine, we build two arrays - one containing the X data (timestamps) for a line chart, the other containing the Y data (speed).
Next, we need to create the chart itself.
Building Charts
#Create PowerPoint Chart Data chart_data = ChartData() chart_data.categories = xset chart_data.add_series('Turbine ' + str(indx) + ' Speed',yset) #Add a PowerPoint Chart Slide sld = prs.slides.add_slide(prs.slide_layouts[2]) #Get a reference to the chart placeholder on the new slide... chart = sld.placeholders[13].insert_chart(XL_CHART_TYPE.LINE,chart_data).chart chart.series[0].smooth = True chart.vary_by_categories = False chart.has_data_labels = False #Format the X axis category_axis = chart.category_axis category_axis.has_major_gridlines = True category_axis.tick_labels.font.size = Pt(10) #Format the Y axis value_axis = chart.value_axis value_axis.has_major_gridlines = True value_axis.tick_labels.font.size = Pt(10) #Disable the legend chart.has_legend = False print("Charted Turbine " + str(indx))
After getting those arrays for our X and Y axes, we need to build the report. The code above…
* Creates a PowerPoint 'ChartData' object containing both the X and Y data.
* Creates a new slide that contains a full-page chart object,
* Gets the chart object from the new slide, sets the data and formats the X & Y axis.
Finishing
Finally, we need to save the report.
prs.save(args.target + ".pptx")
Using The Report
When using the report on an ARDI server, you'd be able to…
* Produce a pre-generated daily version of the presentation.
* Store the last several days of the presentation for people to go back to,
* Allow users to create custom presentations for their own time-ranges, and
* Automatically upload presentations to shared locations, such as Teams folders or Sharepoint.