Click here to Skip to main content
15,396,210 members
Articles / Programming Languages / XML
Posted 28 Aug 2008

Tagged as


126 bookmarked


Rate me:
Please Sign up or sign in to vote.
4.96/5 (30 votes)
22 Feb 2011CPOL12 min read
This C# (Visual Studio 2003) project creates PowerPoint presentations based on XML templates which are filled with dynamic data.

Features PPPcreator

  • Purpose: Automation of PowerPoint.
  • This C# (Visual Studio 2003) project creates PowerPoint presentations based on XML templates which are filled with dynamic data.
  • The documents are created from scratch. You can also add new slides into an existing presentation.
  • You can use this project to create Reports on a weekly or monthly basis which display content from a database in a PowerPoint presentation.
  • You can insert dynamic text, tables and pictures,... into the PPP document.
  • The created documents can be played on PowerPoint 2002 up to 2007. They also play on PowerPoint 97 with restrictions.

Features PPPanalyzer

The Analyzer allows to write all properties of all Shapes in an existing PowerPoint Presentation into XML files.


PowerPoint 2003 is Full of Bugs

My first experiments using PowerPoint 2003 failed because PP 2003 is !FULL! of ugly bugs.


You set the width of a border of a table cell. No problem. Afterwards you try to set the color of the same border: result = Exception 0x800A01A8
Then you try to do it in the reverse order: First set the color. No problem. Then set the width: result = Exception 0x800A01A8. This exception has no documentation in MSDN and in the internet you find hundreds of people with the same problem but no solution.

There were a lot of other things which did not work in PP 2003 and all had one thing in common: they were extremely strange and did not make any sense.

I wasted two entire days searching for a workaround: without success. Finally I found the solution: Using PowerPoint 2007 which does not have these bugs anymore.

When I started the project, I didn't want to use PowerPoint 2007 because I wanted to create PPP documents which can also be played on PP 2003. But then I found that my documents created on PP 2007 will also play on PP 2002 and PP 2003 without problems.

IMPORTANT: Read in the last chapter what you have to install additionally to PP 2007!

The PowerPointCreator Project

This project demonstrates the creation of a Sales Report of a fictitious company "Ipsum Colors Inc." which sells paints.

The following animation shows a PowerPoint Presentation consisting of 5 slides which have been created from scratch with PowerPointCreator:

Image 2

Using the Class PPPcreator

Let's have a look at how to create the first page (the start slide):

string      s_TemplatePath = Directory.GetCurrentDirectory() + "\\Templates";
PPPcreator  i_PppCreator   = new PPPcreator(s_TemplatePath, true);

Hashtable   i_Replacements = new Hashtable();
i_Replacements["CurrentDate"] = DateTime.Today.ToString("dd. MMMM yyyy");

i_PppCreator.InsertTemplateSlide(-1, null, "Template_StartSlide.xml", i_Replacements);

It's really that simple! These 5 lines of code create an entire PowerPoint slide! You specify an XML template "Template_StartSlide.xml" and a hashtable with replacements for all dynamic data which is to be inserted into the template (here the current date).

The second parameter of the PPPcreator constructor (true) specifies the creation mode.
true -> PowerPoint opens and you see the creation process "live" on the screen as if you would add all the elements manually.
false -> PowerPoint runs minimized in the taskbar without a visible window. This mode is faster.

You can also insert new slides into an already existing presentation:

