Skip to main content

Le SDK Open XML 2.0 : introduction et développement


Julien Chable

Julien Chable – Wygwam France

Téléchargez le code-source

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 :

  • Visual Studio 2008 SP1
  • .NET 3.5 SP1
  • SDK Open XML v2 CTP (lien en fin d’article)

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

I. Pourquoi un SDK Open XML v2 ?

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.

Add Reference

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.

II. Quelques mots supplémentaires sur le SDK

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

  1. Version 1.0 – permet la manipulation directe des documents Open XML au niveau des parties.
  2. Version 2.0 – fournie des classes fortement typées pour manipuler le contenu des parties

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.

III. Un remplaçant pour Office Automation

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.

IV. Ce que n’est pas le SDK Open XML

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 :

  • Le SDK n’est pas un remplacement du modèle objet d’Office (VBA ou VSTO),
  • Le SDK ne fourni pas une abstraction placée au dessus du format de fichier, vous manipulez le format Open XML, vous devrez donc en connaître les rudiments essentiels pour utiliser le SDK,
  • Le SDK n’est pas un outil pour convertir les formats entre eux (Open XML vers HTML, XPS vers Open XML, etc - à vous de les développer),
  • Le SDK n’est pas capable de valider un document si vous modifiez vous-même le XML des parties sans passer par le modèle objet du SDK (en soit, c’est déjà une excellente chose que vous ayez accès au XML sous-jacent, et cette possibilité est étudié pour les versions futures),
  • Le SDK ne fournie pas d’outils fonctionnels (pagination de documents Word, recalcul des formules dans un document Excel, fusion de présentation PowerPoint, etc).

V. Les outils livrés avec le SDK

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.

OpenXml Diff

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.

Open xml Diff

Le Class Explorer

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.

Class Explorer

Le Document Reflector

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

Document reflector

VI. Utiliser le SDK Open XML par la pratique

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.

Génération d’un document Word

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.

Resultat Word

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.

Consommer un document Excel

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.

Doc Excel

 

Result at Excel

VII. Conclusion

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.

VIII. Références

Microsoft réalise une enquête en ligne pour comprendre votre opinion sur le site Web de. Si vous choisissez de participer, l’enquête en ligne vous sera présentée lorsque vous quitterez le site Web de.

Souhaitez-vous y participer ?