Open-XML-SDK Documentation

Open XML SDK by Microsoft

4,614 stars C# C# 1 file ยท ~3,669 tokens #docx#office#openxml-format#pptx
RAW Doc

Technical Documentation: dotnet/Open-XML-SDK

โ„น๏ธ Provenance: Multi-Tier Ingestion ยท CodeWiki Reference

Overview (README.md)

Open XML SDK

[!NOTE]

3.0.0 introduced breaking changes and you should be able to update your package and recompile with limited changes. Please see the v3.0.0 milestone for issues and PRs that were included.

[!IMPORTANT]
The CI feed URL has changed as of 2 April, 2024. Please update to the new URL if using CI builds.



The Open XML SDK is a framework for working with Microsoft Office Word, Excel, and PowerPoint documents. It includes APIs for low-level operations related to OPC packages, Flat OPC files, and Open XML markup in two forms (i.e., strongly-typed classes and LINQ to XML). It is designed to closely follow the Microsoft Office implementation of the ISO 29500 standard, but was not intended to directly provide higher-level abstractions or productivity tools.

These APIs enable scenarios such as:

  • High-performance generation of word-processing documents, spreadsheets, and presentations.
  • Document modification, such as adding, updating, and removing content and metadata.
  • Searching and replacing content using regular expressions.
  • Splitting up (shredding) a file into multiple files, and combining multiple files into a single file.
  • Updating cached data and embedded spreadsheets for charts in Word/PowerPoint.

Prerequisite for using the Open XML SDK: detailed knowledge of the relevant formats (https://learn.microsoft.com/en-us/openspecs/office_standards/ms-offstandlp) and standards (https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html - search for 29500)

Table of Contents

Packages

The official release NuGet packages for Open XML SDK are on NuGet.org:

Package Stable Prerelease
DocumentFormat.OpenXml.Framework
DocumentFormat.OpenXml
DocumentFormat.OpenXml.Linq
DocumentFormat.OpenXml.Features

Daily Builds

The NuGet package for the latest builds of the Open XML SDK is available as a custom feed on an Azure blob. Stable releases here will be mirrored onto NuGet and will be identical. You must set up a NuGet.config file that looks similar to this:

xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="OpenXmlCI" value="https://ooxml.blob.core.windows.net/feed/index.json" />
  </packageSources>
</configuration>

For latests changes, please see the changelog

Known Issues

  • On .NET Core and .NET 5 and following, ZIP packages do not have a way to stream data. Thus, the working set can explode in certain situations. This is a known issue.
  • On .NET Framework, an IsolatedStorageException may be thrown under certain circumstances. This generally occurs when manipulating a large document in an environment with an AppDomain that does not have enough evidence. A sample with a workaround is available here.

Documentation

Please see Open XML SDK for the official documentation.

If you have how-to questions

  • Open XML SDK 2.5 Productivity Tool: The Productivity Tool provides viewing and code generation compatible with the Open XML SDK 2.5.
  • Open XML Powertools: This provides example code and guidance for implementing a wide range of Open XML scenarios.
  • ClosedXml: This library provides a simplified object model on top of the OpenXml SDK for manipulating and creating Excel documents.
  • OfficeIMO: This library provides a simplified object model on top of the OpenXml SDK for manipulating and creating Word, Excel, PowerPoint documents with support for Markdown, Html and Pdf, and Visio.
  • OpenXML-Office: This nuget library provides a simplified object model on top of the OpenXml SDK manipulating and creating PPT and Excel documents.
  • Serialize.OpenXml.CodeGen: This is a tool that converts an OpenXml document into the .NET code required to create it.
  • Html2OpenXml: This is a tool that takes HTML and converts it to an OpenXml document.
  • DocxToSource: This is a tool designed to be a replacement for the old OpenXML SDK Productivity Tool.
  • OOXML Viewer: This is an extension for Visual Studio Code to View and Edit the xml parts of an Office Open XML file and to view a diff with the previous version of an OOXML part when saved from an outside program. Search "OOXML" in the VS Code extensions tab or download it from the VS Code Marketplace
  • ShapeCrawler: This library provides a simplified object model on top of the OpenXml SDK to manipulate PowerPoint documents.
  • OOXML Validator: VS Code extension to validate Office Open XML files. Search "OOXML" in the VS Code extensions tab or download it from the VS Code Marketplace

How can I contribute?

We welcome contributions! Many people all over the world have helped make this project better.

  • Contributing explains what kinds of contributions we welcome

Reporting security issues and security bugs

Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) [email protected]. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the Security TechCenter.

.NET Foundation

The Open XML SDK is a .NET Foundation project.

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information, see the .NET Foundation Code of Conduct.

License

The Open XML SDK is licensed under the MIT license.


Diagnostics (`docs/Diagnostics.md`)

