Skip to content

Commit 36e2341

Browse files
authored
Merge pull request #174 from OfficeDev/main
[admin] merge to live
2 parents b97f90b + b8207c9 commit 36e2341

File tree

433 files changed

+15361
-12819
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

433 files changed

+15361
-12819
lines changed

docs/about-the-open-xml-sdk.md

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ The document parts in an Open XML package are created as XML markup. Because XML
2727

2828
Structurally, an Open XML document is an Open Packaging Conventions (OPC) package. As stated previously, a package is composed of a collection of document parts. Each part has a part name that consists of a sequence of segments or a pathname such as "/word/theme/theme1.xml." The package contains a [Content\_Types].xml part that allows you to determine the content type of all document parts in the package. A set of explicit relationships for a source package or part is contained in a relationships part that ends with the .rels extension.
2929

30-
Word processing documents are described by using WordprocessingML markup. For more information, see [Working with WordprocessingML documents (Open XML SDK)](working-with-wordprocessingml-documents.md). A WordprocessingML document is composed of a collection of stories where each story is one of the following:
30+
Word processing documents are described by using WordprocessingML markup. For more information, see [Working with WordprocessingML documents](word/overview.md). A WordprocessingML document is composed of a collection of stories where each story is one of the following:
3131

3232
- Main document (the only required story)
3333
- Glossary document
@@ -36,32 +36,22 @@ Word processing documents are described by using WordprocessingML markup. For mo
3636
- Text box
3737
- Footnote and endnote
3838

39-
Presentations are described by using PresentationML markup. For more information, see [Working with PresentationML documents (Open XML SDK)](working-with-presentationml-documents.md). Presentation packages can contain the following document parts:
39+
Presentations are described by using PresentationML markup. For more information, see [Working with PresentationML documents](presentation/overview.md). Presentation packages can contain the following document parts:
4040

4141
- Slide master
4242
- Notes master
4343
- Handout master
4444
- Slide layout
4545
- Notes
4646

47-
Spreadsheet workbooks are described by using SpreadsheetML markup. For more information, see [Working with SpreadsheetML documents (Open XML SDK)](working-with-spreadsheetml-documents.md). Workbook packages can contain:
47+
Spreadsheet workbooks are described by using SpreadsheetML markup. For more information, see [Working with SpreadsheetML documents](spreadsheet/overview.md). Workbook packages can contain:
4848

4949
- Workbook part (required part)
5050
- One or more worksheets
5151
- Charts
5252
- Tables
5353
- Custom XML
5454

55-
## Open XML SDK 1.0
56-
57-
Version 1 of the Open XML SDK simplified the manipulation of Open XML packages. The Open XML SDK Application Programming Interface (API) encapsulates many of the common tasks that you typically perform on Open XML packages, so you can perform complex operations with just a few lines of code. Some common tasks:
58-
59-
- **Search** With a few lines of code, you can search a collection of Excel 2007 worksheets for some arbitrary data.
60-
- **Document assembly** You can create documents by combining the document parts of existing documents programmatically. For example, you can pull slides from various PowerPoint 2007 presentations to create a single presentation.
61-
- **Validation** With a few lines of code, you can validate the document parts in a package or validate an entire package against a schema.
62-
- **Data update** With the Open XML object model, you can easily modify the data in multiple packages.
63-
- **Privacy** With a few lines of code, you can remove comments and other personal information from a document before it is distributed.
64-
6555
## Open XML SDK for Microsoft Office
6656

6757
The SDK supports the following common tasks/scenarios:

