Some of you may recall Brian discussed the System.IO.Packaging assembly from the Windows Presentation Foundations in his blog back in June. 

In the coming posts I want to discuss how you can use the WinFX System.IO.Packaging assemblies with .NET 2.0 to manipulate the new Office Open XML file format. 

What you will need:

Visual Studio 2005 - In order to run WinFX code, you will need Visual Studio .NET 2005.  I'm a C# guy myself, but I'll try to provide samples in both C# and VB.NET.  You can use any edition of VS 2005, including the VS Express Editions of VB.NET and C#. 

Gotcha: I found that I had to browse directly to the windowsbase.dll (the assembly that contains Packaging) in order to reference it.  It did not appear in the VS list, YMMV.

WinFX - Also, you will need WinFX.  While WinFX is a part of Vista, it is also supported on WindowsXP SP2 and Windows Server 2003 SP1.  For Office “12” beta1, you can use the November, December or January CTP of WinFX.

An Office "12" Beta1 File - You'll need a Beta 1 file to try this. 

Let's get started.

Step1: Finding the Start Part

When working with the OpenXML formats, the way to begin is to find the start part.  The start part is declared with a package relationship of type (http://schemas.microsoft.com/office/2006/relationships/officeDocument).  For Word documents, this relationship is to the document.xml part, for Excel workbooks, it is the workbook.xml , and for PowerPoint presentations, it's the presentation.xml.  Once you've found the start part, you only need to start to walk down the tree to find all of the other parts until you find the one you are looking for.  In future posts I'll describe how to get to some of the more specific parts. 

The following sample will open the file with the given file name and find the Office start part (documentPart).  I've attached this as a C# code snippet.

/// <summary>

/// Given a file name, find the start part. Works with any Office Open XML file.

/// </summary>

/// <param name="fileName">name of the file to find the start part</param>

public void FindStartPart(string fileName)

{

string officeDocRelType = @"http://schemas.microsoft.com/office/2006/relationships/officeDocument";

       PackagePart documentPart = null;

       Uri documentUri = null;

 

       //Open the package with Read permission

       using (Package officePackage = Package.Open(fileName, FileMode.Open, FileAccess.Read))

       {

                     //Get the start part

               foreach (PackageRelationship relationship in officePackage.GetRelationshipsByType(officeDocRelType))

                {

                    // There should only be one document part in the package

                    documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);

                    documentPart = officePackage.GetPart(documentUri);

                    break;

                }

                //TODO: Add your code here:

}

}

 

Step2: Finding the part you’re looking for

You can find any part related to the officeDocument part by repeating the foreach loop through the relationships against that part.  Follow this recursively until you have the part you are looking for.  For example, add the following code right after the foreach loop above to find the comments part of a Word Document:

//Find the Comments part:

string commentsPartRelType = @”http://schemas.microsoft.com/office/2006/relationships/wordComments";

PackagePart commentsPart = null;

Stream commentsXML = null;

 

//Walk through the relationships from the document.xml:

foreach (PackageRelationship relationship in documentPart.GetRelationshipsByType(commentsPartRelType))

{

//The comments part is found in /word/comments.xml

//use the documentUri to resolve the target:

Uri commentsUri = PackUriHelper.ResolvePartUri(documentUri, relationship.TargetUri);

commentsPart = officePackage.GetPart(commentsUri);

//There is only 1 comments part:

break;

}

That's pretty painless, just rinse and repeat to find the part you are looking for.  In my next post we'll look at removing a part.