Пользовательские функции пакета SDK
Функции пакета SDK Open XML доступны начиная с версии 2.14.0, что позволяет содержать поведение и состояние в документе или части и настраивать их без повторного выполнения содержащего пакета или части. Доступ к этому объекту осуществляется через Features
свойство в пакетах, частях и элементах.
Это реализация шаблона стратегии , которая позволяет легко заменить поведение на лету. Он смоделирован по функциям запроса в ASP.NET Core.
Наследование компонентов
Пакеты, части и элементы имеют собственную коллекцию компонентов. Однако они также наследуют содержащую часть и пакет, если они доступны.
Чтобы выделить это, ознакомьтесь с тестовой ситуацией ниже.
OpenXmlPackage package = /* Create a package */;
var packageFeature = new PrivateFeature();
package.Features.Set<PrivateFeature>(packageFeature);
var part = package.GetPartById("existingPart");
Assert.Same(part.Features.GetRequired<PrivateFeature>(), package.Features.GetRequired<PrivateFeature>());
part.Features.Set<PrivateFeature>(new());
Assert.NotSame(part.Features.GetRequired<PrivateFeature>(), package.Features.GetRequired<PrivateFeature>());
private sealed class PrivateFeature
{
}
Примечание.
Коллекция признаков элементов доступна только для чтения. Это связано с проблемами с памятью, если она становится доступной для записи. Если это необходимо, обратитесь https://github.com/dotnet/open-xml-sdk к нам, чтобы сообщить нам о вашем сценарии.
Визуализация зарегистрированных компонентов
Встроенные реализации предоставляют полезное представление отладки IFeatureCollection , чтобы вы могли видеть доступные функции и их свойства или поля:
Доступные функции
Доступные в настоящее время функции описаны ниже и на каком область они доступны:
IDisposableFeature
Эта функция позволяет регистрировать действия, которые должны выполняться при уничтожении или удалении пакета или части:
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 */);
Пакеты и части будут иметь собственные реализации этой функции. Элементы будут извлекать функцию для их содержащей части, если она доступна.
IPackageEventsFeature
Эта функция позволяет получать уведомления о событиях при изменении пакета:
OpenXmlPackage package = GetSomePackage();
package.TryAddPackageEventsFeature();
var feature = package.Features.GetRequired<IPackageEventsFeature>();
Примечание.
Иногда пакет изменяется, но событие не запускается. Не все области были определены, где было бы целесообразно поднять событие. Если вы нашли проблему, сообщите о проблеме.
IPartEventsFeature
Эта функция позволяет получать уведомления о событиях при создании события. Это функция, которая добавляется в часть или пакет:
OpenXmlPart part = GetSomePackage();
package.AddPartEventsFeature();
var feature = part.Features.GetRequired<IPartEventsFeature>();
Как правило, предполагается, что для событий может существовать одноэлементная реализация, и убедитесь, что часть является правильной.
Примечание.
Иногда часть изменяется, но событие не запускается. Не все области были определены, где было бы целесообразно поднять событие. Если вы нашли проблему, сообщите о проблеме.
IPartRootEventsFeature
Эта функция позволяет получать уведомления о событиях, когда корневой каталог части изменяется, загружается, создается и т. д. Это функция, которая добавляется в компонент уровня части:
OpenXmlPart part = GetSomePart();
part.AddPartRootEventsFeature();
var feature = part.Features.GetRequired<IPartRootEventsFeature>();
Как правило, предполагается, что для событий может существовать одноэлементная реализация, и убедитесь, что часть является правильной.
Примечание.
Иногда корень части изменяется, но событие не запускается. Не все области были определены, где было бы целесообразно поднять событие. Если вы нашли проблему, сообщите о проблеме.
IRandomNumberGeneratorFeature
Эта функция позволяет общей службе создавать случайные числа и заполнять массив.
IParagraphIdGeneratorFeature
Эта функция позволяет выполнять заполнение и отслеживание элементов, содержащих идентификаторы абзаца. По умолчанию это обеспечит уникальность значений и обеспечит допустимость существующих значений в рамках ограничений стандарта. Чтобы использовать эту функцию, выполните следующие действия:
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
Эту функцию также можно использовать для обеспечения уникальности нескольких документов с незначительным изменением:
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);