5,693,062 members and growing! (18,187 online)
Email Password   helpLost your password?
Enterprise Systems » Office Development » General     Intermediate License: The Code Project Open License (CPOL)

PowerPointCreator

By Elmue

This C# (VS 2003) project creates PowerPoint presentations based on XML templates which are filled with dynamic data.
C#, XML, .NET (.NET 1.1, .NET), Dev

Posted: 28 Aug 2008
Updated: 28 Aug 2008
Views: 4,564
Bookmarked: 27 times
Announcements
Loading...



Search    
Advanced Search
Sitemap
8 votes for this Article.
Popularity: 4.09 Rating: 4.53 out of 5
1 vote, 12.5%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
1 vote, 12.5%
4
6 votes, 75.0%
5

Features

  • Purpose: Automation of PowerPoint.
  • This C# (VS 2003) project creates PowerPoint presentations based on XML templates which are filled with dynamic data.
  • The documents are created from the 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 (XP). They also play on PowerPoint 97 with restrictions.

PowerPoint 2003 is Full of Bugs

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

Example:
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 exremely 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 the scratch with PowerPointCreator:

Using the Class PPPcreator

Let's have a look 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 dynmic 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 minimzed 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",
    i_Replacements);

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.

ATTENTION:
!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

<Shapes>
    <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>
        </Row>

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

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.

Textboxes:
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 then the text.

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

Tables: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 it's 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 defintions 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 it's 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:

The XML - Styles Section

<Styles>
    <TitleBox   Shape.TextFrame.MarginLeft="10"
                Shape.TextFrame.TextRange.Font.Name="Arial"
                Shape.TextFrame.TextRange.Font.Size="22"

                Shape.TextFrame.TextRange.Font.Bold="true"
                Shape.TextFrame.TextRange.Font.Color.RGB="#373C71"
                Shape.TextFrame.TextRange.ParagraphFormat.Alignment="ppAlignCenter"
    />
        
    <CellCommon Borders.ppBorderTop.Weight="1"

                Borders.ppBorderBottom.Weight="1"
                Borders.ppBorderLeft.Weight="1"
                Borders.ppBorderRight.Weight="1"
                Borders.ppBorderLeft.ForeColor.RGB="#373C71"
                Borders.ppBorderRight.ForeColor.RGB="#373C71"

                Borders.ppBorderBottom.ForeColor.RGB="#373C71"
                Shape.TextFrame.TextRange.Font.Name="Arial"
                Shape.TextFrame.TextRange.Font.Size="10"
                Shape.Fill.Solid="true"
    />

    <CellDark   Borders.ppBorderTop.ForeColor.RGB="#FFFFFF"
                Shape.TextFrame.TextRange.Font.Bold="true"
                Shape.TextFrame.TextRange.Font.Color.RGB="#FFFFFF"
                Shape.Fill.ForeColor.RGB="#373C71"

    />
    etc....
</Shape>

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 neigbours...
...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.

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:

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

The data to be insterted may come from a database, you can read it from a 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:

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

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:

<Shapes>
     <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>
          </Row>
     </Table>
</Shapes>

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%"});
etc...

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.

Restrictions

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 all 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:

Sourcecode

You will find a very clean and well structured C# sourcecode with plenty 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.

Requirements

to compile or run this project:

  1. Obviously you must have PowerPoint XP installed.
  2. IMPORTANT: in the Office XP 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 XP 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 XP 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..

Elmü

License

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

About the Author

Elmue



Location: Germany Germany

Other popular Office Development articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 6 of 6 (Total in Forum: 6) (Refresh)FirstPrevNext
NewsATTENTION: Version 3.0 released !memberElmue6:11 4 Sep '08  
GeneralRe: ATTENTION: Version 3.0 released !memberkirankonathala11:04 23 Sep '08  
GeneralRe: ATTENTION: Version 3.0 released !memberElmue3:41 26 Sep '08  
GeneralAn Alternative MethodmemberAndrew Rissing14:04 28 Aug '08  
GeneralRe: An Alternative MethodmemberElmue13:38 29 Aug '08  
GeneralRe: An Alternative MethodmemberAndrew Rissing12:53 31 Aug '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 28 Aug 2008
Editor: Sean Ewington
Copyright 2008 by Elmue
Everything else Copyright © CodeProject, 1999-2008
Web12 | Advertise on the Code Project