i_PppCreator.LoadPresentation   (@"C:\My Documents\....\SalesReport.ppt");
i_PppCreator.InsertTemplateSlide(5, "Template_Background.pot", "Template_XYZ.xml",

The first parameter of InsertTemplateSlide() specifies the zero based insert position of the new slide.

  • 5 -> insert before the 5th slide
  • -1 -> append behind the last slide

The second parameter of InsertTemplateSlide() specifies an optional PowerPoint Template. (*.pot)
From this SlideMaster template only the basic layout (like header and footer) will be loaded, not the content!

The XML Templates

The structure of the XML templates is very similar to HTML files. The templates completely define how the resulting Presentation will look. They contain two main tags:

  1. Styles
  2. Shapes

The Shapes tag contains all PowerPoint Shapes you want to insert into the document like TextBoxes, Tables, Pictures or Lines.
The Styles tag contains definitions of how these elements will look like, for example their color and font size.


  • All Tags and Attributes in the XML file are CASE SENSITIVE!
  • All Values in the XML file MUST be enclosed in quotation marks!

The XML - Shapes Section

    <Textbox Top="60" Left="120" Width="580" Style="TitleBox" Name="Title">
       Sales Report</Textbox>

    <Picture Top="155" Left="120" Width="250" Height="195">Company_Logo.gif</Picture>

    <Table Top="75" Left="45" ColumnWidths="100,120,100,150" MaxHeight="405">
        <Row Height="20">
            <Cell Style="CellCommon,CellDark">First Cell</Cell>
            <Cell Style="CellCommon,CellBright">Second Cell</Cell>
            <Cell Style="CellCommon,CellBright" ColSpan="2">Third and Fourth Cell</Cell>

    <Line BeginX="120" BeginY="465" EndX="120" EndY="494" Style="GreenLine" />

All Shapes use absolute positioning, so the attributes Top and Left are mandatory. The Shapes are drawn in the order in which they appear in the XML file. So if you want to put text on top of a picture you have to define the picture first.

Every Shape can have an optional Name attribute. This name is similar to an ID or Name tag in HTML. It is stored invisible in the PPP document and may be useful to locate a Shape if you want to modify the document later.


You don't need to specify the Height attribute for a Textbox as the height depends on the text which you put into the box. The height is only required if the textbox has a visible border or a background color and is bigger than the text.


All Pictures are loaded from the Template folder which you have specified in the constructor of PPPcreator.


The Table in the above example has 4 columns whose widths (100,120,100,150) you specify in the attribute ColumnWidths.

The Height attribute for table rows is optional. If it is missing, the row's content will define its height. Cells can be combined with their right neighbour using the ColSpan attribute.

As the cells in the above example show, you can specify multiple styles separated by a comma.

In the Styles section of the XML file (see below):

  • CellCommon contains definitions for all cells.
  • CellBright contains only the color definitions for the white cells.
  • CellDark contains only the color definitions for the blue cells.

The MaxHeight attribute for the table defines when its content will be broken onto the next slide. PowerPoint does not do that automatically (like Word does). If the table becomes too high, PowerPointCreator removes as many words from the last table cell as is required to make the text fit on that slide. After that a new slide is appended which receives the rest of the table. To optically show the continuation of a table, it's border becomes dashed:

Image 3

The XML - Styles Section

    <TitleBox   Shape.TextFrame.MarginLeft="10"


    <CellCommon Borders.ppBorderTop.Weight="1"



    <CellDark   Borders.ppBorderTop.ForeColor.RGB="#FFFFFF"


All entries have exactly the same name as the corresponding objects in the namespace PowerPoint.

Don't try to abbreviate these attributes!!

For example: A cell may specify border settings (LineFormat), also a row and a Line use the same properties. There are multiple objects which allow you to specify a ForeColor or BackColor. You will run into a big confusion if you try to simplify these long properties!

If you need additional properties which are not yet supported by the PPPcreator class, you have to add them on your own. I would have liked to use Reflection to set the properties but this is not possible as Microsoft.Office.Interop.PowerPoint is a COM object which does not support Reflection. So each and every property must be set separately in a long switch() statement.

Table Cell Borders

When you define the cell borders, you have to be careful. For each cell you can specify width, color, etc.. for it's top border, bottom border, left border and right border separately. But each cell shares its borders with its neighbours...
...and as a table is painted from top to bottom, the settings of the bottom border of a cell will be overwritten with the settings of the top border of the following row.

Image 4

To obtain a table as you see in this image the cell C must define a top border which is white, but Cell B must define a top border which is blue, while the bottom border of all Cells A-C may be defined as ANYthing which will be ignored as the next row overwrites it with its own settings!

The bottom border will ONLY be of importance in the very last row.
The right border will ONLY be of importance in the very last column.
For all other cells only the top and the left border have importance.

If you study the file "Template_Table.xml" thoroughly, you will understand how it works:

  • The style CellDark defines a white top border.
  • The style CellTopDark defines a blue top border.
  • In the attribute Style="CellDark,CellTopDark" the order of the styles matters!

That means that the TopBorder color in CellTopDark will overwrite the definition in CellDark!

Cell B:

<Cell Style="CellCommon,CellDark,CellTopDark">Priority</Cell>

Cell C:

<Cell Style="CellCommon,CellDark">Finished</Cell>

The Replacements

The Replacements make the templates really dynamic. To insert a dynamic title into a PP slide write in the XML file:

    <Textbox Top="60" Left="120" Width="580" Style="TitleBox">%Title%</Textbox>

The data to be inserted may come from a database, you can read it from an XML file, or get it from wherever you like. You have to store it into a hashtable and pass it to PPPcreator.

Hashtable i_Replacements = new Hashtable();
i_Replacements["Title"] = "Sales Report";
i_PppCreator.InsertTemplateSlide(-1, null, "Template_Table.xml", i_Replacements);

You can do the same with text in table cells or picture files.

Also, the values of Attributes can be defined dynamically. For example, if your template defines different title styles, you can decide at runtime which style to use for the title:

    <Textbox Top="60" Left="120" Width="580" Style="%TitleStyle%">Sales Report</Textbox>

Formatted Text

Another feature is the ability to write formatted text into a PowerPoint TextBox or TableCell.

Image 5

Option 1

The Replacements may contain HTML code if it is enclosed between <HTML> and </HTML>:

i_Replacements["Summary"] = "<Html><b><big>Lorem ipsum</big></b></Html>";

Option 2

You put the HTML code directly into the XML file:

<Textbox Top="60" Left="90" Width="580" Style="TitleBox" Name="Title">
    Sales Report <BR />
    <Font Color="#000088">Business Statistic</Font>
    <small>half-way 2008</small>


  • XML is much stricter than HTML: EVERY Tag must be closed. (also <BR>, <LI>, etc.)
  • XML is case sensitive: you cannot close a <DIV> with a </div>
  • Obviously not all HTML tags are supported. Study the class TextRangeFormat for allowed tags.

Dynamic Lists

And what if I want to create a list with a variable count of rows (for example from a database)? No problem!

Write in the XML file:

     <Table Top="100" Left="65" ColumnWidths="360,77,77,77" MaxHeight="405">
          <Row Height="15" DataSource="SalesData">
               <Cell Style="xyz">%SalesData#Product%</Cell>
               <Cell Style="xyz">%SalesData#Sold%</Cell>
               <Cell Style="xyz">%SalesData#Profit%</Cell>
               <Cell Style="xyz">%SalesData#Percent%</Cell>

The row will be repeated as often as your DataSource has row entries. The replacements must be of the form %DataSourceName#ColumnName%. In the C# code, write:

DataSource i_SalesData = new DataSource(new string[]{ "Product", "Sold", "Profit",
    "Percent" });

i_SalesData.AddRow(new string[]{"LA553 - Gallon Ultra Premium Flat Wall Paint",
    "353.912", "$3.267.000",  "25,7%"});
i_SalesData.AddRow(new string[]{"IN965 - Interior Wall Paint 10 litre Acryl",
    "270.733", "$2.332.000",  "22,4%"});

Hashtable i_Replacements = new Hashtable();
i_Replacements["SalesData"] = i_SalesData;

i_PppCreator.InsertTemplateSlide(-1, "Template_Background.pot",
    "Template_DynamicList.xml", i_Replacements);

The DataSource class is a special class designed to hold table data for dynamic list creation. The names of the columns are defined in the DataSource constructor and must obviously have the same names as the XML entries.

Above you will find an example of everything I've explained in the PowerPointCreator project.

The Analyzer

The second part of the application is the PowerPoint Analyzer.

You specify any existing PPP or PPS file and the Analyzer creates an XML file for each Slide it finds in it.

There are hundreds of properties which a Shape can have.

To avoid an endless XML file the analyzer has built in intelligence:

  1. It does not write values if they are the default properties.
    For example after adding a new TextBox, it has several default properties like Shape.Fill.RotateWithObject="msoFalse".
    These defaults are not written into the generated XML file.
    PowerPointCreator uses the file DefaultShapes.xml to check if a property has its default value.
    The file DefaultShapes.xml must be created once from a real PowerPoint file which contains the default Shapes: the file DefaultShapes.ppt. You don't have to care about this as this is done.
  2. In a second analysis, the analyzer checks all TextBoxes, all TableCells, etc... for their common properties and generates an XML node under <styles> which it stores the common properties. So they are not written 50 times for 50 table cells.
  3. If a property cannot be read or written (PropertyInfo.CanWrite=false), it is skipped. There are several Shape properties which are read-only. It does not make sense to store them in the XML file as they later cannot be assigned in PPPcreator.
  4. There is a lot of ambiguous stuff in a Shape like Shape.TextFrame and Shape.TextFrame2 which is also eliminated.

The result is a handy XML file which can be used as input for the Creator.


Due to the incredible complexity of the PowerPoint API, you must be aware that the generated XML file will probably require manual editing.


Analyzer: It analyzes ANY PowerPoint presentation using its tricky Pseudo-Refection.
Creator: In the current version 5.0 ready to generate Tables, Lines, TextBoxes and Pictures.
But AutoShapes and Groups are premature / not implemented.

PowerPoint is very slow. When you create a presentation "live", you will see how it draws every single table cell and prints the text.

PowerPoint is quite primitive (like the entire Office package). For example, it does not allow you to put a picture into a table cell. This is not possible. Also you cannot append a table row to the end of a table. If the previous row has merged cells (uses ColSpan) the new row would merge the same cells although you never did program that. For all these things PPPcreator has workarounds built in.

A documentation for the PowerPoint API does not exist. What you find in the MSDN is ridiculous. You have to find out everything by trial and error.

Some functions which exist in the PowerPoint API are not implemented. (for example, Slide.Shapes.AddDiagram(...)).

The Helper Grid

All PowerPoint presentations use the odd coordinate system of 720 x 540 pixels. To ease the definition of coordinates when creating the XML file, PowerPointCreator draws a helper grid when compiled in Debug mode. Every 20 pixels, a dashed line is drawn and every 100 units a solid line:

Image 6

Source Code

You will find a very clean and well structured C# source code with plenty of comments, written by a very experienced programmer. The code is reusable, so you can easily put it into your own projects:

  • The class PPPcreator encapsulates all the PowerPoint creation stuff
  • The class DataSource stores Dynamic List data
  • The class XML eases XML file management
  • The class Functions contains a bunch of helper functions


To compile or run this project:

  1. Obviously you must have PowerPoint 2007 installed.

  2. IMPORTANT: in the Office 2007 Installer under "Shared Office Components", you MUST install "Visual Basic for Applications". If this is not installed, you have a severe problem: When creating a presentation, you will get an exception with the most stupid error message Microsoft ever has created: "Unspecified Error". You will search hours and hours to find out why the program runs on one PC but not on the other PC!!

    VB is required although this is a C# project!!

  3. The ".NET Programmability Support" which you find in the Office 2007 installer under "PowerPoint" installs the files Office.dll and Microsoft.Office.Interop.PowerPoint.dll into the Global Assembly Cache.

    But you don't need to install this because I have put these tiny DLLs into the same folder as the EXE and compiled the EXE to run with these 'local' DLLs if they are not found in the GAC. So the program will also run on a computer where only PowerPoint 2007 is installed without these DLLs in the GAC. This avoids crashes, unnecessary problems, frustrated users and a lot of work for the support.

Future Versions

The current version 2.0 contains a lot of useful functionality. Probably future versions, which will be published on CodeProject, will contain more functionality like dynamic generation of diagrams, etc..


  • 28th August, 2008: Initial post
  • 18th December, 2008: Article updated
  • 19th January, 2009: Source updated


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior) ElmüSoft
Chile Chile
Software Engineer since 27 years.