docs/general/diagnosticids.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: Diagnostic IDs
3+
ms.suite: office
4+
5+
ms.author: o365devx
6+
author: o365devx
7+
ms.topic: conceptual
8+
ms.date: 11/01/2017
9+
ms.localizationpriority: high
10+
---
11+
12+
# Diagnostic IDs
13+
14+
Diagnostic IDs are used to identify APIs or patterns that can raise compiler warnings or errors. This can be done via [ObsoleteAttribute](/dotnet/api/system.obsoleteattribute.diagnosticid) or [ExperimentalAttribute](/dotnet/api/system.diagnostics.codeanalysis.experimentalattribute). These can be suppressed at the consumer level for each diagnostic id.
15+
16+
## Experimental APIs
17+
18+
### OOXML0001
19+
20+
**Title**: IPackage related APIs are currently experimental
21+
22+
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.
23+
24+
## Suppress warnings
25+
26+
It's recommended that you use an available workaround whenever possible. However, if you cannot change your code, you can suppress warnings through a `#pragma` directive or a `<NoWarn>` project setting. If you must use the obsolete or experimental APIs and the `OOXMLXXXX` diagnostic does not surface as an error, you can suppress the warning in code or in your project file.
27+
28+
To suppress the warnings in code:
29+
30+
```csharp
31+
// Disable the warning.
32+
#pragma warning disable OOXML0001
33+
34+
// Code that uses obsolete or experimental API.
35+
//...
36+
37+
// Re-enable the warning.
38+
#pragma warning restore OOXML0001
39+
```
40+
41+
To suppress the warnings in a project file:
42+
43+
```xml
44+
<Project Sdk="Microsoft.NET.Sdk">
45+
<PropertyGroup>
46+
<TargetFramework>net6.0</TargetFramework>
47+
<!-- NoWarn below suppresses SYSLIB0001 project-wide -->
48+
<NoWarn>$(NoWarn);OOXML0001</NoWarn>
49+
<!-- To suppress multiple warnings, you can use multiple NoWarn elements -->
50+
<NoWarn>$(NoWarn);OOXML0001</NoWarn>
51+
<NoWarn>$(NoWarn);OTHER_WARNING</NoWarn>
52+
<!-- Alternatively, you can suppress multiple warnings by using a semicolon-delimited list -->
53+
<NoWarn>$(NoWarn);OOXML0001;OTHER_WARNING</NoWarn>
54+
</PropertyGroup>
55+
</Project>
56+
```
57+
58+
> [!NOTE]
59+
> Suppressing warnings in this way only disables the obsoletion warnings you specify. It doesn't disable any other warnings, including obsoletion warnings with different diagnostic IDs.

