Share via


Características del SDK personalizado

Las características del SDK de Open XML están disponibles a partir de la versión 2.14.0 que permite que el comportamiento y el estado se contengan en el documento o parte y se personalicen sin volver a implementar el paquete o elemento contenedor. Se obtiene acceso a ella a través Features de la propiedad en paquetes, elementos y elementos.

Se trata de una implementación del patrón de estrategia que facilita la sustitución del comportamiento sobre la marcha. Se modela después de las características de solicitud en ASP.NET Core.

Herencia de características

Los paquetes, elementos y elementos tienen su propia colección de características. Sin embargo, también heredarán la parte contenedora y el paquete si está disponible.

Para resaltar esto, consulte el siguiente caso de prueba:

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
{
}

Nota:

La colección de características de los elementos es de solo lectura. Esto se debe a problemas de memoria si se puede escribir. Si es necesario, póngase en https://github.com/dotnet/open-xml-sdk contacto con nosotros para comunicarnos su escenario.

Visualización de características registradas

Las implementaciones integradas de IFeatureCollection proporcionan una vista de depuración útil para que pueda ver qué características están disponibles y cuáles son sus propiedades o campos:

Vista de depuración de características

Características disponibles

Las características que están disponibles actualmente se describen a continuación y en qué ámbito están disponibles:

IDisposableFeature

Esta característica permite registrar acciones que deben ejecutarse cuando se destruye o elimina un paquete o una parte:

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 */);

Los paquetes y partes tendrán sus propias implementaciones de esta característica. Los elementos recuperarán la característica de su elemento contenedor si están disponibles.

IPackageEventsFeature

Esta característica permite obtener notificaciones de eventos de cuando se cambia un paquete:

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

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

Nota:

Puede haber ocasiones en las que se cambia el paquete, pero no se desencadena un evento. No se han identificado todas las áreas en las que tendría sentido generar un evento. Si encuentra uno, envíe un problema.

IPartEventsFeature

Esta característica permite obtener notificaciones de eventos de cuándo se crea un evento. Se trata de una característica que se agrega al elemento o paquete:

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

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

Por lo general, suponga que puede haber una implementación singleton para los eventos y compruebe que la parte es la parte correcta.

Nota:

Puede haber ocasiones en las que se cambia la parte, pero no se desencadena un evento. No se han identificado todas las áreas en las que tendría sentido generar un evento. Si encuentra uno, envíe un problema.

IPartRootEventsFeature

Esta característica permite obtener notificaciones de eventos de cuando se modifica, carga, crea o modifica una raíz de parte, etc. Se trata de una característica que se agrega a la característica de nivel de pieza:

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

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

Por lo general, suponga que puede haber una implementación singleton para los eventos y compruebe que la parte es la parte correcta.

Nota:

Puede haber ocasiones en las que se cambia la raíz de la parte, pero no se desencadena un evento. No se han identificado todas las áreas en las que tendría sentido generar un evento. Si encuentra uno, envíe un problema.

IRandomNumberGeneratorFeature

Esta característica permite que un servicio compartido genere números aleatorios y rellene una matriz.

IParagraphIdGeneratorFeature

Esta característica permite rellenar y realizar un seguimiento de los elementos que contienen identificadores de párrafo. De forma predeterminada, esto garantizará la unicidad de los valores y garantizará que los valores que existen sean válidos según las restricciones del estándar. Para usar esta característica:

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

Esta característica también se puede usar para garantizar la unicidad entre varios documentos con un ligero cambio:

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);

IPartRootXElementFeature

Esta característica permite trabajar en mediante OpenXmlPart características XLinq y manipular XElement nodos directamente.

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);

Esto XElement se almacena en caché, pero se mantendrá sincronizado con el elemento subyacente si cambiara.