Share via


Trabajar con la tabla de cadena compartida

En este tema se describe la clase SharedStringTable del SDK 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 elemento SharedStringTable (<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/IEC29500: 2008.

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 Texto

Clase SharedStringTable del SDK de Open XML

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

Clase SharedStringItem

La clase SharedStringItem 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 "Cell" 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 elementos RichTextRun (<r>) y RunProperties (<rPr>). Para conservar el espacio en blanco entre el texto con formato diferente, el atributo space del elemento text (<t>) se establece igual que para conservarse. 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 clase Text 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 siguiente código toma un String y un SharedStringTablePart 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 clase SharedStringTable para insertar texto mediante programación en una celda, vea How to: Insert text into a cell in a spreadsheet document.

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

// Given text and a SharedStringTablePart, creates a SharedStringItem with the specified text 
// and inserts it into the SharedStringTablePart. If the item already exists, returns its index.
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)));
    shareStringPart.SharedStringTable.Save();

    return i;
}