Compartir a través de


Trabajar con la tabla de cadena compartida

En este tema se describe la clase SDK SharedStringTable de Open XML y cómo se relaciona con el esquema SpreadsheetML de formato de archivo Open XML. Para obtener más información sobre la estructura general de los elementos y elementos que componen un documento SpreadsheetML, vea Estructura de un documento SpreadsheetML.


SharedStringTable en SpreadsheetML

La siguiente información de la especificación ISO/IEC 29500 presenta el SharedStringTable elemento (<sst/>).

Una instancia de este tipo de parte contiene una repetición de cada cadena única que se produce en todas las hojas de cálculo de un libro.

Un paquete debe incluir exactamente una parte de tabla de cadenas compartidas.

El elemento raíz de una parte de este tipo de contenido debe ser sst.

Un libro puede incluir miles de celdas que contienen datos de cadena (no numéricos). Además, es muy probable que estos datos se repitan en muchas filas o columnas. El objetivo de la implementación de una sola tabla de cadenas que se comparta en todo el libro consiste en mejorar el rendimiento al abrir y guardar el archivo mediante la lectura y escritura de la información repetida una sola vez.

© ISO/IEC 29500: 2016

Las cadenas compartidas optimizan los requisitos de espacio cuando la hoja de cálculo contiene varias instancias de la misma cadena. Las hojas de cálculo que contienen datos analíticos o profesionales a menudo contienen cadenas repetidas. Si estas cadenas se almacenaran con el formato de cadena en línea, aparecería el mismo marcado una y otra vez en la hoja de cálculo. Si bien es un enfoque válido, tiene varias desventajas. En primer lugar, el archivo requiere más espacio en disco debido al contenido redundante. Por otra parte, las tareas de cargar y guardar también tomarán más tiempo.

Para optimizar el uso de las cadenas en una hoja de cálculo, SpreadsheetML almacena una sola instancia de la cadena en una tabla, denominada tabla de cadenas compartidas. Las celdas hacen referencia a la cadena por su índice, en lugar de almacenar el valor en línea en el valor de celda. Excel siempre crea una tabla de cadenas compartidas cuando guarda un archivo. No obstante, no es necesario el uso de la tabla de cadenas compartidas para crear un archivo SpreadsheetML válido. Si crea un documento de hoja de cálculo mediante programación y la hoja de cálculo contiene un número reducido de cadenas o no contiene ninguna cadena repetida, es posible que las optimizaciones que normalmente se obtienen de la tabla de cadenas compartidas sean insignificantes.

La tabla de cadenas compartidas es una parte independiente dentro del paquete. Cada libro contiene solo una parte de tabla de cadenas compartidas que incluye cadenas que pueden aparecer varias veces en una hoja o en varias hojas.

En la tabla siguiente se enumeran las clases comunes del SDK de Open XML que se usan al trabajar con la clase SharedStringTable.

Elemento de SpreadsheetML Open XML SDK (clase)
<si/> SharedStringItem
<t/> Text

Clase SharedStringTable del SDK de Open XML

La clase SDK SharedStringTable de Open XML representa el elemento de párrafo (<sst/>) definido en el esquema formato de archivo Open XML para documentos SpreadsheetML. Use la SharedStringTable clase para manipular elementos individuales <sst/> en un documento SpreadsheetML.

Clase SharedStringItem

La SharedStringItem clase representa el elemento de cadena compartida (<si/>) que representa una cadena individual en la tabla de cadenas compartidas.

Si la cadena es una cadena simple con formato aplicado en el nivel de celda, el elemento de cadena compartida incluirá un elemento de texto único usado para expresar la cadena. Sin embargo, si la cadena de la celda es más compleja, por ejemplo, si la cadena tiene formato aplicado en el nivel de carácter, el elemento de cadena constará de varios segmentos de texto enriquecido usados de forma colectiva para expresar la cadena.

