Introduction
OpenXML is the de facto means for working with Office Documents, and it provides a real power-house of functionality. But getting going is often difficult as there are hurdles
like terminology, trying to understand the nature of the beast, and just finding some basic tutorials that are less technical and more practical.
This is the very reason for this tip/tutorial. The focus here will be on WordProcessingML.
Background
Before we begin dipping our feet into the code, I'm making alot of assumptions, and the first that you have actually started the road of learning OpenXML but struggling a bit. If you are a complete newbie and not even sure what OpenXML is, here is some good grounding (my hot list):
- Beginning Tutorials - A Must
- An Overview of The Package Convention
- OpenXML Wiki (reference by Keyword)
- OpenXML Introduction Wiki
- Eric Whites Intro - A Must Must
That should be sufficient to really get the ball rolling, and if you looking for a shortcut, Eric White's Intro is fantastic!
Using the code
Create
a Document
So our first task will be to create a document we can use.
public static void HelloWorld(string docName)
{
using (WordprocessingDocument package =
WordprocessingDocument.Create(docName, WordprocessingDocumentType.Document))
{
package.AddMainDocumentPart();
package.MainDocumentPart.Document =
new Document(
new Body(
new Paragraph(
new Run(
new Text("Hello World!")))));
package.MainDocumentPart.Document.Save();
}
}
The code is pretty simple - and adds a MainDocumentPart
and adds the key structure necessary for a document.
Use a Template
Next let's use a Template (*.dotx) as base for creating other Word documents (*.docx). One of the ways you can really short-cut your development time is to build a skeleton with all your formatting requirements and even static text, tables or media that will be necessary for the reports or documents you are creating, and using bookmarks only add in what is dynamic in nature. More about that to come.
public static void CopyTemplate(string FileToMake)
{
File.Copy(@"c:\temp\SERE_Template.dotx", FileToMake);
using (WordprocessingDocument document = WordprocessingDocument.Open(FileToMake, true))
{
document.ChangeDocumentType(WordprocessingDocumentType.Document);
StyleDefinitionsPart part = document.MainDocumentPart.StyleDefinitionsPart;
.......
}
}
Change Style of Existing Document
One of the things many struggle with at the start is how to change the defaults for a document, so it mirrored across all the objects of a document. So instead of having to define a style for every paragraph, why not just define it once. For more information check this post on StackOverflow.
public static void GetSetStyleFromDoc(string file)
{
using (var document = WordprocessingDocument.Open(file,true))
{
StyleDefinitionsPart part = document.MainDocumentPart.StyleDefinitionsPart;
foreach (Style style in part.RootElement.Elements<Style>())
{
if (style.StyleId.Value.Equals("PartA", StringComparison.InvariantCultureIgnoreCase))
{
style.StyleParagraphProperties.SpacingBetweenLines.Line = "276";
style.StyleRunProperties.FontSize.Val = "14";
style.StyleRunProperties.Color.Val = "4F81BD";
ParagraphBorders paragraphBorders1 = new ParagraphBorders();
TopBorder topBorder1 = new TopBorder(){ Val = BorderValues.Single,
Color = "856363", Size = (UInt32Value)24U, Space = (UInt32Value)0U };
LeftBorder leftBorder1 = new LeftBorder(){ Val = BorderValues.Single,
Color = "856363", Size = (UInt32Value)24U, Space = (UInt32Value)0U };
BottomBorder bottomBorder1 = new BottomBorder(){ Val = BorderValues.Single,
Color = "856363", Size = (UInt32Value)24U, Space = (UInt32Value)0U };
RightBorder rightBorder1 = new RightBorder(){ Val = BorderValues.Single,
Color = "856363", Size = (UInt32Value)24U, Space = (UInt32Value)0U };
paragraphBorders1.Append(topBorder1);
paragraphBorders1.Append(leftBorder1);
paragraphBorders1.Append(bottomBorder1);
paragraphBorders1.Append(rightBorder1);
style.StyleParagraphProperties.ParagraphBorders = paragraphBorders1;
}
}
}
}
Add Text to a BookMark
This feeds back to saving development time, instead of manually creating a document from scratch, rather take a template, set BookMarks in place, and then programmatically
add the Document structures you need. This is tremendously effective.
public static void AddTextToBookmark(string fileName, string textToAdd)
{
IDictionary<String, BookmarkStart> bookmarkMap = new Dictionary<String, BookmarkStart>();
using (var document = WordprocessingDocument.Open(fileName, true))
{
var doc = document.MainDocumentPart;
foreach (BookmarkStart bookmarkStart in doc.RootElement.Descendants<BookmarkStart>())
{
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
foreach (BookmarkStart bookmarkStart in bookmarkMap.Values)
{
if (bookmarkStart.Name == "bkImage")
{
Text text = new Text(textToAdd);
Run run = new Run(new RunProperties(new Bold()));
run.Append(text);
bookmarkStart.InsertAfterSelf(run);
}
}
}
}
I've attached a project with all the Source Code which also covers (which you can download from above)
- Adding a Table
- Adding an Image
- Adding Text To A Page that is Landscape Mode
Points of Interest
Again this is not a HOWTO or a beginner tutorial but some real hard practical code to get you started on your own project.
Further in the Project Solution I have attached there should be sufficient building blocks for any project.