Objective
-
Customizing a PowerPoint export for a custom module, similar to the existing exports.
Note
-
The PowerPoint export runs entirely on the server side and completely replaces the previous client-side IronPython solution; there is no compatibility layer for the old implementation.
-
It is already implemented by default for the standard modules Status (Project Deck
009E9K), Status Report (Project Status Report Deck009E9R), and Simulation (Portfolio Roadmap Deck009E9Uungrouped /009EA9grouped). For a custom module, a so-called deck is also created (see Procedure). -
Each export option requires its own
.pptxtemplate: a normal PowerPoint file with placeholders that can be designed in Microsoft PowerPoint as usual.
Procedure
-
Insert the desired placeholders in the
.pptxtemplate:
|
Placeholder |
Effect |
|---|---|
|
|
Simple text replacement (title, label, any text) |
|
|
Table row is cloned for each record (automatic pagination if the table would extend beyond the slide footer) |
|
|
Shape is replaced by a picture (calue has to be Base64-encoded) |
|
|
Shape marks the area for a chart (schedule/Gantt/roadmap); drawn by an object renderer |
The key.field path corresponds exactly to the Python IDs that the ModuleReader returns for the module.
-
Create a new deck under
next/domain/powerpoint/decks/that inherits fromnext.framework.powerpoint.deck.BaseDeck. -
At a minimum, set
TEMPLATE(file name of the template) and_get_output_filename; if required, override_prepare_datato transform raw data before rendering (e.g., to mark text as bold or to merge nested data into flat fields). -
For a chart, register a suitable renderer in
OBJECT_RENDERERSand implement_get_object_data. -
Create a macro entry point (similar to
next/domain/powerpoint/export.py) that opens the module and callsgenerate_deck().
from next.framework.powerpoint import deck, template
from next.framework.powerpoint.object_renderers import schedule
class MyModuleDeck(deck.BaseDeck):
TEMPLATE = 'MyModule_Template.pptx'
OBJECT_RENDERERS = {'^SCHEDULE': schedule.ScheduleRenderer}
def _get_output_filename(self, data):
row = data['project'][0]
return self._build_output_filename(row['name'], row['func_id'])
def _prepare_data(self, data):
# z.B. Feld fett darstellen
row = data['project'][0]
row['name'] = template.bold_markdown(row['name'])
return data
def _get_object_data(self, marker, data):
if marker != '^SCHEDULE':
return None
tasks = [
schedule.ScheduleTask(
name=row['task_name'],
duration=row.get('duration_rem') or '',
start=_epoch_days_to_date(row.get('calc_start')),
end=_epoch_days_to_date(row.get('calc_end')),
critical=not (float(row.get('buffer') or 0) > 0),
)
for row in data['project'][0].get('schedule', [])
]
return tasks or None
Notes
-
The page describes how a custom deck can be build. How exactly it is wired up to a PLANTA module or a button (macro module, call to
generate_deck()) is only outlined here. It is best to use one of the existing decks (Project Deck, Project Status Report, Portfolio Roadmap) or their macro entry points innext/domain/powerpoint/export.pyas a template. -
Three ready-made renderers are available for charts:
schedule.ScheduleRenderer(flat, paginating schedule),native_gantt.NativeGanttRenderer(hierarchical Gantt chart on a single slide), androadmap.RoadmapRenderer(quarterly portfolio roadmap, optionally grouped). A custom look can be achieved by overriding individual class attributes (colors, font size, row height, …) without touching the renderer logic itself. -
Text and table values support a fixed set of inline Markdown:
**bold**,*italic*,~~strikethrough~~,`code`,[text](url); Line breaks, headings, and lists are not supported. -
A path without an index into a data area with multiple rows (e.g.,
project.namewhen there are several projects) automatically uses row 0 and logs a warning; in this case, add an index (project[2].name). -
An entirely new chart type can be added as a custom
ObjectRenderer(base classnext.framework.powerpoint.object_renderers.base.ObjectRenderer) without having to change anything in the framework itself.