Por ejemplo, el siguiente código XML es la tabla de cadenas compartidas de una hoja de cálculo que contiene texto con formato en el nivel de celda y en el nivel de carácter. Las tres primeras cadenas ("Cell A1", "Cell B1" y "My Cell") pertenecen a celdas con formato en el nivel de celda y solo el texto se almacena en la tabla de cadenas compartidas. Las dos cadenas siguientes ("Cell A2" y "Cell B2") contienen formato en el nivel de carácter. La palabra "Celda" tiene un formato diferente de "A2" y "B2", por lo que el formato de las celdas se almacena junto con el texto dentro del elemento de cadena compartida mediante los RichTextRun elementos (<r/>) y RunProperties (<rPr/>). Para conservar el espacio en blanco entre el texto con formato diferente, el space atributo del text elemento (<t/>) se establece en igual que preserve. Para obtener más información acerca de los elementos de propiedades de segmento y de segmento de texto enriquecido, vea la especificación ISO/IEC 29500.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="6" uniqueCount="5">
        <si>
            <t>Cell A1</t>
        </si>
        <si>
            <t>Cell B1</t>
        </si>
        <si>
            <t>My Cell</t>
        </si>
        <si>
            <r>
                <rPr>
                    <sz val="11"/>
                    <color rgb="FFFF0000"/>
                    <rFont val="Calibri"/>
                    <family val="2"/>
                    <scheme val="minor"/>
                </rPr>
                <t>Cell</t>
            </r>
            <r>
                <rPr>
                    <sz val="11"/>
                    <color theme="1"/>
                    <rFont val="Calibri"/>
                    <family val="2"/>
                    <scheme val="minor"/>
                </rPr>
                <t xml:space="preserve"> </t>
            </r>
            <r>
                <rPr>
                    <b/>
                    <sz val="11"/>
                    <color theme="1"/>
                    <rFont val="Calibri"/>
                    <family val="2"/>
                    <scheme val="minor"/>
                </rPr>
                <t>A2</t>
            </r>
        </si>
        <si>
            <r>
                <rPr>
                    <sz val="11"/>
                    <color rgb="FF00B0F0"/>
                    <rFont val="Calibri"/>
                    <family val="2"/>
                    <scheme val="minor"/>
                </rPr>
                <t>Cell</t>
            </r>
            <r>
                <rPr>
                    <sz val="11"/>
                    <color theme="1"/>
                    <rFont val="Calibri"/>
                    <family val="2"/>
                    <scheme val="minor"/>
                </rPr>
                <t xml:space="preserve"> </t>
            </r>
            <r>
                <rPr>
                    <i/>
                    <sz val="11"/>
                    <color theme="1"/>
                    <rFont val="Calibri"/>
                    <family val="2"/>
                    <scheme val="minor"/>
                </rPr>
                <t>B2</t>
            </r>
        </si>
    </sst>

Clase Text

La Text clase representa el elemento text (<t/>) que representa el contenido de texto que se muestra como parte de una cadena.

Ejemplo de código de Open XML SDK 2.0

El código siguiente toma y StringSharedStringTablePart y comprueba si el texto especificado existe en la tabla de cadenas compartidas. Si el texto no existe, se agrega como un elemento de cadena compartida a la tabla de cadenas compartidas.

Para obtener más información sobre cómo usar la SharedStringTable clase para insertar texto mediante programación en una celda, vea Cómo: Insertar texto en una celda de un documento de hoja de cálculo.

static int InsertSharedStringItem(string text, SharedStringTablePart shareStringPart)
{
    // If the part does not contain a SharedStringTable, create one.
    if (shareStringPart.SharedStringTable is null)
    {
        shareStringPart.SharedStringTable = new SharedStringTable();
    }

    int i = 0;

    // Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
    foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
    {
        if (item.InnerText == text)
        {
            return i;
        }

        i++;
    }

    // The text does not exist in the part. Create the SharedStringItem and return its index.
    shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));

    return i;
}