Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining
Export (0) Print
Expand All
Expand Minimize

Changing the Print Orientation of Word 2010 Documents by Using the Open XML SDK 2.0

Office 2010

Office Visual How To

Summary:  Use the strongly typed classes in the Open XML SDK 2.0 to specify the print orientation for a Word document, without loading the document into Microsoft Word.

Last modified: September 12, 2012

Applies to: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2010 | VBA | Word 2010

Published:  November 2010

Provided by:  Ken Getz, MCW Technologies, LLC

Overview

The Open XML file formats make it possible to specify print orientation in Microsoft Word documents. The Open XML SDK 2.0 adds strongly typed classes that simplify access to the Open XML file formats: The SDK simplifies the tasks of working with print orientation, because it makes it easier to interact with the elements within the Open XML content. The code sample that is included with this Visual How To describes how to the use the SDK to achieve this goal.

Code It

The sample, provided with this Visual How To, includes the code that is required to specify print orientation in a Word 2007 or Word 2010 document. The following sections describe the code.

Setting Up References

To use the code from the Open XML SDK 2.0, you must add some references to your project. The sample project already includes these references, but in your own code, you would have to explicitly reference the following assemblies:

  • WindowsBase─This reference may be set for you, depending on the kind of project that you create.

  • DocumentFormat.OpenXml─This assembly is installed by the Open XML SDK 2.0.

Also, you should add the following using/Imports statements to the top of your code file.

using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

Examining the Procedure

The WDSetPrintOrientation procedure accepts two parameters: to indicate the name of the document to modify (string), and to describe the new print orientation (DocumentFormat.OpenXml.Wordprocessing.PageOrientationValues).

public static void WDSetPrintOrientation(
  string fileName, PageOrientationValues newOrientation)

For each section in the document, if the new orientation is different than the print orientation of the current section, the procedure modifies the print orientation for the section. In addition, the procedure must update the width and height and the margins for each section.

To call the procedure, pass the parameter values, as shown in the example code. Verify that you provide a document named C:\temp\Orientation.docx, which (for demonstration) contains multiple sections, before you run the sample code.

WDSetPrintOrientation(
  @"C:\temp\Orientation.docx", PageOrientationValues.Portrait);

Accessing the Document

The code starts by opening the document by using the WordprocessingDocument.Open method and indicating that the document should be open for read-write access (the final true parameter). The code maintains a Boolean variable tracking whether the document has changed (so it can save the document later, if so). The code retrieves a reference to the main document part, and then uses that reference to retrieve a collection of all the SectionProperties descendants within the content of the document—later code will use this collection to set the orientation for each section in turn.

using (var document = WordprocessingDocument.Open(fileName, true))
{
  bool documentChanged = false;

  var docPart = document.MainDocumentPart;
  var sections = docPart.Document.Descendants<SectionProperties>();
  // Code removed here…
}

Iterating Through the Sections

The next block of code iterates through all the sections in the collection of SectionProperties elements. For each section, the code initializes a variable that tracks whether the page orientation for the section was changed (it is possible that the new orientation matches the original orientation, with no change required), so the code can update the page size and margins. The code continues by retrieving a reference to the first PageSize descendant of the SectionProperties element. If the reference is not null , the code will fix the orientation as required.

foreach (SectionProperties sectPr in sections)
{
  bool pageOrientationChanged = false;

  PageSize pgSz = sectPr.Descendants<PageSize>().FirstOrDefault();
  if (pgSz != null)
  {
    // Code removed here…
  }
}

Setting the Section Orientation

The next block of code starts by verifying that the Orient property of the PageSize element already exists. As with many properties of Microsoft Word Open XML elements, it is possible that the property/attribute does not exist yet. In that case, retrieving the property returns a null reference using the Open XML SDK 2.0. If the property does not exist, and the new orientation is Portrait, there is nothing to do—that is the default and there is no reason to modify the document. If the Orient property already exists, and its value differs from the new orientation value supplied as a parameter to the method, the code sets the Value property of the Orient property, and sets both the pageOrientationChanged and the documentChanged flags. (The code uses the pageOrientationChanged flag to determine whether it must update the page size and margins. It uses the documentChanged flag to determine whether it must save the document at the end). Be aware that if the code must create the Orient property, it must also create the value to store in the property, as a new EnumValue instance, supplying the new orientation in the EnumValue constructor.

if (pgSz.Orient == null)
{
  if (newOrientation != PageOrientationValues.Portrait)
  {
    pageOrientationChanged = true;
    documentChanged = true;
    pgSz.Orient = new EnumValue<PageOrientationValues>(newOrientation);
  }
}
else
{
  if (pgSz.Orient.Value != newOrientation)
  {
    pgSz.Orient.Value = newOrientation;
    pageOrientationChanged = true;
    documentChanged = true;
  }
}

Fixing the Page Size

At this point in the code, the page orientation may have changed. If so, the code must perform two more tasks: It must fix the page size, and fix the page margins for the section. The code swaps the page height and width, storing the values in the PageSize element.

