subscribe: Posts | Comments

Create a Word file with OpenXML. Net

0 comments
HTML clipboard

I. Introduction
With the arrival of the new version of Microsoft Office 2007, Microsoft introduced the new document format Office Open XML to Word, Excel and PowerPoint and succeeding the binary file formats of Office (. Doc,. Xls and. Ppt) emerged with the release of Office 97.

With this new format recently standardized by the ECMA, Word files are becoming mere packages zip files containing XML. Thus, it is no longer necessary to have Microsoft Word to create or view files, a simple text editor or a "home" is enough.

In this article we will first learn the basic code needed to create a Word document format Open XML containing a simple text. We etofferons then this code to change the appearance (police, colour, font) text. Finally, we will see how to add any object (text or binary) to our document (in our case it will be an image).

II. Reminder on the structure of a document WordProcessingML
WordprocessingML is a set of conventions to represent a Word document format Open XML. For Excel documents there SpreadsheetML and PowerPoint documents it is PresentationML.

This article is not intended to introduce you to the architecture and structure of a document the Open XML format. You must have read before reading this article. If this is not the case, I advise you to visit these links: white papers and structure of a document Open XML. However, we will still make a little reminder on the structure of a document (or package) Open XML type WordprocessingML you can view particular by adding the extension. Zip files. Docx and opening it with your reader zip files.
The three main components of the new format are:

Units: Each file contained in the tree is a Part. Most are XML files but there may also be binary files (pictures, videos, etc. OLE objects.) Or even other multimedia files Open XML if the Word document contains.

The type of content: they are metadata contained in the file [Content_Types]. Xml and to describe the type of content stored in a Share (jpeg file of styles, file relationships, etc.).. You can also see which method of reading used to read a Part.

The relationship: they help define the associations between a source and a share target. Relations specify how shares are mixed to form a document. The relationships are defined in the files. Tural.
The docProps folder contains files document properties.
The document.xml file is the main Part of a document WordprocessingML and contains the text of the document.

III. Prerequisites necessary
To facilitate the task, the Framework 3.0 from Microsoft. NET includes new packaging API provided in the WindowsBase.dll assembly. The classes that constitute the API packaging are contained in the namespace System.IO.Package.

You will need Framework 3.0 and its SDK.
To add a reference to your project in Visual Studio: in the draft menu, click add a reference. If the dll WindowsBase is not in the tab. Net, choose the Browse tab and go look for it in Program Files Reference Assemblies Microsoft Framework v3.0.

You should also refer namespaces System.IO and System.Xml in your project:
using System.IO;
using System.Xml;
using System.IO.Packaging;

IV. Creating a first document WordprocessingML
The purpose of this first step is to create a first docx document whose contents document.xml file (see the tree) is as follows:
<? xml version = "1.0" encoding = "utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t> Hi! </ w: t>
</ w: r>
</ w: p>
</ w: body>
</ w: document>
We have here the minimum content that should have the document.xml file. The explanations on the different tags will be discussed later.

IV-A. Analysis code
At the level of C # code, nothing really complicated. Indeed, it is sufficient for the moment to create an object XmlDocument and fill it with nodes necessary to obtain the desired tree (the manipulation of XML standard sum):

/ / Using the NameSpace WordprocessingML:
WordprocessingML string = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";

/ / Creation of WordML
XmlDocument xmlStartPart = new XmlDocument ();
XmlElement tagDocument = xmlStartPart.CreateElement ( "w: document", WordprocessingML);
xmlStartPart.AppendChild (tagDocument);
XmlElement tagBody = xmlStartPart.CreateElement ( "w: body," WordprocessingML);
tagDocument.AppendChild (tagBody);
XmlElement tagParagraph = xmlStartPart.CreateElement ( "w: p", WordprocessingML);
tagBody.AppendChild (tagParagraph);
XmlElement tagRun = xmlStartPart.CreateElement ( "w: r", WordprocessingML);
tagParagraph.AppendChild (tagRun);
XmlElement tagText = xmlStartPart.CreateElement ( "w: t", WordprocessingML);
tagRun.AppendChild (tagText);

/ / Insert Text
XmlNode nodeText = xmlStartPart.CreateNode (XmlNodeType.Text, "w: t", WordprocessingML);
nodeText.Value = "Hi!"
tagText.AppendChild (nodeText);

Now is the namespace System.IO.Packaging will serve us. It contains a class effect Package, which presents a static Open method for creating new packages and open existing packages. Attention, calling the method Open will be followed by a call to the method Close. We turn here as a parameter the name of our file, the fact that it already exists on delete and the fact that it has access to reading / writing:
/ / Creating a new package
Package pkgOutputDoc = null;
pkgOutputDoc = Package.Open ( "monFichier.docx", FileMode.Create, FileAccess.ReadWrite);

Once the package created, we will now create a Share (remember, this is one of three components that we discussed during the recall on the structure of a file docx). This document will share document.xml contained in the directory word. For this we CreatPart method which expects a parameter Uri to specify where to locate the document.xml file in the package and a string specifying the type of file contents. We specify here "application / vnd.openxmlformats-

officedocument.wordprocessingml.document.main + xml" which means that Part contains information of our main docx document (ie where the text will be stored in Word document, in our case: "hello!").
/ / Creating a share
Uri uri = new Uri ( "/ word / document.xml" UriKind.Relative);
PackagePart partDocumentXML = pkgOutputDoc.CreatePart (uri,
"application / vnd.openxmlformats-officedocument.wordprocessingml.document.main + xml");

To finish this stage, it remains to serialize the contents of the share in the package:
StreamWriter streamStartPart = new StreamWriter (partDocumentXML.GetStream (FileMode.Create, FileAccess.Write));
xmlStartPart.Save (streamStartPart);
streamStartPart.Close ();
The writing our document.xml file is now complete. But there is still one last step to finish the creation of our document WordprocessingML. Indeed, if we take the three main components that we discussed earlier, we forgot one: the element relationship. Insert the document.xml file in the package is not enough, we must also link the package. For this, we have the method CreateRelationship is known since our aim Package. We turn first parameter being built Uri previously representing the target of the relationship. The second parameter can specify if this target is located inside or outside of the package. The third parameter defines the type of relationship. Here we have a relationship type officeDocument because this is the type of relationship which is the main share package (document.docx). Finally, the last parameter is used to give an identifier to this relationship.

