Open a word processing document for read-only access

This topic describes how to use the classes in the Open XML SDK for Office to programmatically open a word processing document for read only access.


When to Open a Document for Read-only Access

Sometimes you want to open a document to inspect or retrieve some information, and you want to do so in a way that ensures the document remains unchanged. In these instances, you want to open the document for read-only access. This how-to topic discusses several ways to programmatically open a read-only word processing document.


Create a WordprocessingDocument Object

In the Open XML SDK, the WordprocessingDocument class represents a Word document package. To work with a Word document, first create an instance of the WordprocessingDocument class from the document, and then work with that instance. Once you create the instance from the document, you can then obtain access to the main document part that contains the text of the document. Every Open XML package contains some number of parts. At a minimum, a WordProcessingDocument must contain a main document part that acts as a container for the main text of the document. The package can also contain additional parts. Notice that in a Word document, the text in the main document part is represented in the package as XML using WordprocessingML markup.

To create the class instance from the document you call one of the Open methods. Several Open methods are provided, each with a different signature. The methods that let you specify whether a document is editable are listed in the following table.

Open Method Class Library Reference Topic Description
Open(String, Boolean) Open(String, Boolean) Create an instance of the WordprocessingDocument class from the specified file.
Open(Stream, Boolean) Open(Stream, Boolean) Create an instance of the WordprocessingDocument class from the specified IO stream.
Open(String, Boolean, OpenSettings) Open(String, Boolean, OpenSettings) Create an instance of the WordprocessingDocument class from the specified file.
Open(Stream, Boolean, OpenSettings) Open(Stream, Boolean, OpenSettings) Create an instance of the WordprocessingDocument class from the specified I/O stream.

The table above lists only those Open methods that accept a Boolean value as the second parameter to specify whether a document is editable. To open a document for read only access, you specify false for this parameter.

Notice that two of the Open methods create an instance of the WordprocessingDocument class based on a string as the first parameter. The first example in the sample code uses this technique. It uses the first Open method in the table above; with a signature that requires two parameters. The first parameter takes a string that represents the full path filename from which you want to open the document. The second parameter is either true or false; this example uses false and indicates whether you want to open the file for editing.

The following code example calls the Open Method.

    // Open a WordprocessingDocument for read-only access based on a filepath.
    using (WordprocessingDocument wordDocument =
        WordprocessingDocument.Open(filepath, false))

The other two Open methods create an instance of the WordprocessingDocument class based on an input/output stream. You might employ this approach, for instance, if you have a Microsoft SharePoint Foundation 2010 application that uses stream input/output, and you want to use the Open XML SDK to work with a document.

The following code example opens a document based on a stream.

    Stream stream = File.Open(strDoc, FileMode.Open);
    // Open a WordprocessingDocument for read-only access based on a stream.
    using (WordprocessingDocument wordDocument =
        WordprocessingDocument.Open(stream, false))

Suppose you have an application that employs the Open XML support in the System.IO.Packaging namespace of the .NET Framework Class Library, and you want to use the Open XML SDK to work with a package read only. While the Open XML SDK includes method overloads that accept a Package as the first parameter, there is not one that takes a Boolean as the second parameter to indicate whether the document should be opened for editing.

The recommended method is to open the package read-only to begin with prior to creating the instance of the WordprocessingDocument class, as shown in the second example in the sample code. The following code example performs this operation.

    // Open System.IO.Packaging.Package.
    Package wordPackage = Package.Open(filepath, FileMode.Open, FileAccess.Read);

    // Open a WordprocessingDocument based on a package.
    using (WordprocessingDocument wordDocument =
        WordprocessingDocument.Open(wordPackage))

Once you open the Word document package, you can access the main document part. To access the body of the main document part, you assign a reference to the existing document body, as shown in the following code example.

    // Assign a reference to the existing document body.
    Body body = wordprocessingDocument.MainDocumentPart.Document.Body;

Structure of a WordProcessingML Document

The basic document structure of a WordProcessingML document consists of the document and body elements, followed by one or more block level elements such as p, which represents a paragraph. A paragraph contains one or more r elements. The r stands for run, which is a region of text with a common set of properties, such as formatting. A run contains one or more t elements. The t element contains a range of text. The following code example shows the WordprocessingML markup for a document that contains the text "Example text."

    <w:document xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
      <w:body>
        <w:p>
          <w:r>
            <w:t>Example text.</w:t>
          </w:r>
        </w:p>
      </w:body>
    </w:document>

Using the Open XML SDK, you can create document structure and content using strongly-typed classes that correspond to WordprocessingML elements. You will find these classes in the DocumentFormat.OpenXml.Wordprocessing namespace. The following table lists the class names of the classes that correspond to the document, body, p, r, and t elements.

WordprocessingML Element Open XML SDK Class Description
document Document The root element for the main document part.
body Body The container for the block level structures such as paragraphs, tables, annotations and others specified in the ISO/IEC 29500 specification.
p Paragraph A paragraph.
r Run A run.
t Text A range of text.

For more information about the overall structure of the parts and elements of a WordprocessingML document, see Structure of a WordprocessingML document.


Generate the WordprocessingML Markup to Add Text and Attempt to Save

The sample code shows how you can add some text and attempt to save the changes to show that access is read-only. Once you have access to the body of the main document part, you add text by adding instances of the Paragraph, Run, and Text classes. This generates the required WordprocessingML markup. The following code example adds the paragraph, run, and text.

    // Attempt to add some text.
    Paragraph para = body.AppendChild(new Paragraph());
    Run run = para.AppendChild(new Run());
    run.AppendChild(new Text("Append text in body, but text is not saved - OpenWordprocessingDocumentReadonly"));

    // Call Save to generate an exception and show that access is read-only.
    wordDocument.MainDocumentPart.Document.Save();

Sample Code

The first example method shown here, OpenWordprocessingDocumentReadOnly, opens a Word document for read-only access. Call it by passing a full path to the file that you want to open. For example, the following code example opens the Word12.docx file in the Public Documents folder for read-only access.

    OpenWordprocessingDocumentReadonly(@"c:\Users\Public\Public Documents\Word12.docx");

The second example method, OpenWordprocessingPackageReadonly, shows how to open a Word document for read-only access from a System.IO.Packaging.Package. Call it by passing a full path to the file that you want to open. For example, the following code opens the Word12.docx file in the Public Documents folder for read-only access.

    OpenWordprocessingPackageReadonly(@"c:\Users\Public\Public Documents\Word12.docx");

Important

If you uncomment the statement that saves the file, the program would throw an IOException because the file is opened for read-only access.

The following is the complete sample code in C# and VB.


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

OpenWordprocessingDocumentReadonly(args[0]);

static void OpenWordprocessingDocumentReadonly(string filepath)
{
    // Open a WordprocessingDocument based on a filepath.
    using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(filepath, false))
    {
        if (wordDocument is null)
        {
            throw new ArgumentNullException(nameof(wordDocument));
        }
        // Assign a reference to the existing document body.
        MainDocumentPart mainDocumentPart = wordDocument.MainDocumentPart ?? wordDocument.AddMainDocumentPart();
        mainDocumentPart.Document ??= new Document();

        Body body = mainDocumentPart.Document.Body ?? mainDocumentPart.Document.AppendChild(new Body());

        // Attempt to add some text.
        Paragraph para = body.AppendChild(new Paragraph());
        Run run = para.AppendChild(new Run());
        run.AppendChild(new Text("Append text in body, but text is not saved - OpenWordprocessingDocumentReadonly"));

        // Call Save to generate an exception and show that access is read-only.
        //mainDocumentPart.Document.Save();
    }
}

See also