Plus que tout autre type de documents numériques, les documents bureautiques (Word, Excel et PowerPoint) prennent une place de plus en plus importante dans la vie des entreprises et de ses employés. Souvent vecteur ou source d’informations multi format : texte, feuille de calculs ou encore présentation, ces fichiers représentent et stockent souvent une grande partie du savoir d’une entreprise. Le format de documents bureautiques Open XML issu originellement du savoir-faire de Microsoft en la matière, avant de devenir une norme internationale ISO en 2008, propose justement une structure fiable et flexible pour échanger et véhiculer la majorité des informations du quotidien.
Dans cet article, nous allons parcourir ensemble le SDK Open XML, dans sa deuxième version, afin de mieux comprendre comment aborder les projets utilisant le format Open XML et les outils mis à la disposition des développeurs avec cette nouvelle mouture.
Pré requis :
Pour préparer la lecture de cet article, vous pouvez consulter les articles suivants :
Certains contenus ont été inspirés par l’article de Zeyad Rajabi que vous pouvez trouver à cette adresse : http://blogs.msdn.com/brian_jones/archive/2008/10/14/open-xml-sdk-2-0-architecture.aspx
L’arrivée de .NET 3.0 avait amené une première solution pour manipuler les documents Open XML, du moins au niveau de sa structure Open Packaging Convention, avec l’espace de nom System.IO.Packaging. La sortie du SDK Open XML, première version, allait un cran au-delà en proposant une encapsulation de la couche structurelle OPC des documents Open XML et en offrant un ensemble de classes typées pour chaque partie d’un document.
Cependant, cette première version présentait toujours la même limitation qu’avec System.IO.Packaging ; le fait qu’il fallait toujours manipuler le contenu XML des parties en lisant les spécifications.
Cette nouvelle version du SDK Open XML va quant à elle beaucoup plus loin, car elle offre une totale abstraction – bien qu’elle ne bloquera les plus experts d’entre vous qui désireraient créer le XML eux-mêmes – quand à la structure et au contenu en exposant un modèle objet complet de classes et d’énumération. La majorité des développeurs ne devrait plus trouver d’excuses pour ne pas générer ou à consommer des documents Office sur un serveur ou un client … sans Office !
En effet dans un effort de toujours rendre plus productif les développeurs, Microsoft n’a cessé depuis de fournir aux développeurs des outils pour créer ou consommer des documents Office ; et cela sans nécessiter aucune instance d’Office sur la machine hôte. C’était déjà une réalité avec la sortie de .NET 3 et l’espace de nom System.IO.Packaging, puis la sortie de la première version du SDK Open XML ; aujourd’hui Microsoft frappe fort à nouveau et confirme son engagement envers cette norme de documents bureautiques avec la sortie du SDK Open XML v2.
Le SDK Open XML v2 encapsule la partie structurelle du fichier – organiser selon la spécification Open Packaging Convention - et la structure XML des différentes parties d’un document dans un modèle objet simple et flexible à manipuler. Ceci dit, comment cela se traduit-il en pratique ? Un exemple étant plus parlant qu’un long discours, et pour vous faire une idée rapidement, voici le code nécessaire à un développeur pour créer un document Word entièrement fonctionnel avec le SDK v2 :
using (WordprocessingDocument package = WordprocessingDocument.Create(docName, WordprocessingDocumentType.Document))
{
// Ajouter une partie de contenu au document
package.AddMainDocumentPart();
// Créer le contenu de votre document
package.MainDocumentPart.Document =
new Document(
new Body(
new Paragraph(
new Run(
new Text("Hello World !")))));
// Enregistrer le contenu dans le document
package.MainDocumentPart.Document.Save();
}La création de document bureautique n’a jamais été aussi simple ! Le SDK Open XML v2 gérera lui-même pour vous toutes les opérations de génération ou de manipulation de la structure XML et OPC. Pour résumer, vous pouvez manipuler entièrement un document grâce au modèle objet sans avoir jamais à créer vous-même une quelconque structure XML. Par rapport aux précédents SDK ou librairies disponibles, cette approche simplifie à l’extrême la vie des développeurs.
Deux manipulations sont nécessaires de votre part pour utiliser le SDK Open XML v2 : télécharger la CTP du SDK Open XML (cf lien en fin d’article) et ajouter la référence aux DLLs WindowsBase et DocumentFormat.OpenXml à votre projet.
.png)
Notez que le SDK supporte très bien la programmation avec Linq To XML – comme nous le verrons par la suite - qui permet de requêter ou de construire une structure XML très simplement et rapidement. Côté performance, notez qu’il vous faudra moins de 3 secondes pour générer 1000 documents avec le code précédent sur une machine standard.
Le SDK a été conçu pour être mis à disposition en version fonctionnelle successive (l’équipe itère sur l’aspect fonctionnel du SDK plutôt que sur l’amélioration des fonctionnalités existantes) :
Le SDK Open XML v2 permettra aussi de valider des documents Open XML existants ou ceux que vous avez composé. Néanmoins soyez conscient que le modèle objet proposé ici n’est pas un remplaçant du modèle objet d’Office tel qu’on le retrouve dans VSTO, et que vous devez néanmoins connaître la structure générale des fichiers Open XML. Dans la même logique, ce SDK a été conçu uniquement pour manipuler le format Open XML, par conséquent n’espérez pas y trouver de convertisseurs (vers HTML, XPS, doc, etc), ni de validateur si vous manipulez directement le XML sous jacent sans passer par l’API ou encore d’outils fonctionnels (recalcul de feuille Excel, pagination d’un document Word, etc). Cette version est encore en Community Technology Preview et ne pourra être déployé dans des solutions d’entreprise avant le « Go Live » de l’éditeur.
La réponse n’est pas tranchée, puisque cela dépendra pour beaucoup du scénario que vous devez reproduire. Néanmoins, une chose est sûre : pour générer ou extraire des données d’un document, Office Automation n’est plus la meilleure solution ! En effet, ceux qui déjà créer des solutions à base d’Office Automation sur un serveur se rappelleront sûrement des recommandations de la KB suivante : http://support.microsoft.com/kb/257757.
Les avantages d’utiliser le SDK Open XML sur un serveur sont nombreux : sécurité, performance, stabilité, montée en charge, etc. Vous pouvez donc maintenant créer des solutions stables et capable de montée en charge dans des environnements multithread/multicore ou répartis. Le fait de ne pas avoir d’instance d’Office vous offrira également toute la mémoire et le la puissance processeur nécessaire pour réaliser vos tâches et uniquement celles-ci. Le rapport de performance entre l’utilisation de Office Automation et le SDK Open XML peut varier de 100 à plus de 1000 fois plus rapide pour le SDK Open XML v2.
Vous l’aurez compris, le SDK Open XML peut sans aucun doute se prévaloir du titre de remplaçant d’Office Automation pour les scénarios de génération, de consommation et de manipulations de fichiers Office.
Cependant attention, le SDK Open XML n’est pas un couteau Suisse multifonction auquel nous pouvons tout demander. Il est donc nécessaire de vous communiquer quelques points où le SDK Open XML n’est pas à l’aise ou tout simplement pas fait pour :
Un SDK livré sans outil complémentaire n’en étant pas vraiment un, sachez que cette version du SDK s’accompagne d’une documentation et de plusieurs outils. Leur seul but est d’épauler les développeurs dans leur apprentissage et l’utilisation au jour le jour du SDK. Voici un détail de chaque outil apporté par la version disponible lors de la rédaction de cet article.
Ce premier outil vous permettra de faire la différenciation entre le contenu de deux documents Open XML. Cela a son intérêt lorsque vous générez des documents, si ceux-ci ne s’ouvre pas ou n’affiche pas ce que vous espériez. Il vous suffira alors de les comparer à une version qui s’ouvre, par exemple générer par Office, pour savoir ce que vous devrez modifier dans votre solution de génération de documents Open XML.
.png)
Cet outil est une documentation à part entière dans lequel vous pourrez chercher les classes et les énumérations proposées par le SDK. En face de chaque classe, vous trouverez la section de la spécification Open XML de l’ECMA ainsi que la documentation MSDN de la classe.
.png)
Cet outil est la Rolls des outils de ce SDK puisqu’il permettra aussi bien aux débutants qu’aux experts de pouvoir générer le code de génération d’un document complet, que ce soit un document Word, Excel ou PowerPoint. En effet, il vous suffira d’ouvrir un document avec cet outil, et il générera pour vous l’intégralité du code C# utilisant le SDK Open XML v2 pour générer à l’identique le document ainsi ouvert.
En plus de proposer cette fonctionnalité qui devrait augmenter la productivité des développeurs de façon conséquente, cet outil permet aussi de prendre connaissance du XML de chaque partie ou des éléments du document (paragraphe, cellule, diapositive, etc).
.png)
Les scénarios fonctionnels d’utilisation d’un tel SDK sont assez nombreux, cela peut aller de la simple génération de factures ou de rapports à l’extraction de données pour exportation dans une base de données. N’oublions pas les scénarios de conversion ou de manipulation de documents à la volée (formatage d’entreprise, suppression des données personnelles, etc).
Dans cet article nous allons voir ensemble les deux scénarios de base, à savoir la génération et la consommation de documents. Dans le premier cas, il s’agira d’un document Word, dans le second cas d’un document Excel.
La génération d’un document Word passe simplement par l’utilisation du modèle objet du SDK qui se révèle être très efficace et rapide pour cette tâche. Pour générer le document du code suivant, nous créons simplement deux parties : la partie principale (celle qui contient les paragraphes du document) et la partie de style (contenant l’ensemble des styles du document) :
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Create("SampleDemo.docx",
DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
// Création d'une nouvelle partie de contenu
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
// Création d'un nouveau paragraphe
Document mainDoc = new Document(
new Body(
new Paragraph(
new ParagraphProperties(
new ParagraphStyleId() { Val = "Title" }),
new Run(
new RunProperties(
new Italic()),
new Text("Bienvenue au SDK Open XML V2 !")))));
// Enregistrement de la partie
mainDoc.Save(mainPart);
// Création d'une nouvelle partie de style
StyleDefinitionsPart stylePart = mainPart.AddNewPart<StyleDefinitionsPart>();
Styles styles = new Styles(
new Style(
new Name() { Val = "Title" },
new BasedOn() { Val = "Normal" },
new NextParagraphStyle() { Val = "Normal" },
new LinkedStyle() { Val = "TitleChar" },
new UIPriority() { Val = 10 },
new PrimaryStyle(),
new Rsid() { Val = "002C2DBE" },
new ParagraphProperties(
new ParagraphBorders(
new BottomBorder() { Val = BorderValues.Single, Color = "auto", Size = (UInt64)4UL, Space = (UInt64)1UL }),
new SpacingBetweenLines() { Line = 240, LineRule = LineSpacingRuleValues.Auto },
new ContextualSpacing()),
new RunProperties(
new RunFonts() { AsciiTheme = ThemeFontValues.MajorHighAnsi, HighAnsiTheme = ThemeFontValues.MajorHighAnsi, EastAsiaTheme = ThemeFontValues.MajorEastAsia, ComplexScriptTheme = ThemeFontValues.MajorBidi },
new Spacing() { Val = 5 },
new FontSize() { Val = (UInt64)52UL },
new FontSizeComplexScript() { Val = (UInt64)52UL })
) { Type = StyleValues.Paragraph, StyleId = "Title" });
// Enregistrement des styles
styles.Save(stylePart);
}Comme énoncer précédemment, l’utilisation du SDK Open XML v2 nécessite une connaissance du format. Chaque classe utilisée dans le code précédent représente un élément ou un attribut XML qu’il vous faudra connaître pour exploiter le format à son maximum.
L’exécution de l’application permettra de générer un document que vous ouvrirez sans aucun problème dans Office 2007 ou Open Office 3.0.
.png)
Utilisé parallèlement avec Linq et les nouvelles fioritures de la nouvelle syntaxe de C# 3, la productivité des développeurs atteindra son apogée dans ce genre de projet.
Attaquons nous maintenant à la discipline inverse de la précédente partie, c'est-à-dire, la consommation de données d’un document Open XML. L’exemple qui suit procède à l’extraction des données d’un document Excel en utilisant le SDK et un peu de Linq.
static WorksheetPart ObtenirPartieFeuille(WorkbookPart classeur, string nomFeuille)
{
try {
Sheet feuille = classeur.Workbook.Descendants<Sheet>()
.Where(s => nomFeuille.Equals(s.Name)).First();
return (WorksheetPart)classeur.GetPartById(feuille.Id);
}
catch (Exception) {
return null;
}
}
static Cell ObtenirCellule(WorksheetPart feuille, int indexLigne, int indexColonne)
{
try {
Row row = feuille.Worksheet.Descendants<Row>()
.Where(r => indexLigne == r.RowIndex).First();
return (Cell)row.ChildElements.ElementAt(indexColonne);
}
catch (Exception) {
return null;
}
}static string ObtenirValeurCellule(Cell cellule, SharedStringTablePart sharedStringTablePart)
{
if (cellule.ChildElements.Count == 0)
return null;
string value = cellule.CellValue.InnerText;
if ((cellule.DataType != null) && (cellule.DataType == CellValues.SharedString))
value = sharedStringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
return value;
}
static void Main(string[] args)
{
using (SpreadsheetDocument excelDoc = SpreadsheetDocument.Open("Sample.xlsx", false))
{
WorksheetPart feuille1 = ObtenirPartieFeuille(excelDoc.WorkbookPart, "Sheet1");
Cell cA1 = ObtenirCellule(feuille1, 1, 0); // Ligne 1, première colonne (base 0)
Cell cA2 = ObtenirCellule(feuille1, 2, 0); // Ligne 2, première colonne (base 0)
Console.WriteLine("{0} {1}", ObtenirValeurCellule(cA1, excelDoc.WorkbookPart.SharedStringTablePart), ObtenirValeurCellule(cA2, excelDoc.WorkbookPart.SharedStringTablePart));
}
}Le SDK v2 rend la consommation d’un document Open XML aussi aisée que la génération. Les classes typées du SDK répondent à la logique de Linq to XML et elles vous permettront d’écrire du code de façon productive et intuitive sans vous égarer dans les méandres techniques de la sérialisation/désérialisation XML.
A l’instar de l’exemple sur la génération du document Word, il vous faudra connaître les bases de la structure d’un document pour être à même de récupérer les données voulues. Par exemple, dans le cas d’un document Excel, vous devez savoir que les valeurs de type chaines sont contenues dans une partie indépendante qui indexe toutes les chaines de votre classeur afin d’en optimiser le stockage.
.png)
.png)
La création de documents bureautiques Office n’a jamais été aussi simple avant l’arrivée du SDK v2. Cette version devrait apporter aux développeurs de la productivité et de la simplicité dans la manipulation de documents Office, et cela, quelques soit le format utilisé (Word, Excel ou PowerPoint). Les nombreux outils annexés avec cette version du SDK assureront également deux objectifs : le premier de formation et le second d’accroitre encore votre productivité.
Cette version du SDK, bien qu’encore en CTP, est relativement stable et performante et mérite que l’on y prête attention pour les projets à venir. Néanmoins, son statut de CTP vous empêchera de la déployer dans vos projets clients pour le moment. Il faudra sûrement attendre la sortie du SP2 d’Office 2007 ou de Office « 14 » pour savourer la fraîcheur de cette librairie qui n’augure que de bonnes choses pour les documents Office dans les années à venir.
Egalement, n’oubliez pas de rejoindre la communauté Connect sur le site associé au SDK (https://connect.microsoft.com/site/sitehome.aspx?SiteID=589) afin de déposer vos feedbacks, vos bugs, etc et de contribuer à son amélioration.