/ / Create the RelationShip
pkgOutputDoc.CreateRelationship (uri, TargetMode.Internal,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", "rId1");
pkgOutputDoc.Flush ();

/ / Closure package
pkgOutputDoc.Close ();
Here, the creation of our first Word document is complete. If you run this code will get you a document which monFichier.docx here is the display in Word 2007:


IV-B. Analysis of the file generated
Let's take a look at the files created. If you extract the contents of the document monFichier.docx you go find the tree outlined at the beginning (even if it is right now a lot lighter).

At the root you'll find the file [Content_Types]. Xml which describes the types of content of the various units of the package:
<? xml version = "1.0" encoding = "utf-8"?>
<Types Xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="xml" ContentType="application/vnd.openxmlformats- officedocument.wordprocessingml.document.main+xml" />
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
</ Types>

You can see here the type of content"application / vnd.openxmlformats-officedocument.wordprocessingml.document.main + xml" that we have previously defined in the Code C #.

You will also find a directory _rels which contains the file. Tural containing elements relationship:
<? xml version = "1.0" encoding = "utf-8"?>
<Relationships Xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship
Type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
Target = "/ word / document.xml" Id = "rId1" />
</ Relationships>
There are many rId1 the relationship that we defined in the Code C # with the target file document.xml.

V. The main document Part
Before we can expand our text (adding paragraphs, colors, etc.). We must first understand the structure of the main Part of a document Open XML file document.xml. As you would expect, the various changes that we want to make to our text will be thanks to the addition of XML tags in the file documents.xml. The addition of these additional tags will not cause any real difficulties (it suffices to modify the code C # above and more particularly to XmlDocument object to add the desired tags, the code still remains the same). The problem lies in the fact of what tags add and where to insert.

Let's look at the basic structure of the main Part of a document Open XML:
<? xml version = "1.0" encoding = "utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:background w:color="CEB966"/>
<w:body>
<w:p>
<w:r>
<w:t> Hi! </ w: t>
</ w: r>
</ w: p>
</ w: body>
</ w: document>
The tag document is the root of the document. It specifies the contents of the main Part of a document Open XML. This can only have 2 children elements: body element and the element background.

The background shows the information about the substance of a document WordprocessingML (eg background color).
The body tag lists the contents of the document body. It may contain a number of types of elements tbl (table) and p (paragraph).

VI. Paragraphs and formatting
VI-A. Paragraphs

Subsection (which is defined with the element p) is the most basic unit to store a block content in a document WordprocessingML. A paragraph defines a separate division of content that begins with a new line. A paragraph may contain three types of information: the properties of subsection (optional), the contents of paragraph (typically a tag run), and a set of voluntary revision identifications used to compare the contents of both documents.

We can obviously put several paragraphs in a document. Thus, if we want our text contains two paragraphs, the document.xml file should look like this:
<? xml version = "1.0" encoding = "utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:background w:color="CEB966"/>
<w:body>
<w:p>
<w:r>
<w:t> Paragraph 1 </ w: t>
</ w: r>
</ w: p>
<w:p>
<w:r>
<w:t> Paragraph 2 </ w: t>
</ w: r>
</ w: p>
</ w: body>
</ w: document>
It is possible to specify a set of properties that will apply to the entire paragraph. These properties must be declared in a pPr within the p element.

For example:
The jc can specify the alignment of the text. The value "both" is a justified alignment (there are also "right", "left" and "center").
The pageBreakBefore can insert a page break just before the paragraph concerned.
Thus, a paragraph whose text alignment is justified and which begins on a new page to declare this way:
<? xml version = "1.0" encoding = "utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:background w:color="CEB966"/>
<w:body>
<w:p>
<w:pPr>
<w:jc w:val="both"/>
<w:pageBreakBefore/>
</ w: pPr>
<w:r>
<w:t> Hi! </ w: t>
</ w: r>
</ w: p>
</ w: body>
</ w: document>
The C # code to achieve this is not complicated. It is sufficient simply to effect change our XmlDocument object that we had stated earlier. The rest of the code (creation of the package, relationships, etc..) Remains strictly identical. Here is the code to create two paragraphs and declare properties justified and page break in the second paragraph:

/ / Using the NameSpace WordprocessingML:
WordprocessingML string =
"http://schemas.openxmlformats.org/wordprocessingml/2006/main";

/ / Creation of WordML
XmlDocument xmlStartPart = new XmlDocument ();
XmlElement tagDocument = xmlStartPart.CreateElement ( "w: document",
WordprocessingML);
xmlStartPart.AppendChild (tagDocument);
XmlElement tagBody = xmlStartPart.CreateElement ( "w: body," WordprocessingML);
tagDocument.AppendChild (tagBody);

/ / Declaration of paragraph 1
XmlElement tagParagraph = xmlStartPart.CreateElement ( "w: p", WordprocessingML);
tagBody.AppendChild (tagParagraph);
XmlElement tagRun = xmlStartPart.CreateElement ( "w: r", WordprocessingML);
tagParagraph.AppendChild (tagRun);
XmlElement tagText = xmlStartPart.CreateElement ( "w: t", WordprocessingML);
tagRun.AppendChild (tagText);
/ / Insert Text
XmlNode nodeText = xmlStartPart.CreateNode (XmlNodeType.Text, "w: t", WordprocessingML);
nodeText.Value = "Hi!"
tagText.AppendChild (nodeText);
/ / Declaration of paragraph 2
tagParagraph = xmlStartPart.CreateElement ( "w: p", WordprocessingML);
tagBody.AppendChild (tagParagraph);

/ / Declaration of properties of paragraph
XmlElement tagParagraphProp = xmlStartPart.CreateElement ( "w: pPr" WordprocessingML);
tagParagraph.AppendChild (tagParagraphProp);

/ / property alignment
XmlElement tagAlignement = xmlStartPart.CreateElement ( "w: jc" WordprocessingML);
/ / attribute node w: jc
XmlAttribute attribut1 = xmlStartPart.CreateAttribute ( "w: val" WordprocessingML);
attribut1.InnerText = "both";
tagAlignement.SetAttributeNode (attribut1);
tagParagraphProp.AppendChild (tagAlignement);

/ / property page break
XmlElement tagBreak = xmlStartPart.CreateElement ( "w: pageBreakBefore" WordprocessingML);
tagParagraphProp.AppendChild (tagBreak);

tagRun = xmlStartPart.CreateElement ( "w: r", WordprocessingML);
tagParagraph.AppendChild (tagRun);
tagText = xmlStartPart.CreateElement ( "w: t", WordprocessingML);
tagRun.AppendChild (tagText);
nodeText = xmlStartPart.CreateNode (XmlNodeType.Text, "w: t", WordprocessingML);
nodeText.Value = "Hi!"
tagText.AppendChild (nodeText);
/ / rest of the code …

VI-B. The runs
A run (tag r) is a region of texts with a common set of properties. An element r allows a combination of styles and formatting properties, applies equally to all parts of the run. The text in a document WordprocessingML must be contained in one or more runs. A paragraph is a collection of one or more runs. A run must be contained in one paragraph. The text inside a run is written in a tag t.

Just as a paragraph may have properties, a run can be too. All elements inside an element r have their properties inspected by an element rPr optional and which must be the first child element r. In other words, rPr element is a container for a set of elements of ownership that are applied to the rest of the children of the element r. The elements of property inside the container element rPr can control whether the text in the following elements t is bold, underline or italics, for example. Some examples of properties: bold, border, character style, color, font, font size, italics, direction of the text or underscore.

The content of the most common run is the t (but there are others!), Which is the container for the text which comprises the content of the document. An element t may contain an arbitrary amount of text, even up to be able to contain the entire contents of the document. An element t must be included in an element r. An element r may contain multiple elements t, interspersed with other elements.

Thus, the following sentence: "Open XML. NET is easy. "Which contains text in red, bold and highlighted will be broken down as follows:
<w:r>
<w:rPr>
<w:color w:val="FF0000"/>
</ w: rPr>
<w:t> Open XML </ w: t>
</ w: r>
<w:r>
<w:t xml:space="preserve"> with </ w: t>
</ w: r>
<w:r>
<w:rPr>
<w:b/>
</ w: rPr>
<w:t>. NET </ w: t>
</ w: r>
<w:r>
<w:t xml:space="preserve"> is </ w: t>
</ w: r>
<w:r>
<w:rPr>
<w:highlight w:val="yellow"/>
</ w: rPr>
<w:t> easy </ w: t>
</ w: r>
Note the use of the property xml: space = "preserve" to keep the spaces found in the text inside the tag t.
Here are some code to decorate it. Please note here that I do that code for the creation of the first run. Indeed, you simply repeat the operation for the other, you know to do now is the mere manipulation of XML.

/ / Using the NameSpace WordprocessingML:
WordprocessingML string = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";

/ / Creation of WordML
XmlDocument xmlStartPart = new XmlDocument ();
XmlElement tagDocument = xmlStartPart.CreateElement ( "w: document",
WordprocessingML);
xmlStartPart.AppendChild (tagDocument);
XmlElement tagBody = xmlStartPart.CreateElement ( "w: body," WordprocessingML);
tagDocument.AppendChild (tagBody);

/ / Declaration of paragraph
XmlElement tagParagraph = xmlStartPart.CreateElement ( "w: p", WordprocessingML);
tagBody.AppendChild (tagParagraph);

/ / creation of the first run
XmlElement tagRun = xmlStartPart.CreateElement ( "w: r", WordprocessingML);
tagParagraph.AppendChild (tagRun);

/ / Element properties of the first run
XmlElement tagRunProp = xmlStartPart.CreateElement ( "w: rPr" WordprocessingML);
tagRun.AppendChild (tagRunProp);
/ / property color
XmlElement tagCouleur = xmlStartPart.CreateElement ( "w: color," WordprocessingML);
/ / attribute of the element w: color
XmlAttribute valeurCouleur = xmlStartPart.CreateAttribute ( "w: val" WordprocessingML);
valeurCouleur.InnerText = "FF0000";
tagCouleur.SetAttributeNode (valeurCouleur);
tagRunProp.AppendChild (tagCouleur);

/ / creation of element t
XmlElement tagText = xmlStartPart.CreateElement ( "w: t", WordprocessingML);
tagRun.AppendChild (tagText);
tagText.InnerText = "Open XML";

/ / rest of the code …

VII. The styles
After seeing how to define a particular paragraph and properties formatting can be applied, perhaps you ask yourself this question: Is it possible, like CSS style sheets to Web programming, to separate the content of its presentation? Asked relevant that can be happily answered in the affirmative through the use of styles.

In a document WordprocessingML, styles are predefined sets of properties that can be applied to text in the document. This allows the formatting properties to be stored and managed independently of the content, enabling the presentation of the contents of the document to be changed in one place (rather than changing the properties of each paragraphs one to one).

VII-A. The Part styles

Like the contents of a document WordprocessingML which is stored in the main Part (document.xml), styles will also be stored in a Part: file styles.xml located at the same level as the document.xml file. As for the establishment of the Main Part, the establishment of the Part containing styles require define its type (application / vnd.openxmlformats-officedocument.wordprocessingml.styles + xml) in the file [Content_Types]. Xml and create a relationship (http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles) for the link to the package.

Here is the file structure styles.xml:
<? xml version = "1.0" encoding = "UTF-8" standalone = "yes"?>
<w: styles xmlns: r = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns: w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:docDefaults> </ w: docDefaults>
<w:latentStyles> </ w: latentStyles>
<w:style> </ w: style>
<w:style> </ w: style>
</ w: styles>
It consists of up to a docDefauts (optional), plus an element in latentStyles (optional) and as many elements as desired style.

VII-B. Definition of a style
A style is defined using a style. The definition of a style can be cut into three segments:
* A set of properties common to all styles
* The type of style
* The specific properties style (related to the type of style)
The properties common to all styles are a set of properties that can be used regardless of the type of style, for example, the name of style, style identifier, if the style is hidden, if the style is locked, and so on.

The type of style can define what type of block will apply the style. WordprocessingML contains six types of style:
* Styles apply to a paragraph
* The styles applied to a run
* The related styles (paragraph + text)
* Styles apply to a table
* The styles applied to a list
* The default properties for paragraphs and text

Here is the definition of a style (without specific properties style):
<w:style w:type="paragraph" w:default="1" w:styleId="MonStyle1">
<w:name w:val="mon style 1"/>
<w:basedOn w:val="MonStyleDeBase"/>
<w:next w:val="MonStyle2"/>

</ w: style>

Here is the statement of a few properties common to all styles such as ID ( "MonStyle1"), the name ( "my style 1") or the basic style (inheritance) from which this style is built ( "MonStyleDeBase"). The type of style is defined by the type attribute, here it is a style applied to a paragraph. Note the default attribute that allows you to specify that this style is the style default applying to all paragraphs that do not refer to a particular style.

Now let us see the properties specific style. They of course depend on the type of style said. We n'etudierons here that the styles apply to paragraphs and the text.

 

VII-C. Styles applying to a paragraph
These types of style apply to a paragraph in its entirety. This implies that the style can define both the text properties (properties that apply to text in the document) and properties of subsection (properties that apply to positioning and appearance of the paragraph). The styles that apply to a paragraph (p element) can not be referenced by elements run in a document. These styles should be referenced by the element pStyle in pPr element of a paragraph.

Consideront style:
<w:style w:type="paragraph" w:styleId="MonStyle1">
<w:name w:val="mon style 1"/>
<w:pPr>
<w:spacing w:line="480" w:lineRule="auto"/>
<w:ind w:firstLine="1440"/>
</ w: pPr>
<w:rPr>
<w:rFonts w:ascii="Algerian" w:hAnsi="Algerian"/>
<w:color w:val="ED1C24"/>
<w:sz w:val="40"/>
</ w: rPr>
</ w: style>
This style defines properties that will apply in paragraph through the element pPr and properties that will apply to run the element contained in this paragraph through the element rPr.

This style will be referenced by one paragraph:
<w:p>
<w:pPr>
<w:pStyle w:val="MonStyle1"/>
</ w: pPr>
<w:r>
<w:t> Open XML. Net is easy </ w: t>
</ w: r>
</ w: p> p>

The style is referenced through the pStyle element within the element pPr paragraph which, remember, defines the properties that apply to a paragraph
Here is the result:


VII-D. Styles applied to a Run

These styles can be applied only runs inside a document, not a paragraph. This means that they can not define properties that apply to text within a paragraph. These styles are referenced by the element rStyle inside the element of ownership run (rPr).

Consider the following style (type character):
<w:style w:type="character" w:styleId="monStyledeRun">
<w:name w:val="Style for run"/>
<w:priority w:val="99"/>
<w:rPr>
<w:rFonts w:ascii="Courier New" w:hAnsi="Courier New"/>
<w:color w:val="FFF200"/>
<w:u w:val="single"/>
</ w: rPr>
</ w: style>
You will note the use of the element rPr to define properties that will apply.

This style will be referenced by one paragraph:
<w:p>
<w:r>
<w:rPr>
<w:rStyle w:val="monStyledeRun"/>
</ w: rPr>
<w:t> A style is applied to this text </ w: t>
</ w: r>
</ w: p>
The style "monStyledeRun" is referenced through the rStyle element within the element properties rPp the run.

VII-E. The default properties
Although we can not really talk about a style in the strict sense (these properties can not be directly applied to text), they help define the properties of formatting to be applied by default to all paragraphs of the document and runs . For that, one does not use the tag style but a new element: docDefaults. The latter element may contain two children: pPrDefault which defines the default properties for paragraphs and rPrDefault which defines the default properties for runs.

Here is an example of definition for the element docDefaults:
<w:docDefaults>
<w:pPrDefault>
<w:pPr>
<w:jc w:val="center"/>
</ w: pPr>
</ w: pPrDefault>
<w:rPrDefault>
<w:rPr>
<w:b/>
</ w: rPr>
</ w: rPrDefault>
</ w: docDefaults>
More explanation would be superfluous, simply defining element pPr in pPrDefault and rPr element in rPrDefault then declare the desired properties.

VII-F. Order of application styles
With the various types of existing styles, it is possible to apply several different styles to the same content. Consider the following excerpt:
<w:p>
<w:pPr>
<w:pStyle w:val="MonStyle1"/>
</ w: pPr>
<w:r>
<w:rPr>
<w:rStyle w:val="monStyledeRun"/>
<w:color w:val="FF0000"/>
</ w: rPr>
<w:t> A style is applied to this text </ w: t>
</ w: r>
</ w: p>
In this example, a first style "MonStyle1" is applied to the paragraph. A second style "monStyleDeRun" is then applied to a run in the same paragraph. Finally, a color unreported in a style is applied to the text. Suppose that "MonStyle1" and "monStyleDeRun" define each a different color for the text: What color is finally the text? To solve this problem, different styles are applied in a precise order and summarized in the following table:

This table can be described as follows:
* First, the default styles are applied to all paragraphs of the document and runs.
* Second, the specific styles for tables are applied to all the tables in the document.
* Second, apply styles defined for enumerations
* Then, applying styles in paragraphs (and runs contained in these paragraphs) are called.
* Then, runs the specific styles are applied.
* And finally, applying the formatting properties direct (not contained in styles).
Thus, if one takes our previous example, is finally defined color directly (FF0000), which will have the final word.

VII-G. A little code
After seeing the bases on styles, put it into effect. We will create an Open XML document containing a paragraph (with text) which we apply a style. This will be type-paragraph ", ie defining properties applying to a paragraph (in this paragraph will focus) but also the text contained in this paragraph (by color).

Here is the XML code of this style (contained in the file styles.xml):
<? xml version = "1.0" encoding = "utf-8"?>
<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:style w:type="paragraph" w:styleId="MonStyle1">
<w:name w:val="MonStyle1" />
<w:pPr>
<w:jc w:val="center" />
</ w: pPr>
<w:rPr>
<w:color w:val="FF0000" />
</ w: rPr>
</ w: style>
</ w: styles>

To achieve this, nothing very complicated. As always, it is necessary from a XmlDocument and build its tree by adding nodes. Here is the code:
/ / Creating Style
XmlDocument xmlStylePart = new XmlDocument ();
XmlElement tagStyles = xmlStylePart.CreateElement ( "w: styles," WordprocessingML);
xmlStylePart.AppendChild (tagStyles);
XmlElement tagStyle = xmlStylePart.CreateElement ( "w: style," WordprocessingML);
tagStyles.AppendChild (tagStyle);

/**** attributes style ****/
/ / type style
XmlAttribute attributType = xmlStylePart.CreateAttribute ( "w: type", WordprocessingML);
attributType.InnerText = "paragraph";
tagStyle.SetAttributeNode (attributType);
/ / style
XmlAttribute attributId = xmlStylePart.CreateAttribute ( "w: styleId" WordprocessingML);
attributId.InnerText = "MonStyle1";
tagStyle.SetAttributeNode (attributId);

/ / node Name
XmlElement tagName xmlStylePart.CreateElement = ( "w: name," WordprocessingML);
tagStyle.AppendChild (tagName);
XmlAttribute attributName = xmlStylePart.CreateAttribute ( "w: val" WordprocessingML);
attributName.InnerText = "MonStyle1";
tagName.SetAttributeNode (attributName);

/ / node pPr
XmlElement tagpPr = xmlStylePart.CreateElement ( "w: pPr" WordprocessingML);
tagStyle.AppendChild (tagpPr);
/ / property alignment
XmlElement tagAlignement = xmlStylePart.CreateElement ( "w: jc" WordprocessingML);
/ / attribute node w: jc
XmlAttribute attributJc = xmlStylePart.CreateAttribute ( "w: val" WordprocessingML);
attributJc.InnerText = "center";
tagAlignement.SetAttributeNode (attributJc);
tagpPr.AppendChild (tagAlignement);

/ / node rPr
XmlElement tagrPr = xmlStylePart.CreateElement ( "w: rPr" WordprocessingML);
tagStyle.AppendChild (tagrPr);
/ / property color
XmlElement tagCouleur = xmlStylePart.CreateElement ( "w: color," WordprocessingML);
/ / attribute of the element w: color
XmlAttribute valeurCouleur = xmlStylePart.CreateAttribute ( "w: val" WordprocessingML);
valeurCouleur.InnerText = "FF0000";
tagCouleur.SetAttributeNode (valeurCouleur);
tagrPr.AppendChild (tagCouleur);

Turning to file document.xml here is the content …
<? xml version = "1.0 'encoding =" utf-8 "?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="MonStyle1" />
</ w: pPr>
<w:r>
<w:t> hello </ w: t>
</ w: r>
</ w: p>
<w:p />
</ w: body>
</ w: document>
… and the code to build:

/ / Creation of WordML
XmlDocument xmlStartPart = new XmlDocument ();
XmlElement tagDocument = xmlStartPart.CreateElement ( "w: document", WordprocessingML);
xmlStartPart.AppendChild (tagDocument);
XmlElement tagBody = xmlStartPart.CreateElement ( "w: body," WordprocessingML);
tagDocument.AppendChild (tagBody);
XmlElement tagParagraph = xmlStartPart.CreateElement ( "w: p", WordprocessingML);
tagBody.AppendChild (tagParagraph);

/ / properties paragraph
XmlElement tagParagraphProp = xmlStartPart.CreateElement ( "w: pPr" WordprocessingML);
tagParagraph.AppendChild (tagParagraphProp);

/ / style of paragraph
XmlElement tagpStyle = xmlStartPart.CreateElement ( "w: pStyle" WordprocessingML);
/ / attribute of the element w: pStyle
XmlAttribute valeurStyle = xmlStartPart.CreateAttribute ( "w: val" WordprocessingML);
valeurStyle.InnerText = "MonStyle1";
tagStyle.SetAttributeNode (valeurStyle);
tagParagraphProp.AppendChild (tagpStyle);

/ / creation of the Run
XmlElement tagRun = xmlStartPart.CreateElement ( "w: r", WordprocessingML);
tagParagraph.AppendChild (tagRun);

/ / creation of element t
XmlElement tagText = xmlStartPart.CreateElement ( "w: t", WordprocessingML);
tagRun.AppendChild (tagText);
tagText.InnerText = "hello";
Nothing exceptional compared to what has already been seen. The only novelty lies in adding the element pStyle.

It then creates a new package …
/ / Create a new file
Package pkgOutputDoc = null;
pkgOutputDoc = Package.Open ( "monFichier.docx", FileMode.Create, FileAccess.ReadWrite);

… then another and share a relationship to link the package:
/ / Create the main part
Uri uri = new Uri ( "document.xml" UriKind.Relative);
PackagePart partDocumentXML = pkgOutputDoc.CreatePart (uri,
"application / vnd.openxmlformats-officedocument.wordprocessingml.document.main + xml");
StreamWriter streamStartPart =
new StreamWriter (partDocumentXML.GetStream (FileMode.Create, FileAccess.Write));
xmlStartPart.Save (streamStartPart);
streamStartPart.Close ();

/ / Create the RelationShip
pkgOutputDoc.CreateRelationship (uri, TargetMode.Internal,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
"rId1");
All this is the code we have already seen and which allows us to create the main Part of the document.

Now we still need to look after our file styles. Like the document.xml file, the file style will be a Part of the document WordprocessingML. The code to create it will be very similar.

We first create a new Part (PackagePart) specifying its location (Uri) and type of content: "application / vnd.openxmlformats-officedocument.wordprocessingml.styles + xml" which is the type specified for the Part styles . Then we serialise all in the package:

/ / Save style generated in the file in the package styles.xml
uri = new Uri ( "styles.xml" UriKind.Relative);
PackagePart partStylesXML = pkgOutputDoc.CreatePart (uri,
"application / vnd.openxmlformats-officedocument.wordprocessingml.styles + xml");
streamStartPart =
new StreamWriter (partStylesXML.GetStream (FileMode.Create, FileAccess.Write));
xmlStylePart.Save (streamStartPart);
streamStartPart.Close ();

We created the Part and declared its type, we have no choice but now more than link it to creating a relationship. Attention is a little different here than when creating the relationship for Part main document. Indeed, with the document.xml file it was necessary to create a relationship between the package and this file to specify which was the main share when you read the package. But here we want to specify that there is a relationship between Part styles and Part main document.

To create the relationship we will therefore not use the Package object but the object partDocumentXML:
/ / Create the RelationShip
partDocumentXML.CreateRelationship (uri, TargetMode.Internal,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
"rId1");

The type of relationship is defined by "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" that characterizes a relationship of type styles.

This would effectively create a new directory _rels in the directory with word inside a file containing document.xml.rels this relationship. Here is the content:
<? xml version = "1.0" encoding = "utf-8"?>
<Relationships Xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship
Type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
Target = "/ word / styles.xml" Id = "rId1" />
</ Relationships>

Finally, all that remains is to close the package:
pkgOutputDoc.Flush ();
pkgOutputDoc.Close ();

VIII. The files properties
These are stored in the directory docProps located at the root of the package.
Core.xml The file contains a set of properties common to all files Open XML. These properties include the creator's name, date of creation, title and description. So whether you treat a document docx, xlsx or pptx, these properties will always be placed at that location.

The file contains app.xml specific properties for each type of packages Open XML. For example, a package WordprocessingML, these properties include the number of characters, words, lines, paragraphs and pages in the document. For a package type Spreadsheet (xlsx), these properties include the titles of leaves. For a package type Presentation (pptx), these properties include the presentation format, the number of slides, the number of notes.
We will only interest us in this party to file core.xml.

Here is an example of what could be the contents of this file:
<? xml version = "1.0" encoding = "UTF-8" standalone = "yes"?>
<cp: coreProperties xmlns: cp = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
xmlns: dc = "http://purl.org/dc/elements/1.1/" xmlns: dcterms = "http://purl.org/dc/terms/"
xmlns: dcmitype = "http://purl.org/dc/dcmitype/" xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance">
<dc:title> OpenXML and dotnet </ dc: title>
<dc:subject> create a Word 2007 file </ dc: subject>
<dc:creator> Moi </ dc: creator>
<dc:description> comments </ dc: description>
<dcterms:created xsi:type="dcterms:W3CDTF"> 2006-12-26T10: 16:00 Z </ dcterms: created>
<dcterms:modified xsi:type="dcterms:W3CDTF"> 2006-12-26T10: 16:00 Z </ dcterms: modified>
<cp:category> Article dotnet </ cp: category>
<cp:contentStatus> Ongoing </ cp: contentStatus>
<cp:keywords> dotnet OpenXML </ cp: keywords>
<cp:revision> 2 </ cp: revision>
</ cp: coreProperties>

Note the use of different namespaces.
The property can not be repeated. A double corromprait element in the package.
The elements of property are not mandatory and can be omitted if you do not want to fill the field (the presence of file core.xml indeed it is not even mandatory in the package).

Let us first the corresponding XmlDocument (we limit ourselves by creating the elements title, creator, and created category):
string cp = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
string dc = "http://purl.org/dc/elements/1.1/";
dcterms string = "http://purl.org/dc/terms/";
string xsi = "http://www.w3.org/2001/XMLSchema-instance";
XmlDocument xmlCorePart = new XmlDocument ();
XmlElement tagCore = xmlCorePart.CreateElement ( "cp: coreProperties", "PC");
xmlCorePart.AppendChild (tagCore);
XmlElement tagTitle = xmlCorePart.CreateElement ( "dc: title", "dc");
tagTitle.InnerText = "title";
tagCore.AppendChild (tagTitle);
XmlElement tagCreator = xmlCorePart.CreateElement ( "dc: creator", "dc");
tagCreator.InnerText = "Creator";
tagCore.AppendChild (tagCreator);
XmlElement tagCat = xmlCorePart.CreateElement ( "cp: category", "PC");
tagCat.InnerText = "Category";
tagCore.AppendChild (tagCat);
XmlElement tagCreated = xmlCorePart.CreateElement ( "dcterms: created," dcterms);

/ / formatting of the date
DateTimeFormatInfo myDTFI = new CultureInfo ( "en-US", false). DateTimeFormat;
tagCreated.InnerText = DateTime.Now.ToString (myDTFI.SortableDateTimePattern);
tagCore.AppendChild (tagCreated);
/ / attribute
XmlAttribute attributType = xmlCorePart.CreateAttribute ( "xsi: type", xsi);
attributType.InnerText = "dcterms: W3CDTF";
tagCreated.SetAttributeNode (attributType);

The only small problems here are limited to the use of different namespaces and a special encoding for the date (not to forget "using System.Globalization" to use DateTimeFormatInfo).

Let me now turn to writing file core.xml. It will be stored at the site "/ docProps / core.xml" and will content type "application / vnd.openxmlformats-package.core-properties + xml". It will then do not forget, as always, to create a relationship of "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" between this Part and the package. Attention by the identifier of this relationship. Indeed, let us not forget that we already have a relationship between the document.xml file and the package (identifier rId1). The unique identifier to be, we will here "rId2."

Here is the relevant code:
/ / Save the core generated in the file in the package core.xml
uri = new Uri ( "/ docProps / core.xml" UriKind.Relative);
PackagePart partCoreXML = pkgOutputDoc.CreatePart (uri,
"application / vnd.openxmlformats-package.core-properties + xml");
streamStartPart =
new StreamWriter (partCoreXML.GetStream (FileMode.Create, FileAccess.Write));
xmlCorePart.Save (streamStartPart);
streamStartPart.Close ();
/ / Create the RelationShip
pkgOutputDoc.CreateRelationship (uri, TargetMode.Internal,
"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-
properties "," rId2 ");
Finally, here is the complete list of properties available:

Properties  Descriptions Uses
 title Title of the document. <dc:title> OpenXML and dotnet </ dc: title>
subject Subject of the document. <dc:subject> purpose of the document </ dc: subject>
Creator name of the creator. <dc:creator> Moi </ dc: creator>
description Descriptions of the document. <dc:description> comments </ dc: description>
identify   <dc:identifier> id </ dc: identifier>
Language language of the document. <dc:language> com </ dc: language>
category category of document.
Ex: letter, report, etc..
<cp:category> Article </ cp: category>
contentStatus Statute of the document.
Ex: ongoing, final, and so on.
<cp:contentStatus> Ongoing </ cp: contentStatus>
contentType  type of content. <cp:contentType> dotnet </ cp: contentType>
Keywords  keywords for indexing. <cp:keywords> dotnet OpenXML </ cp: keywords>
revision  number revision. <cp:revision> 2 </ cp: revision>
lastModifiedBy  name the last person who changed the document. <cp:lastModifiedBy> Moi </ cp: lastModifiedBy>
 Version Version of the document. <cp:version> 1.0 </ cp: version>
created date of creation of the document. <dcterms:created xsi:type="dcterms:W3CDTF">
2006-12-26T10: 16:00 Z </ dcterms: created>
modified date of the last amendment. <dcterms:modified xsi:type="dcterms:W3CDTF">
2006-12-26T10: 16:00 Z </ dcterms: modified>


IX. Add an image to document

IX-A. DrawingML
The namespace DrawingML defines all the elements for building graphical objects (images, charts, graphs, forms, etc.).. This namespace is not specific to documents WordprocessingML but can also be used in documents SpreadsheetML or PresentationML.

In a document WordprocessingML, it is possible to include graphic objects DrawingML using the element drawing within a run. When these objects are present in a document WordprocessingML, it is necessary to include information that indicates how objects will be placed in relation to the document. The drawing has this capacity, indicating the information necessary to embed and display objects DrawingML in a document WordprocessingML.

Here is an example of what could give the insertion of an image in a document WordprocessingML (note the different namespaces used):
<w:drawing>
<wp:inline>
<wp:extent cx="3000000" cy="3000000" />
<wp:docPr name="monImage.png" id="1" />
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="2" name=" monImage.png" />
<pic:cNvPicPr />
</ pic: nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId2" />
<a:stretch>
<a:fillRect />
</ a: stretch>
</ pic: blipFill>
<pic:spPr>
<a:xfrm>
<a:off x="0" y="0" />
<a:ext cx="3000000" cy="3000000" />
</ a: xfrm>
<a:prstGeom prst="rect" />
</ pic: spPr>
</ pic: pic>
</ a: graphicData>
</ a: graphic>
</ wp: inline>
</ w: drawing>
We will give some explanations on the various elements used.

The drawing may contain an element or element inline anchor each with different properties. These children can define how the image will be prepared over the text (aligned with the text or anchored).

We have chosen a type inline. The inline contains a number of elements which children docPr (mandatory), graphic (mandatory) and extent (optional).
The docPr allows to specify two other properties required: name (specifies a name for the object DrawingML) and id (specifies a unique identifier for the object DrawingML).
The extent to specify the place that will take the subject DrawingML in the document. It has two attributes cx and cy that define respectively the height and width.

The unit of measurement is the EMU (English Metric Unit). Possible values range from 0 to 27273042316900. There are 360000 EMUs by centimetre, 914400 EMUs per inch and 12700 EMUs per item.

The graphic shows the existence of an object graph. The specifications for this object graph are referenced in the child element graphicData. This defines what type of content of the object graph. This information is shown using the uri. The rest of the content of the element graphicData depends on the value of this attribute. Some of possible values for this attribute:
* Http://schemas.openxmlformats.org/drawingml/2006/chart
* Http://schemas.openxmlformats.org/drawingml/2006/compatibility
* Http://schemas.openxmlformats.org/drawingml/2006/lockedCanvas
* Http://schemas.openxmlformats.org/drawingml/2006/picture
* Http://schemas.openxmlformats.org/drawingml/2006/table
* Http://schemas.openxmlformats.org/drawingml/2006/ole
Here we use an object in the picture graphical object. An object picture is defined by the element peak. It may contain a number of nodes including three children are required: nvPicPr, blipFill and spPr:

The nvPicPr is a container for non-visual properties associated with an image. It contains two knots mandatory cNvPicPr and cNvPr.
The blipFill defines how the subject will be filled picture. The crux blip refers to the image file to be used. This file is stored in the package is used embed attribute that specifies the ID of an element in the relationship file document.xml.rels. The crux stretch indicates that the image will be stretched to fill the available space.

The spPr can set a number of effects that change the appearance of the image. These include for example the effects of rotation, reflection, shadow, and so on. The crux prstGeom child can use a geometric shape preset. Here we use a rectangular shape but we could have used a heart, a trapeze, a round or any other form available (listed in the specifications of the format in Chapter 5.1.12.56 ST_ShapeType).

IX-B. The code
Let's now look at the code needed to achieve this.
We will first create a XmlElement containing the XML structure defined above (element drawing). The only difficulty for the moment can be summed up in the length of the code needed…. Attention, however, the different namespaces used.
WordprocessingML string = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
RelationShips string = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
Drawing string = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
DrawingML string = "http://schemas.openxmlformats.org/drawingml/2006/main";
Pic string = "http://schemas.openxmlformats.org/drawingml/2006/picture";

/ / Creation of WordML
XmlDocument xmlStartPart = new XmlDocument ();

XmlElement tagDrawing = xmlStartPart.CreateElement ( "w: drawing," WordprocessingML);
XmlElement tagInline = xmlStartPart.CreateElement ( "wp: inline" Drawing);
tagDrawing.AppendChild (tagInline);

/ / Element extent
XmlElement tagExtent = xmlStartPart.CreateElement ( "wp: extent," Drawing);
tagInline.AppendChild (tagExtent);
/ / attributes extent
XmlAttribute attributcx = xmlStartPart.CreateAttribute (cx);
attributcx.InnerText = "1300000";
tagExtent.SetAttributeNode (attributcx);
XmlAttribute attributcy = xmlStartPart.CreateAttribute ( "cy");
attributcy.InnerText = "1300000";
tagExtent.SetAttributeNode (attributcy);

/ / Element docPr
XmlElement tagdocPr = xmlStartPart.CreateElement ( "wp: docPr" Drawing);
tagInline.AppendChild (tagdocPr);
/ / attributes docPr
XmlAttribute attributname = xmlStartPart.CreateAttribute ( "name");
attributname.InnerText = "openxml.png";
tagdocPr.SetAttributeNode (attributname);
XmlAttribute attributid = xmlStartPart.CreateAttribute (id);
attributid.InnerText = "1";
tagdocPr.SetAttributeNode (attributid);

/ / Element graphic
XmlElement taggraphic = xmlStartPart.CreateElement ( "a: graphic," DrawingML);
tagInline.AppendChild (taggraphic);
/ / Element graphicData
XmlElement taggraphicData = xmlStartPart.CreateElement ( "a: graphicData" DrawingML);
taggraphic.AppendChild (taggraphicData);
/ / attributes graphicData
XmlAttribute attributuri = xmlStartPart.CreateAttribute ( "uri");
attributuri.InnerText = "http://schemas.openxmlformats.org/drawingml/2006/picture";
taggraphicData.SetAttributeNode (attributuri);

/ / Element pic
XmlElement tagpic = xmlStartPart.CreateElement ( "pic: peak, Pic);
taggraphicData.AppendChild (tagpic);

/ / Element nvPicPr
XmlElement tagnvPicPr = xmlStartPart.CreateElement ( "pic: nvPicPr", Pic);
tagpic.AppendChild (tagnvPicPr);
/ / Element cNvPr
XmlElement tagcNvPr = xmlStartPart.CreateElement ( "pic: cNvPr", Pic);
tagnvPicPr.AppendChild (tagcNvPr);
/ / attributes cNvPr
XmlAttribute attributnamecNvPr = xmlStartPart.CreateAttribute ( "name");
attributnamecNvPr.InnerText = "openxml.jpg";
tagcNvPr.SetAttributeNode (attributnamecNvPr);
XmlAttribute attributidcNvPr = xmlStartPart.CreateAttribute (id);
attributidcNvPr.InnerText = "2";
tagcNvPr.SetAttributeNode (attributidcNvPr);
/ / Element cNvPicPr
XmlElement tagcNvPicPr = xmlStartPart.CreateElement ( "pic: cNvPicPr", Pic);
tagnvPicPr.AppendChild (tagcNvPicPr);

/ / Element blipFill
XmlElement tagblipFill = xmlStartPart.CreateElement ( "pic: blipFill", Pic);
tagpic.AppendChild (tagblipFill);
/ / Element blip
XmlElement tagblip = xmlStartPart.CreateElement ( "a: blip," DrawingML);
tagblipFill.AppendChild (tagblip);
/ / attribute blip
XmlAttribute attributembed = xmlStartPart.CreateAttribute ( "r: embed," RelationShips);
attributembed.InnerText = "rId1";
tagblip.SetAttributeNode (attributembed);
/ / Element stretch
XmlElement tagstretch = xmlStartPart.CreateElement ( "a: stretch," DrawingML);
tagblipFill.AppendChild (tagstretch);
/ / Element fillRect
XmlElement tagfillRect = xmlStartPart.CreateElement ( "a: fillRect" DrawingML);
tagstretch.AppendChild (tagfillRect);

/ / Element spPr
XmlElement tagspPr = xmlStartPart.CreateElement ( "pic: spPr", Pic);
tagpic.AppendChild (tagspPr);
/ / Element xfrm
XmlElement tagxfrm = xmlStartPart.CreateElement ( "a: xfrm" DrawingML);
tagspPr.AppendChild (tagxfrm);

/ / Element off
XmlElement tagoff = xmlStartPart.CreateElement ( "a: off," DrawingML);
tagxfrm.AppendChild (tagoff);
/ / attributes off
XmlAttribute attributx = xmlStartPart.CreateAttribute ( "x");
attributx.InnerText = "0";
tagoff.SetAttributeNode (attributx);
XmlAttribute attributy = xmlStartPart.CreateAttribute ( "y");
attributy.InnerText = "0";
tagoff.SetAttributeNode (attributy);
/ / Element ext
XmlElement tagext = xmlStartPart.CreateElement ( "a: ext" DrawingML);
tagxfrm.AppendChild (tagext);
/ / attributes ext
XmlAttribute attributcxext = xmlStartPart.CreateAttribute (cx);
attributcxext.InnerText = "1300000";
tagext.SetAttributeNode (attributcxext);
XmlAttribute attributcyext = xmlStartPart.CreateAttribute ( "cy");
attributcyext.InnerText = "1300000";
tagext.SetAttributeNode (attributcyext);

/ / Element prstGeom
XmlElement tagprstGeom = xmlStartPart.CreateElement ( "a: prstGeom" DrawingML);
tagspPr.AppendChild (tagprstGeom);
/ / attributes prstGeom
XmlAttribute attributprst = xmlStartPart.CreateAttribute ( "prst");
attributprst.InnerText = "rect";
tagprstGeom.SetAttributeNode (attributprst);

Once the tree is created, we must integrate in a run in an XmlDocument. It created a XmlDocument containing two paragraphs: one for text and one for the image. The inclusion of previously established XmlElement is the last line:
XmlElement tagDocument = xmlStartPart.CreateElement ( "w: document", WordprocessingML);
xmlStartPart.AppendChild (tagDocument);
XmlElement tagBody = xmlStartPart.CreateElement ( "w: body," WordprocessingML);
tagDocument.AppendChild (tagBody);
XmlElement tagParagraph = xmlStartPart.CreateElement ( "w: p", WordprocessingML);
tagBody.AppendChild (tagParagraph);
/ / creation of the first run
XmlElement tagRun = xmlStartPart.CreateElement ( "w: r", WordprocessingML);
tagParagraph.AppendChild (tagRun);
/ / some text
XmlElement tagText = xmlStartPart.CreateElement ( "w: t", WordprocessingML);
tagRun.AppendChild (tagText);
tagText.InnerText = "Here is a picture:";
tagRun.AppendChild (tagText);

/ / New paragraph with an image
XmlElement tagParagraph2 = xmlStartPart.CreateElement ( "w: p", WordprocessingML);
tagBody.AppendChild (tagParagraph2);
/ / creation of the 2nd run
XmlElement tagRun2 = xmlStartPart.CreateElement ( "w: r", WordprocessingML);
tagParagraph2.AppendChild (tagRun2);

/ / insertion of the image in the run
tagRun2.AppendChild (tagDrawing);

Now we must save this XmlDocument in a new package as it now has the habit of doing so….

/ / Creating a new package
Package pkgOutputDoc = null;
pkgOutputDoc = Package.Open ( "monFichier.docx", FileMode.Create, FileAccess.ReadWrite);
/ / Save the XmlDocument in the document.xml file in the package
Uri uri = new Uri ( "/ word / document.xml" UriKind.Relative);
PackagePart partDocumentXML = pkgOutputDoc.CreatePart (uri,
"application / vnd.openxmlformats-officedocument.wordprocessingml.document.main + xml");
StreamWriter streamStartPart =
new StreamWriter (partDocumentXML.GetStream (FileMode.Create, FileAccess.Write));
xmlStartPart.Save (streamStartPart);
streamStartPart.Close ();

/ / Create the RelationShip
pkgOutputDoc.CreateRelationship (uri, TargetMode.Internal,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"
"rId1");
All we have to insert the image (openxml.png) in the package. It will be stored in a directory media inside the directory word. Like the document.xml file or styles.xml, an image is a Part. We will therefore have to define the type of content and a relationship linking it to another Part (here, the document.xml file).

Let's start by declaring a share as we have always done. It creates an object PackagePart and he goes to setting the location of the file in the package and the type of content (here "image / png). It then records the image in the package using a FileStream.
/ / save the image in the package
uri = new Uri ( "/ word / media / openxml.png" UriKind.Relative);
PackagePart partImage = pkgOutputDoc.CreatePart (uri, "image / png");
using (Stream targetStream = partImage.GetStream ())
(
using (FileStream sourceStream = new FileStream ( "openxml.png"
FileMode.Open, FileAccess.Read))
(
byte [] buffer = new byte [1024];
int nrBytesWritten = sourceStream.Read (buffer, 0, 1024);
while (nrBytesWritten> 0)
(
targetStream.Write (buffer, 0, nrBytesWritten);
nrBytesWritten = sourceStream.Read (buffer, 0, 1024);
)
)
)
Finally, we must create the relationship. As with the roster of styles, is not binding on the image package but the main share (the document.xml file). It uses the object partDocumentXML to create this relationship, not pkgOutputDoc. It is in the file directory document.xml.rels word _rels it is stored.

/ / Create the RelationShip between image and the main part
partDocumentXML.CreateRelationship (uri, TargetMode.Internal,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
"rId1");

http://schemas.openxmlformats.org/officeDocument/2006/relationships/image is the type of relationship that is the type of relationship to the images. We specify here an identifier rId1 relationship because this is the only relationship that we declare in the file document.xml.rels. If there are already other relations (for styles for example), it will be worth checking that the ID is unique.

Finally, it closes the package:
/ / Closure package
pkgOutputDoc.Flush ();
pkgOutputDoc.Close ();
And the result:

X. To go further
Microsoft has released a package of snippets used with Visual Studio 2005 for the document format Open XML (Word, Excel and PowerPoint).
And it is here: snipets.

Although the creation of files Open XML is relatively simple, it nonetheless still need to enter a sizeable number of lines of code (and in particular for the creation of the structure XML). That is why a number of libraries to simplify the code needed began to emerge across the Web.

XI. Conclusion
We have seen through this article the basis for the generation of documents in Word format Open XML using bricks Framework 3.0 around the assembly System.IO.Package.

The generation of Office documents (Word in this example) can now be executed without qu'Office being installed and without having used the Primary Interop Assemblies of Office as was the case with the old formats.