Работа с таблицей общих строк
В этом разделе рассматривается класс Open XML SDK SharedStringTable и его связь со схемой SpreadsheetML формата файла Open XML. Дополнительные сведения об общей структуре частей и элементов, составляющих документ SpreadsheetML, см. в разделе Структура документа SpreadsheetML.
Элемент SharedStringTable в документе SpreadsheetML
В следующей информации из спецификации ISO/IEC 29500 представлен SharedStringTable
элемент (<sst/>
).
Экземпляр части этого типа содержит один экземпляр каждой уникальной строки со всех листов книги.
Пакет содержит ровно одну часть общей строковой книги
Корневой элемент части такого типа контента sst.
Книга может содержать тысячи ячеек со строковыми (не числовыми) данными. Кроме того, весьма вероятно, эти данные будут повторяться во многих строках или столбцах. Преимущество единой общей строковой таблицы состоит в том, что она повышает производительность книги при открытии и сохранении файла, позволяя читать и записывать данные только один раз.
© ISO/IEC 29500: 2016
Общие строки снижают требования к хранилищу, если электронная таблица содержит множество экземпляров одной строки. Электронные таблицы с бизнес-данными или аналитическими данными часто содержат повторяющиеся строки. Если бы они хранились в разметке, в листе повторялась одна и та же разметка. Хотя этот подход имеет право на жизнь, у него есть несколько недостатков. Во-первых, для хранения файла требуется больше места из-за избыточного контента. Кроме того, для загрузки и сохранения необходимо больше времени.
Чтобы оптимизировать использование строк в электронной таблице, в SpreadsheetML хранится один экземпляр всех строк общая строковая таблица. Ячейки ссылаются на строку по индексу, а не содержат само строковое значение. Excel всегда создает общую строковую таблицу при сохранении файла. Однако она необязательна для создания допустимого файла SpreadsheetML. Если вы создаете электронную таблицу программно и она содержит несколько строк или не содержит повторяющиеся строки, эффективность общей строковой таблицы не ощутима.
Общая строковая таблица это отдельная часть пакета. Каждая книга содержит только одну такую таблицу со строками, которые могут быть повторяться много раз на одном или нескольких листах.
В следующей таблице перечислены распространенные классы пакета SDK Open XML, используемые при работе с классом SharedStringTable.
Элемент SpreadsheetML | Класс пакета SDK Open XML |
---|---|
<si/> |
SharedStringItem |
<t/> |
Text |
Класс SharedStringTable пакета SDK Open XML
Класс Open XML SDK SharedStringTable
представляет элемент абзаца (<sst/>
), определенный в схеме формата файлов Open XML для документов SpreadsheetML.
Используйте класс для SharedStringTable
управления отдельными <sst/>
элементами в документе SpreadsheetML.
Класс SharedStringItem
Класс SharedStringItem
представляет элемент общей строки (<si/>
), который представляет отдельную строку в общей строковой таблице.
Если строковое значение это сложная строка, к которой на уровне ячейке применено форматирования, общий строковый элемент содержит один текстовый элемент, используемый для обозначения строки. Но если строка в ячейке более сложная, например с форматированием на уровне символа, строковый элемент состоит из нескольких форматированных прогонов, которые вместе выражают строку.
Например, приведенный ниже XML-код — это общая строковая таблица для листа, которая содержит текст, отформатированный на уровнях ячеек и символов. Первые три строки ("Cell A1", "Cell B1" и "My Cell") содержатся в ячейках с форматированием на уровне ячеек. При этом в общей строковой таблице хранится только текст. Следующие две строки ("Cell A2" и "Cell B2") содержат форматирование на уровне символов. Слово "Ячейка" отформатировано иначе, чем "A2" и "B2", поэтому форматирование ячеек сохраняется вместе с текстом в общем строковом элементе с помощью RichTextRun
элементов (<r/>
) и RunProperties
(<rPr/>
). Чтобы сохранить пробел между текстом, отформатированным по-разному, space
атрибут элемента (<t/>
) имеет значение preserve
text
. Дополнительные сведения об элементах прогонов с форматированием и их свойствах см. в спецификации 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>
Класс Text
Класс Text
представляет элемент text (<t/>
), который представляет текстовое содержимое, отображаемое как часть строки.
Пример кода Open XML SDK
Следующий код принимает String
и SharedStringTablePart
и проверяет, существует ли указанный текст в общей строковой таблице. Если текста нет, он добавляется как общий строковый элемент в общую строковую таблицу.
Дополнительные сведения об использовании SharedStringTable
класса для программной вставки текста в ячейку см. в статье Практическое руководство. Вставка текста в ячейку в документе электронной таблицы.
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;
}