As of v3.0, a new abstraction layer was added in between System.IO.Packaging and DocumentFormat.OpenXml.Packaging.OpenXmlPackage. This is currently experimental, but can be used if needed. This will be stabalized in a future release, and may or may not require code changes.


Features (`docs/Features.md`)

Features

Features are a new concept in v2.14 and later that allows for behavior and state to be contained within the document or part. This is accessed via Features property on packages, parts, and elements. Elements inherit part features, and parts inherit package features.

This is inspired by the pattern ASP.NET Core uses to modify behavior of HttpContext: https://learn.microsoft.com/aspnet/core/fundamentals/request-features. This is an implementation of the strategy pattern that makes it easy to replace behavior on the fly.

As of v3.0, the IFeatureCollection includes the ability to enumerate registered features.

Visualizing Registered Features

The in-box implementations of the IFeatureCollection provide a helpful debug view so you can see what features are available and what their properties/fields are:

Current Features

The features that are currently available are described below and at what scope they are available:

IDisposableFeature

This feature allows for registering actions that need to run when a package or a part is destroyed or disposed:

csharp
OpenXmlPackage package = GetSomePackage();
package.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the package is disposed */);

OpenXmlPart part = GetSomePart();
part.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the part is removed or closed */);

Packages and parts will have their own implementations of this feature. Elements will retrieve the feature for their containing part if available.

IPackageEventsFeature

This feature allows getting event notifications of when a package is changed:

csharp
OpenXmlPackage package = GetSomePackage();
package.TryAddPackageEventsFeature();

var feature = package.Features.GetRequired<IPackageEventsFeature>();

Note: There may be times when the package is changed but an event is not fired. Not all areas have been identified where it would make sense to raise an event. Please file an issue if you find one.

IPartEventsFeature

This feature allows getting event notifications of when an event is being created. This is a feature that is added to the part or package:

csharp
OpenXmlPart part = GetSomePackage();
package.AddPartEventsFeature();

var feature = part.Features.GetRequired<IPartEventsFeature>();

Generally, assume that there may be a singleton implementation for the events and verify that the part is the correct part.

Note: There may be times when the part is changed but an event is not fired. Not all areas have been identified where it would make sense to raise an event. Please file an issue if you find one.

IPartRootEventsFeature

This feature allows getting event notifications of when a part root is being modified/loaded/created/etc. This is a feature that is added to the part level feature:

csharp
OpenXmlPart part = GetSomePart();
part.AddPartRootEventsFeature();

var feature = part.Features.GetRequired<IPartRootEventsFeature>();

Generally, assume that there may be a singleton implementation for the events and verify that the part is the correct part.

Note: There may be times when the part root is changed but an event is not fired. Not all areas have been identified where it would make sense to raise an event. Please file an issue if you find one.

DocumentFormat.OpenXml.Features

This library contains additional (non-core) features that build on top of built-in features and functionality.

IRandomNumberGeneratorFeature

This feature allows for a shared service to generate random numbers and fill an array.

IParagraphIdGeneratorFeature

This feature allows for population and tracking of elements that contain paragraph ids. By default, this will ensure uniqueness of values and ensure that values that do exist are valid per the constraints of the standard. To use this feature:

csharp
WordprocessingDocument document = CreateWordDocument();
document.TryAddParagraphIdFeature();

var part = doc.AddMainDocumentPart();
var body = new Body();
part.Document = new Document(body);

var p = new Paragraph();
body.AddChild(p); // After adding p.ParagraphId will be set to a unique, valid value

This feature can also be used to ensure uniqueness among multiple documents with a slight change:

csharp
using var doc1 = CreateDocument1();
using var doc2 = CreateDocument2();

var shared = doc1
    .AddSharedParagraphIdFeature()
    .Add(doc2);

// Add item to doc1
var part1 = doc1.AddMainDocumentPart();
var body1 = new Body();
var p1 = new Paragraph();
part1.Document = new Document(body1);
body1.AddChild(p1);

// Add item with same ID to doc2
var part2 = doc2.AddMainDocumentPart();
var body2 = new Body();
var p2 = new Paragraph { ParagraphId = p1.ParagraphId };
part2.Document = new Document(body2);
body2.AddChild(p2);

// Assert
Assert.NotEqual(p1.ParagraphId, p2.ParagraphId);
Assert.Equal(2, shared.Count);

DocumentFormat.OpenXml.Linq

IPartRootXElementFeature

This feature allows operating on an OpenXmlPart by using XLinq features and directly manipulating XElement nodes.

csharp
OpenXmlPart part = GetSomePart();

var node = new(W.document, new XAttribute(XNamespace.Xmlns + "w", W.w),
    new XElement(W.body,
        new XElement(W.p,
            new XElement(W.r,
                new XElement(W.t, "Hello World!")))));

part.SetXElement(node);

This XElement is cached but will be kept in sync with the underlying part if it were to change.


--- METRICS ---