docs/general/features.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
---
2+
title: Custom SDK Features
3+
ms.suite: office
4+
5+
ms.author: o365devx
6+
author: o365devx
7+
ms.topic: conceptual
8+
ms.date: 11/13/2023
9+
ms.localizationpriority: medium
10+
---
11+
12+
# Custom SDK Features
13+
14+
Features in the Open XML SDK are available starting in v2.14.0 that allows for behavior and state to be contained within the document or part and customized without reimplementing the containing package or part. This is accessed via `Features` property on packages, parts, and elements.
15+
16+
This is an implementation of the [strategy pattern](https://refactoring.guru/design-patterns/strategy) that makes it easy to replace behavior on the fly. It is modeled after the [request features](/aspnet/core/fundamentals/request-features) in ASP.NET Core.
17+
18+
## Feature inheritance
19+
20+
Packages, parts, and elements all have their own feature collection. However, they will also inherit the containing part and package if it is available.
21+
22+
To highlight this, see the test case below:
23+
24+
```csharp
25+
OpenXmlPackage package = /* Create a package */;
26+
27+
var packageFeature = new PrivateFeature();
28+
package.Features.Set<PrivateFeature>(packageFeature);
29+
30+
var part = package.GetPartById("existingPart");
31+
Assert.Same(part.Features.GetRequired<PrivateFeature>(), package.Features.GetRequired<PrivateFeature>());
32+
33+
part.Features.Set<PrivateFeature>(new());
34+
Assert.NotSame(part.Features.GetRequired<PrivateFeature>(), package.Features.GetRequired<PrivateFeature>());
35+
36+
37+
private sealed class PrivateFeature
38+
{
39+
}
40+
```
41+
> [!NOTE]
42+
> The feature collection on elements is readonly. This is due to memory issues if it is made writeable. If this is needed, please engage on https://github.com/dotnet/open-xml-sdk to let us know your scenario.
43+
44+
## Visualizing Registered Features
45+
46+
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:
47+
48+
![Features Debug View](../media/feature-debug-view.png)
49+
50+
## Available Features
51+
52+
The features that are currently available are described below and at what scope they are available:
53+
54+
### IDisposableFeature
55+
56+
This feature allows for registering actions that need to run when a package or a part is destroyed or disposed:
57+
58+
```csharp
59+
OpenXmlPackage package = GetSomePackage();
60+
package.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the package is disposed */);
61+
62+
OpenXmlPart part = GetSomePart();
63+
part.Features.Get<IDisposableFeature>().Register(() => /* Some action that is called when the part is removed or closed */);
64+
```
65+
66+
Packages and parts will have their own implementations of this feature. Elements will retrieve the feature for their containing part if available.
67+
68+
### IPackageEventsFeature
69+
70+
This feature allows getting event notifications of when a package is changed:
71+
72+
```csharp
73+
OpenXmlPackage package = GetSomePackage();
74+
package.TryAddPackageEventsFeature();
75+
76+
var feature = package.Features.GetRequired<IPackageEventsFeature>();
77+
```
78+
79+
> [!NOTE]
80+
> 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.
81+
82+
### IPartEventsFeature
83+
84+
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:
85+
86+
```csharp
87+
OpenXmlPart part = GetSomePackage();
88+
package.AddPartEventsFeature();
89+
90+
var feature = part.Features.GetRequired<IPartEventsFeature>();
91+
```
92+
93+
Generally, assume that there may be a singleton implementation for the events and verify that the part is the correct part.
94+
95+
> [!NOTE]
96+
> 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.
97+
98+
### IPartRootEventsFeature
99+
100+
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:
101+
102+
```csharp
103+
OpenXmlPart part = GetSomePart();
104+
part.AddPartRootEventsFeature();
105+
106+
var feature = part.Features.GetRequired<IPartRootEventsFeature>();
107+
```
108+
109+
Generally, assume that there may be a singleton implementation for the events and verify that the part is the correct part.
110+
111+
> [!NOTE]
112+
> 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.
113+
114+
### IRandomNumberGeneratorFeature
115+
116+
This feature allows for a shared service to generate random numbers and fill an array.
117+
118+
### IParagraphIdGeneratorFeature
119+
120+
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:
121+
122+
```csharp
123+
WordprocessingDocument document = CreateWordDocument();
124+
document.TryAddParagraphIdFeature();
125+
126+
var part = doc.AddMainDocumentPart();
127+
var body = new Body();
128+
part.Document = new Document(body);
129+
130+
var p = new Paragraph();
131+
body.AddChild(p); // After adding p.ParagraphId will be set to a unique, valid value
132+
```
133+
134+
This feature can also be used to ensure uniqueness among multiple documents with a slight change:
135+
136+
```csharp
137+
using var doc1 = CreateDocument1();
138+
using var doc2 = CreateDocument2();
139+
140+
var shared = doc1
141+
.AddSharedParagraphIdFeature()
142+
.Add(doc2);
143+
144+
// Add item to doc1
145+
var part1 = doc1.AddMainDocumentPart();
146+
var body1 = new Body();
147+
var p1 = new Paragraph();
148+
part1.Document = new Document(body1);
149+
body1.AddChild(p1);
150+
151+
// Add item with same ID to doc2
152+
var part2 = doc2.AddMainDocumentPart();
153+
var body2 = new Body();
154+
var p2 = new Paragraph { ParagraphId = p1.ParagraphId };
155+
part2.Document = new Document(body2);
156+
body2.AddChild(p2);
157+
158+
// Assert
159+
Assert.NotEqual(p1.ParagraphId, p2.ParagraphId);
160+
Assert.Equal(2, shared.Count);
161+
```
162+
163+
### IPartRootXElementFeature
164+
165+
This feature allows operating on an `OpenXmlPart` by using XLinq features and directly manipulating `XElement` nodes.
166+
167+
```csharp
168+
OpenXmlPart part = GetSomePart();
169+
170+
var node = new(W.document, new XAttribute(XNamespace.Xmlns + "w", W.w),
171+
new XElement(W.body,
172+
new XElement(W.p,
173+
new XElement(W.r,
174+
new XElement(W.t, "Hello World!")))));
175+
176+
part.SetXElement(node);
177+
```
178+
179+
This `XElement` is cached but will be kept in sync with the underlying part if it were to change.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
3+
api_name:
4+
- Microsoft.Office.DocumentFormat.OpenXML.Packaging
5+
api_type:
6+
- schema
7+
ms.assetid: c9b2ce55-548c-4443-8d2e-08fe1f06b7d7
8+
title: 'How to: Add a new document part that receives a relationship ID to a package'
9+
ms.suite: office
10+
11+
ms.author: o365devx
12+
author: o365devx
13+
ms.topic: conceptual
14+
ms.date: 11/01/2017
15+
ms.localizationpriority: medium
16+
---
17+
18+
# Add a new document part that receives a relationship ID to a package
19+
20+
This topic shows how to use the classes in the Open XML SDK for
21+
Office to add a document part (file) that receives a relationship **Id** parameter for a word
22+
processing document.
23+
24+
25+
26+
-----------------------------------------------------------------------------
27+
## Packages and Document Parts
28+
An Open XML document is stored as a package, whose format is defined by
29+
[ISO/IEC 29500-2](https://www.iso.org/standard/71691.html). The
30+
package can have multiple parts with relationships between them. The
31+
relationship between parts controls the category of the document. A
32+
document can be defined as a word-processing document if its
33+
package-relationship item contains a relationship to a main document
34+
part. If its package-relationship item contains a relationship to a
35+
presentation part it can be defined as a presentation document. If its
36+
package-relationship item contains a relationship to a workbook part, it
37+
is defined as a spreadsheet document. In this how-to topic, you will use
38+
a word-processing document package.
39+
40+
41+
-----------------------------------------------------------------------------
42+
43+
[!include[Structure](../includes/word/structure.md)]
44+
45+
-----------------------------------------------------------------------------
46+
## Sample Code
47+
The following code, adds a new document part that contains custom XML
48+
from an external file and then populates the document part. You can call
49+
the method **AddNewPart** by using a call like
50+
the following code example.
51+
52+
### [C#](#tab/cs-0)
53+
```csharp
54+
string document = @"C:\Users\Public\Documents\MyPkg1.docx";
55+
AddNewPart(document);
56+
```
57+
58+
### [Visual Basic](#tab/vb-0)
59+
```vb
60+
Dim document As String = "C:\Users\Public\Documents\MyPkg1.docx"
61+
AddNewPart(document)
62+
```
63+
***
64+
65+
66+
The following is the complete code example in both C\# and Visual Basic.
67+
68+
### [C#](#tab/cs)
69+
[!code-csharp[](../../samples/word/add_a_new_part_that_receives_a_relationship_id_to_a_package/cs/Program.cs)]
70+
71+
### [Visual Basic](#tab/vb)
72+
[!code-vb[](../../samples/word/add_a_new_part_that_receives_a_relationship_id_to_a_package/vb/Program.vb)]
73+
74+
-----------------------------------------------------------------------------
75+
## See also
76+
77+
78+
- [Open XML SDK class library reference](/office/open-xml/open-xml-sdk)
79+
80+
81+

0 commit comments

Comments
 (0)