if (pageOrientationChanged)
{
  var width = pgSz.Width;
  var height = pgSz.Height;
  pgSz.Width = height;
  pgSz.Height = width;
  // Code removed here…
}

Fixing the Margins

The next step in the sample procedure handles margins for the section. If the page orientation has changed, the code must rotate the margins to match. To do so, the code retrieves a reference to the PageMargin element for the section and, if it exists, rotates the margins. Be aware that the code rotates the margins by 90 degrees—some printers rotate the margins by 270 degrees instead, and you could modify the code to account for that. Also, be aware that the Top and Bottom properties of the PageMargin object are signed values, and the Left and Right properties are unsigned values. The code must convert between the two kinds of values as it rotates the margin settings.

PageMargin pgMar = sectPr.Descendants<PageMargin>().FirstOrDefault();
if (pgMar != null)
{

  // Rotate margins. Printer settings control how far you 
  // rotate when switching to landscape mode. Not having those
  // settings, this code rotates 90 degrees. You could easily
  // modify this behavior, or make it a parameter for the 
  // procedure.

  var top = pgMar.Top.Value;
  var bottom = pgMar.Bottom.Value;
  var left = pgMar.Left.Value;
  var right = pgMar.Right.Value;

  pgMar.Top = new Int32Value((int)left);
  pgMar.Bottom = new Int32Value((int)right);
  pgMar.Left = new UInt32Value((uint)System.Math.Max(0, bottom));
  pgMar.Right = new UInt32Value((uint)System.Math.Max(0, top));
}

Saving the Document

After modification, the code determines whether the document has changed; if the document has changed, the code then saves it.

if (documentChanged)
{
  docPart.Document.Save();
}

Sample Procedure

The following code example contains the complete sample procedure.

public static void WDSetPrintOrientation(
  string fileName, PageOrientationValues newOrientation)
{
  using (var document = WordprocessingDocument.Open(fileName, true))
  {
    bool documentChanged = false;

    var docPart = document.MainDocumentPart;
    var sections = docPart.Document.Descendants<SectionProperties>();

    foreach (SectionProperties sectPr in sections)
    {
      bool pageOrientationChanged = false;

      PageSize pgSz = sectPr.Descendants<PageSize>().FirstOrDefault();
      if (pgSz != null)
      {
        if (pgSz.Orient == null)
        {
          if (newOrientation != PageOrientationValues.Portrait)
          {
            pageOrientationChanged = true;
            documentChanged = true;
            pgSz.Orient = 
              new EnumValue<PageOrientationValues>(newOrientation);
          }
        }
        else
        {
          // The Orient property exists, but its value
          // is different than the new value.
          if (pgSz.Orient.Value != newOrientation)
          {
            pgSz.Orient.Value = newOrientation;
            pageOrientationChanged = true;
            documentChanged = true;
          }
        }

        if (pageOrientationChanged)
        {
          var width = pgSz.Width;
          var height = pgSz.Height;
          pgSz.Width = height;
          pgSz.Height = width;

          PageMargin pgMar = 
            sectPr.Descendants<PageMargin>().FirstOrDefault();
          if (pgMar != null)
          {
            var top = pgMar.Top.Value;
            var bottom = pgMar.Bottom.Value;
            var left = pgMar.Left.Value;
            var right = pgMar.Right.Value;

            pgMar.Top = new Int32Value((int)left);
            pgMar.Bottom = new Int32Value((int)right);
            pgMar.Left = new UInt32Value(
              (uint)System.Math.Max(0, bottom));
            pgMar.Right = new UInt32Value(
              (uint)System.Math.Max(0, top));
          }
        }
      }
    }
    if (documentChanged)
    {
      docPart.Document.Save();
    }
  }
}
Read It

The sample that is included with this Visual How To describes code that sets print orientation in a Word document. In order to use the sample, you must install the Open XML SDK 2.0, available from the link listed in the Explore It section. The sample also uses a modified version of code included as part of a set of code examples for the Open XML SDK 2.0. The Explore It section also includes a link to the full set of code examples, although you can use the sample without downloading and installing the code examples.

The sample application demonstrates only some the available properties and methods that are provided by the Open XML SDK 2.0 that you can use to modify document structure. For more information, see the documentation that is included with the Open XML SDK 2.0 Productivity Tool. Click the Open XML SDK Documentation tab in the lower-left corner of the application window, and search for the class that you want to study. Although the documentation does currently not include code examples, given the sample shown here and the documentation, you should be able to successfully modify the sample application.

See It

Watch the video

Watch video

Length: 00:09:24

Click to grab code

Grab the Code

Explore It

About the Author
Ken Getz is a senior consultant with MCW Technologies. He is coauthor of ASP.NET Developers Jumpstart (Addison-Wesley, 2002), Access Developer's Handbook (Sybex, 2001), and VBA Developer's Handbook, 2nd Edition (Sybex, 2001).

Show:
© 2015 Microsoft