Содержание
Стиль — это предопределенный набор свойств таблиц, нумерации, абзацев и (или) символов, которые могут применяться к отдельным частям в документе. В предыдущих частях мы работали со свойствами абзацев и текстовых блоков, но, при этом, не затрагивали такой вопрос как Работа со стилями абзацев, например, мы меняли цвет текста или меняли отступы в абзаце, но даже не пытались изменить стиль, например, установить стиль текста «Заголовок 1». Для работы со стилями отдельных частей документа используется класс Style и в этой части мы познакомимся с ним при работе с текстом в Open XML.
Работа со стилями в документе Word
Если вы ранее работали с COM-объектами Word, например, используя Microsoft.Office.Interop.Word, то наверняка знаете, что при такой работе нам достаточно вызвать всего один метод, указав качестве параметра идентификатор стиля, чтобы он был применен к абзацу. При этом, от нас не требуется работа со созданию этого стиля. В Open XML дело обстоит несколько иначе. Так как при работе с Open XML мы не запускаем процесс Word, а фактически, создаем новый документ с нуля, то и работаем мы только с тем, что есть в документе. Если мы не создали и не добавили в документ стиль, то его невозможно применить так же просто как при работе Microsoft.Office.Interop. Поэтому, работа со стилями в Open XML строится по следующему алгоритму:
- Создаем необходимый стиль
- Добавляем стиль в документ
- Используем стиль в любых частях документа, где он доступен.
Рассмотрим этот алгоритм подробно.
Создание нового стиля в Open XML (класс Style)
Класс Style в Open XML задает определение одного стиля в документе Word. Определение стиля можно разделить на три части:
- Задание общих свойств стиля
- Определение типа стиля
- Определение свойств, относящиеся к типу стиля
Общие свойства стиля относятся к набору свойств, которые можно использовать независимо от его типа стиля, например, к общим свойствам стиля в Open XML относятся имя стиля, дополнительные псевдонимы, идентификатор стиля, признаки того, что стиль скрыт, или заблокирован и т. д.
Что касается свойств, относящихся к типы стиля, то набор этих свойств напрямую зависит от типа стиля. Например, если мы создаем стиль для абзаца, то нам становятся доступными свойства абзаца (ParagraphProperties) и свойства отдельных частей текста (RunProperties).
Open XML поддерживает шесть типов определений стилей по значениям атрибута типа определения стиля:
- Стили абзацев
- Стили символов
- Связанные стили (абзац + символ)
- Стили таблиц
- Стили нумерации
- Свойства абзаца и символа по умолчанию
Теперь рассмотрим свойства класса Style.
| Свойство | Тип | Описание |
Aliases |
Aliases? |
Задает набор альтернативных имен (алиасов, псевдонимов) для определения стиля. Эти имена можно использовать в пользовательском интерфейсе приложения по мере необходимости. Альтернативные имена должны храниться в свойстве Val этого элемента и разделяться запятыми. Все присутствующие запятые интерпретируются как символ-разделитель, а не как часть альтернативного имени стиля. |
AutoRedefine |
AutoRedefine? |
Автоматическое слияние пользовательского форматирования с определением стиля. Пример использования этого свойства представлен ниже. |
BasedOn |
BasedOn? |
Задает идентификатор родительского стиля, от которого наследуется текущий стиль |
CustomStyle |
OnOffValue? |
Указывает, что этот стиль пользовательский |
Default |
OnOffValue? |
Указывает, что этот стиль является стилем по умолчанию |
Locked |
Locked? |
Указывает, должно ли приложение запретить использование этого стиля при загрузке и(или) изменении документа |
NextParagraphStyle |
NextParagraphStyle? |
Этот элемент задает стиль, который автоматически применяется к новому абзацу, созданному после абзаца с этим стилем. |
PrimaryStyle |
PrimaryStyle? |
Указывает, должен ли этот стиль рассматриваться как основной при загрузке этого документа приложением. |
SemiHidden |
SemiHidden? |
Указывает, должен ли этот стиль быть скрыт в пользовательском интерфейсе при загрузке документа. При этом, мы можем использовать стиль для работы |
StyleHidden |
StyleHidden? |
Указывает, должен ли этот стиль быть полностью скрыт из пользовательского интерфейса |
StyleId |
StringValue? |
Задает идентификатор стиля, который используется при создании документа |
StyleName |
StyleName? |
Задает имя стиля, которое отображается в пользовательском интерфейсе |
StyleParagraphProperties |
StyleParagraphProperties? |
Набор свойств абзаца |
StyleRunProperties |
StyleRunProperties? |
Набор свойств текста |
StyleTableCellProperties |
StyleTableCellProperties? |
Набор свойств ячейки таблицы |
StyleTableProperties |
StyleTableProperties? |
Набор свойств таблицы |
Type |
EnumValue<StyleValues>? |
Тип стиля |
UIPriority |
UIPriority? |
Задает число, которое можно использовать для сортировки набора стилей в пользовательском интерфейсе при загрузке этого документа приложением |
UnhideWhenUsed |
UnhideWhenUsed? |
Указывает, должно ли удаляться свойство SemiHidden, если этот стиль используется содержимым документа |
Итак, свойства отдельного стиля рассмотрели. Теперь мы можем создать в нашем приложении новый стиль. Чтобы иметь возможность использовать стиль в документе, его необходимо добавить в часть типа StyleDefinitionsPart, которая, в свою очередь добавляется в основную часть документа.
Продемонстрируем работу со стилями на примере. Создадим консольное приложение C#, установим пакет для работы с Open XML (DocumentFormat.OpenXml) и напишем следующий код:
static void Main(string[] args)
{
//создаем новый документ Word
using WordprocessingDocument doc = WordprocessingDocument.Create("hello.docx", WordprocessingDocumentType.Document);
//задаем главную часть документа
MainDocumentPart mainPart = doc.AddMainDocumentPart();
//создаем документ
mainPart.Document = new Document();
//создаем тело документа
Body body = mainPart.Document.AppendChild(new Body());
//добавляем первый параграф
Paragraph para = body.AppendChild(new Paragraph(
new Run(
//в этой строке будут сохраняться начальные и конечные пробелы
new Text("Это строка первого абзаца"))
)
);
//добавляем второй параграф
Paragraph paragraph = body.AppendChild(new Paragraph(
new Run(new Text("Этот строка второго абзаца написана красным цветом"))
{
RunProperties = new RunProperties()
{
Color = new Color() { Val = "ff0000" }
}
})
);
//создаем новый стиль для параграфа
Style style = new Style()
{
Type = StyleValues.Paragraph, //указываем тип
StyleId = "myHeading1",//указываем идентификатор стиля
StyleName = new StyleName() { Val = "Мой заголовок" }, //задаем имя стиля
//задаем настройки стиля
StyleRunProperties = new StyleRunProperties()
{
Bold = new Bold(),
FontSize = new FontSize() {Val = "36" },
}
};
var styles = new Styles();
styles.Append(style);
mainPart.AddNewPart<StyleDefinitionsPart>();
mainPart.StyleDefinitionsPart.Styles = styles;
//устанавливаем стиль для первого абзаца
para.ParagraphProperties = new ParagraphProperties()
{
ParagraphStyleId = new ParagraphStyleId() { Val= "myHeading1" }
};
//устанавливаем стиль для второго абзаца
paragraph.ParagraphProperties = new ParagraphProperties()
{
ParagraphStyleId = new ParagraphStyleId() { Val = "myHeading1" }
};
}
Здесь мы создаем два абзаца текста и стиль с идентификатором myHeading1, после чего применяем стиль к обоим абзацам. Рассмотрим подробно часть когда, относящуюся к работе со стилями. Вначале мы создаем отдельный стиль — объект типа Style:
Style style = new Style()
{
Type = StyleValues.Paragraph, //указываем тип
StyleId = "myHeading1",//указываем идентификатор стиля
StyleName = new StyleName() { Val = "Мой заголовок" }, //задаем имя стиля
//задаем настройки стиля
StyleRunProperties = new StyleRunProperties()
{
Bold = new Bold(),
FontSize = new FontSize() {Val = "36" },
}
};
Вначале мы задаем тип стили — StyleValues.Paragraph (стиль применяется к абзацу). Далее мы задаем общие свойства стиля — его идентификатор и имя:
StyleId = "myHeading1",//указываем идентификатор стиля
StyleName = new StyleName() { Val = "Мой заголовок" }, //задаем имя стиля
Идентификатор используется внутри документа, имя — в приложении, в котором будет открыт наш документ. Далее мы задаем настройки текста в абзаце — жирность и размер шрифта:
StyleRunProperties = new StyleRunProperties()
{
Bold = new Bold(),
FontSize = new FontSize() {Val = "36" },
}
После того, как объект стиля создан, мы должны добавить его в документ. Для этого мы создаем коллекцию стилей, в которую добавляем наш объект, далее создаем новую часть документа для хранения стилей и назначаем созданную коллекцию свойству Styles новой части документа:
var styles = new Styles(); styles.Append(style); mainPart.AddNewPart<StyleDefinitionsPart>(); mainPart.StyleDefinitionsPart.Styles = styles;
Теперь наш стиль может использоваться в документе. Чтобы применить стиль к абзацу, мы указываем его идентификатор в свойстве ParagraphStyleId настроек абзаца.
para.ParagraphProperties = new ParagraphProperties()
{
ParagraphStyleId = new ParagraphStyleId() { Val= "myHeading1" }
};
//устанавливаем стиль для второго абзаца
paragraph.ParagraphProperties = new ParagraphProperties()
{
ParagraphStyleId = new ParagraphStyleId() { Val = "myHeading1" }
};
Запустим приложение и посмотрим на результат:
Обратите внимание на то, что во втором абзаце текст так и остался красного цвета. Как говорилось ранее, прямое форматирование применяется в Open XML в последнюю очередь. То есть, вначале был применен стиль и текст второго абзаца получил жирность и свой размер, а затем — был применен красный цвет текста.
Теперь вернемся к свойствам Style и посмотрим на работу свойства AutoRedefine . Включение этого свойства приводит к тому, что мы можем автоматически менять стиль всех абзацев. Добавим это свойство к нашему стилю:
Style style = new Style()
{
Type = StyleValues.Paragraph, //указываем тип
StyleId = "myHeading1",//указываем идентификатор стиля
StyleName = new StyleName() { Val = "Мой заголовок" }, //задаем имя стиля
AutoRedefine = new AutoRedefine() { Val=OnOffOnlyValues.On},
//задаем настройки стиля
StyleRunProperties = new StyleRunProperties()
{
Bold = new Bold(),
FontSize = new FontSize() {Val = "36" },
}
};
Теперь снова запустите приложение, чтобы создать документ, а затем откройте полученный файл Word и измените любое свойство текста в первом абзаце. Как только меняется настройка текста в одном из абзацев — эта настройка сразу же применяется к стилю и все абзацы с этим стилем меняют свой внешний вид:
Походим образом мы можем настраивать и другие типы стилей в Open XML. Однако, остается ещё один момент работы с текстом в Open XML, который стоит рассмотреть, а именно: как изменить шрифт текста?
Как в Open XML изменить шрифт?
Далеко не всегда и всем подходит использование шрифта по умолчанию для темы того же MS Word. Меняются версии Office, меняются темы оформления, а с ними и шрифты по умолчанию. Так, долгое время основным шрифтом в Word был Calibri, сейчас Aptos, что будет завтра — знаеют только разработчики Microsoft. Нам же может потребоваться использовать другой шрифт в документе, например, Arial. Сделать это можно, используя свойство RunFonts для настроек текста в стиле.
Класс RunFonts предоставляет нам следующие свойства (в таблице перечислены основные свойства):
| Свойство | Тип | Описание |
Ascii |
StringValue? |
Шрифт для символов, относящихся к типу ASCII. |
AsciiTheme |
ThemeFontValues>? |
Шрифт темы для символов, относящихся к типу ASCII. |
HighAnsi |
StringValue? |
Шрифт для документов с символами, не являющимися ASCII. |
HighAnsiTheme |
ThemeFontValues>? |
Шрифт темы для документов с символами, не являющимися ASCII. |
В тексте могут использоваться различные символы, например, часть строки может быть на английском, часть на русском, а часть — вообще на китайском. И мы можем задать свои шрифты для каждой группы символов. Например, изменим наш стиль следующим образом:
Style style = new Style()
{
Type = StyleValues.Paragraph, //указываем тип
StyleId = "myHeading1",//указываем идентификатор стиля
StyleName = new StyleName() { Val = "Мой заголовок" }, //задаем имя стиля
AutoRedefine = new AutoRedefine() { Val=OnOffOnlyValues.On},
//задаем настройки стиля
StyleRunProperties = new StyleRunProperties()
{
Bold = new Bold(),
FontSize = new FontSize() {Val = "36" },
RunFonts = new RunFonts() { HighAnsi="Arial", Ascii="Times New Roman"}
}
};
Здесь мы определили два шрифта — для ASCII- символов и не ASCII. Теперь изменим первый абзац текста, добавив в него строку на английском языке:
Paragraph para = body.AppendChild(new Paragraph(
new Run(
//в этой строке будут сохраняться начальные и конечные пробелы
new Text("Это строка первого абзаца содержит строку Hello World"))
)
);
Запустим приложение, чтобы убедиться, что, в соответствии с нашим стилем, все английские символы написаны шрифтом Times New Roman, а русские — используют Arial.
Итого
В этой части мы познакомились с тем, как работать со стилями оформления документа в Open XML, на примере создания стиля абзаца текста. Стили в Open XML добавляются в часть StyleDefinitionsPart как коллекция объектов типа Style. Каждый стиль имеет свое имя, тип, идентификатор, а также настройки, относящиеся к конкретному объекту в документе (абзацу, ячейке таблице и т.д.)