Comments and Discussions

General3Q Pin
kwolfcode16-Aug-10 0:19
Memberkwolfcode16-Aug-10 0:19 
GeneralOffice version error and XML parsing error Pin
BD Mihai27-Apr-10 10:38
MemberBD Mihai27-Apr-10 10:38 
GeneralRe: Office version error and XML parsing error Pin
Elmue28-Apr-10 5:55
MemberElmue28-Apr-10 5:55 
GeneralOffice 2007 Pin
dimy vaxin8-Dec-09 3:51
Memberdimy vaxin8-Dec-09 3:51 
GeneralRe: Office 2007 Pin
Elmue8-Dec-09 12:38
MemberElmue8-Dec-09 12:38 
GeneralUsed for Digital Signage Pin
Clinton Gallagher14-Jan-09 6:51
professionalClinton Gallagher14-Jan-09 6:51 
GeneralRe: web interface ??? Pin
Elmue16-Jan-09 4:56
MemberElmue16-Jan-09 4:56 
GeneralRe: web interface ??? Pin
Clinton Gallagher16-Jan-09 11:39
professionalClinton Gallagher16-Jan-09 11:39 
I need to look around myself of course but have you seen or know if it is possible to use C# to convert to jpeg or png formats?

GeneralPresentations.Open fails Pin
Cyberfriese15-Dec-08 12:13
MemberCyberfriese15-Dec-08 12:13 
GeneralRe: Presentations.Open fails Pin
Elmue18-Dec-08 2:00
MemberElmue18-Dec-08 2:00 
NewsATTENTION: Version 3.0 released ! Pin
Elmue4-Sep-08 5:11
MemberElmue4-Sep-08 5:11 
GeneralRe: ATTENTION: Version 3.0 released ! Pin
kirankonathala23-Sep-08 10:04
Memberkirankonathala23-Sep-08 10:04 
GeneralRe: ATTENTION: Version 3.0 released ! Pin
Elmue26-Sep-08 2:41
MemberElmue26-Sep-08 2:41 
GeneralAn Alternative Method Pin
Andrew Rissing28-Aug-08 13:04
MemberAndrew Rissing28-Aug-08 13:04 
GeneralRe: An Alternative Method Pin
Elmue29-Aug-08 12:38
MemberElmue29-Aug-08 12:38 
GeneralRe: An Alternative Method Pin
Andrew Rissing31-Aug-08 11:53
MemberAndrew Rissing31-Aug-08 11:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.