Поделиться через


Пользовательские функции пакета 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);