Paru le 12 mars 2006
Par Pierre Lagarde, Microsoft France
Sur cette page
Introduction
Création du Template dans Powerpoint
Ajout du document Powerpoint dans le projet Visual Studio en tant que ressource
Insérer un graphique
Insérer des animations
Conclusion
Introduction
La création de document Office sur le serveur est maintenant beaucoup plus facile grâce au nouveau format de fichier Open XML que propose Office 2007. Ce format n’est, en effet, qu’un fichier ZIP contenant des fichiers XML, en opposition avec l’ancien format binaire que représentait un fichier .doc, .xls ou .ppt.
Ainsi, il est maintenant possible de créer ou de manipuler des documents Office sur un serveur, sans avoir à y installer Office.
C’est dans ce contexte qu’on va tenter de réaliser une application console qui génèrera un document Powerpoint. Etant donné que la structure XML de base pour construire un document Powerpoint vide est relativement lourde et complexe, on va partir d’un document Powerpoint vide préalablement créé dans Powerpoint et qui sera modifié. Ce document sera embarqué en tant que ressource de l’application console.
Pour simplifier la manipulation de document Open XML, on utilisera l’API du Framework 3.0 « System.IO.Package ».
Pour pouvoir importer ce package dans une solution Visual Studio, il faut installer le Framework 3.0 son SDK et l’Add-on à Visual Studio.
Détail d’un fichier Powerpoint exemple
Un document Open XML Powerpoint contient cette arborescence :
Le répertoire « worksheets » contient un fichier XML par feuille de calcul Excel. Ces fichiers XML respectent le format SpreadSheetML.
Schéma disponible ici : http://www.ecma-international.org/news/TC45_current_work/TC45-2006-50_final_draft.htm
Voici une vision complète des éléments que contient un fichier Powerpoint :
Création du Template dans Powerpoint
La première étape consiste à créer un document Powerpoint qui nous servira de model dans notre application et qu’on ajoutera en tant que ressource dans le projet Visual Studio.
Créer une présentation avec 2 slides (Titre + Slide standard).
Ajout du document Powerpoint dans le projet Visual Studio en tant que ressource
Pour ajouter une ressource à un projet, il faut aller dans les propriétés du projet et ajouter une ressource de type fichier.
Ici, on ajoutera une ressource existante qui sera le document Powerpoint qu’on vient de créer.
Un répertoire « Resources » est créé dans la solution Visual Studio contenant le fichier Powerpoint.
Extraction du model et manipulation pour générer le document cible Powerpoint
Ce qui ne reste plus qu’a faire :
-
Extraire le document des ressources.
-
Ouvrir les packages pour éditer le fichier Powerpoint.
-
Manipuler les documents XML pour mettre à jour le model en vue du document cible.
-
Générer le document final sous forme de fichier physique.
Extraire le document des ressources
On va ouvrir le package à partir des ressources de l’application.
using (PackageHelper package =
new PackageHelper(Properties.Resources.PowerPointSample))
{…}
Ouvrir les packages pour éditer le fichier Powerpoint
L’idée, ici, pour simplifier le développement, est de créer un objet Slide qui permettra de manipuler plus facilement le document Powerpoint.
La méthode static « Open » permet d’instancier un objet Slide avec toutes ses propriétés
// URI vers le slide[x].xml
Uri uri = new Uri(string.Format("/ppt/slides/{0}.xml", name), UriKind.Relative);
// Vérifie l’existance de la Part
if (package.PartExists(uri))
return new Slide(package, uri);
else
return null;
On va pouvoir maintenant manipuler l’objet Slide.
Manipuler les documents XML
Dans PresentationML, toute la partie texte se fait dans le fichier slide.xml.
Pour modifier le titre et le sous-titre du Slide 1, il faut venir modifier dans le fichier XML le nœud <a:r><a:t>Text</a:t></a:r> à l’endroit indiqué par la flèche sur le schéma.
public void WritePlaceholderString(string name, string text)
{
// Requête XPath pour atteindre le bon nœud dans le document
string xPathQuery = string.Format(
"//p:sp[p:nvSpPr/p:cNvPr/@name='{0}']" +
"/p:txBody/a:p/a:endParaRPr",
name);
XPathNavigator subTitleNav = PackageData.CreateNavigator()
.SelectSingleNode(xPathQuery,
Namespaces.NamespaceManager);
// Création d’un writer pour insérer dans le XML
using (XmlWriter writer = subTitleNav.InsertBefore())
{
// Insertion du nœud
// <a:r><a:t>Text String</a:t></a:r>
writer.WriteStartElement(Prefixes.DrawingML, "r",
Namespaces.DrawingML);
writer.WriteElementString(Prefixes.DrawingML, "t",
Namespaces.DrawingML, text);
writer.WriteEndElement();
}
}
On appellera 2 fois la méthode, 1 fois sur le titre « Title 1 » et une fois sur le sous-titre
« Subtitle 2 ». Puis la méthode Flush() pour finaliser l’écriture dans les différents « writer ».
slide1.WritePlaceholderString("Title 1", "Présentation de PresentationML");
slide1.WritePlaceholderString("Subtitle 2","Demo Microsoft France");
slide1.Flush();
Générer le document final sous forme de fichier physique
Il ne reste plus qu’a créer le fichier physique.
// Vide les buffers et ferme le Package
m_package.Flush();
m_package.Close();
// Ecriture du Package modifiée sur disque
using (FileStream outputStream = File.Create(filename))
m_packageData.WriteTo(outputStream);
// Fermeture du Package
m_packageData.Close();
Insérer un graphique
Les graphiques dans Powerpoint, Excel et Word utilisent un schéma XML commun qui s’appelle le DrawingML. C’est à partir de ce schéma qu’on peut faire des éléments graphiques tels que :
-
Le texte graphique (effet de relief, ombré, etc.)
-
Des « shapes » (carrés, flèches, etc.)
-
Les effets visuels sur les images (relief, encadré, etc.)
-
Le contenu multimédia (audio / vidéo)
-
Les graphiques (diagramme, camembert, etc.)
Le DrawingML que constitue le graphique sera stocké en tant que ressource de l’application. Les graphiques ne sont pas stockés dans slide.xml mais dans « /ppt/charts/chart[x].xml ».
Les étapes à suivre pour insérer un graphique sont :
Créer la Part
De la même manière que pour les Slides on avait un objet « Slide », on va manipuler ici un objet « Chart ».
La création d’un objet Chart créé la Part associée.
public static Chart Create(PackageHelper package, string name, byte[] data)
{
// Uri du Package
Uri chartUri = new Uri(
string.Format(
"/ppt/charts/{0}.xml", name),
UriKind.Relative);
package.CreateNewPart(chartUri,
"application/vnd.Open XMLformats-" +
"officedocument.drawingml.chart+xml",
data);
// Renvoi une instance de Chart
return new Chart(package, chartUri);
}
Créer la relation entre les deux Parts
Via l’API de System.IO.Package en une instruction, on peut établir la relation entre les deux Packages, slide.xml et chart.xml.
// Création de la relation
string relId =
base.Package.CreateInternalRelationship(base.Uri,
chart.Uri,
"http://schemas.Open XMLformats.org/officeDocument/" +
"2006/relationships/chart");
Remplir la Part du graphique et insérer l’ID dans le slide.xml
La dernière étape consiste à ajouter dans le slide.xml un ID qui correspondra à l’ID du graphique et venir remplir la Part « chart.xml » par le graphique se trouvant en ressource.
// Recherche de l’ID pour le graphique +1
int newDrawingId = 0;
XPathNodeIterator drawingIdsIt =
PackageData.CreateNavigator().Select(
"//p:cNvPr/@id", Namespaces.NamespaceManager);
foreach (XPathNavigator drawingId in drawingIdsIt)
if (int.Parse(drawingId.Value) > newDrawingId)
newDrawingId = int.Parse(drawingId.Value);
newDrawingId++; // id +1
// Ajout de l’ID au slide.xml
XPathNavigator spTreeNav =
PackageData.CreateNavigator().SelectSingleNode(
"p:sld/p:cSld/p:spTree",
Namespaces.NamespaceManager);
// Remplissage du char.xml par le graphique des ressources
spTreeNav.AppendChild(
string.Format(Properties.Resources.ChartDrawingTemplate,
newDrawingId,
Path.GetFileNameWithoutExtension(
chart.Uri.OriginalString),
x, y, cx, cy,
relId));
Insérer des animations
Comme dernier exemple de cet article, on va ajouter une animation de transition entre les slides et une animation de zoom sur le graphique du slide 2.
Animation de transition
L’animation de transition se fait dans la Part « slide.xml » sous le nœud <p :sld>.
// Trouver le nœud du slide
XPathNavigator slideNav =
PackageData.CreateNavigator().SelectSingleNode(
"p:sld", Namespaces.NamespaceManager);
// Ajouter le nœud de transition
using (XmlWriter writer = slideNav.AppendChild())
{
// <p:transition>
// <p:push dir="u" />
// </p:transition>
writer.WriteStartElement(Prefixes.PresentationML,
"transition", Namespaces.PresentationML);
writer.WriteStartElement(Prefixes.PresentationML,
"push", Namespaces.PresentationML);
writer.WriteAttributeString("dir", "u");
writer.WriteEndElement();
writer.WriteEndElement();
}
Animation de zoom sur le graphique
Le XML à générer pour créer une animation n’est pas forcément simple, on utilisera donc toujours la même astuce : créer une animation dans Powerpoint sur un objet, extraire cette animation depuis le document Open XML, l’ajouter en tant que ressource pour pouvoir l’insérer dans le document cible.
Dans cet exemple, l’ajout de l’animation est réalisé en 2 temps :
Les deux ont besoin d’avoir une référence à l’ID du graphique qui sera animé. On retrouve donc, dans le XML, {0} qui sera remplacé par l’ID du graphique au moment du string.Format
// Ajout du squelette d’animation
XPathNavigator slideNav =
PackageData.CreateNavigator().SelectSingleNode(
"p:sld", Namespaces.NamespaceManager);
slideNav.AppendChild(
string.Format(Properties.Resources.TimingBaseTemplate,
graphicId));
// Ajout de l’effet de zoom
XPathNavigator animationNav =
PackageData.CreateNavigator().SelectSingleNode(
"//p:cTn[@nodeType='mainSeq']/p:childTnLst/p:par",
Namespaces.NamespaceManager);
animationNav.AppendChild(
string.Format(animation, graphicId));
Conclusion
Nous avons donc réussi à créer un document Powerpoint à partir d’un Template. Nous avons vu comment manipuler le jeu de slides, ajouter des éléments graphiques, des transitions et des animations, tout en manipulant « PresentationML » et « DrawingML ».
Ce scénario peut donc être appliqué dans des solutions purement serveur, sans que Powerpoint ne soit installé sur le serveur. En définitive, ce n’est que de la manipulation de package (facilitée par le Framework 3.0 l’API de System.IO.Package) et de la manipulation de XML.
Téléchargez
OpenXML-Creation-document-Powerpoint-a-partir-Template-Sample.zip
183 Ko