Содержание
Класс WordprocessingDocumentсодержится в пространстве имен DocumentFormat.OpenXml.Packaging и является основным классом для работы с документами Word. Именно его работа направлена на создание файла Word, как единого документа со структурой, о которой мы говорили в предыдущей части. В этой части мы более подробно рассмотрим работу с методами WordprocessingDocument.
Структура документа Word
Как мы уже знаем, базовая структура документа Word состоит из элементов <document> и <body>, за которыми следуют один или несколько элементов блочного уровня, таких как <p>, представляющий собой абзац. Абзац содержит один или несколько элементов <r> . Элемент <r> обозначает фрагмент текста с общим набором свойств. Фрагмент <r> содержит один или несколько элементов <t>. Элемент <t>содержит фрагмент текста. Библиотека DocumentFormat.OpenXml предоставляет нам строго типизированные классы в пространстве имён DocumentFormat.OpenXML.WordprocessingML, которые соответствуют элементам Word.
В таблице ниже перечислены некоторые важные элементы документа Word, как части пакета WordprocessingML.
| Часть пакета | Элемент в документе | Класс | Описание |
|---|---|---|---|
Main Document |
document |
Document |
Корневой элемент основной части документа. |
Comments |
comments |
Comments |
Корневой элемент раздела комментариев. |
Document Settings |
settings |
Settings |
Корневой элемент раздела настроек документа. |
Endnotes |
endnotes |
Endnotes |
Корневой элемент раздела концевых сносок. |
Footer |
ftr |
Footer |
Корневой элемент раздела нижнего колонтитула. |
Footnotes |
footnotes |
Footnotes |
Корневой элемент раздела сносок. |
Glossary Document |
glossaryDocument |
GlossaryDocument |
Корневой элемент раздела глоссария. |
Header |
hdr |
Header |
Корневой элемент раздела заголовка. |
Style Definitions |
styles |
Styles |
Корневой элемент раздела определений стилей |
Документа Word организован вокруг концепции «историй» (story). История (story) — это область содержимого в документе. Истории в документе Word включают в себя:
- Комментарии
- Концевые сноски
- Нижний колонтитул
- Сноски
- Рамки, глоссарий документа
- Заголовки
- Основная история
- Вложенные документы
- Текстовые поля
При этом не все эти элементы обязаны присутствовать в документе. Самый простой корректный документ содержит только одну историю — основную историю документа, которая представлена элементом типа MainDocumentPart. Самый простой текстовый документ Word мы создали в прошлой части. Теперь рассмотрим более подробно работу с классом WordprocessingDocument , который и отвечает за создание корректной структуры документа.
Методы создания документа Word
Класс WordprocessingDocument содержит ряд статических методов для создания нового документа Word. Ниже представлены основные из них:
| Метод | Описание |
public static WordprocessingDocument Create(Stream stream, WordprocessingDocumentType type); |
Создает новый документ Word используя для этого поток stream. Параметр type определяет тип создаваемого документа и может принимать следующие значения:
|
public static WordprocessingDocument Create(string path, WordprocessingDocumentType type); |
Создает документ Word из файла, расположенного по пути path. |
public static WordprocessingDocument Create(Stream stream, WordprocessingDocumentType type, bool autoSave); |
Создает новый документ Word используя для этого поток stream. Параметр autoSave определяет будет ли создаваемый документ автоматически сохраняться |
public static WordprocessingDocument Create(string path, WordprocessingDocumentType type, bool autoSave); |
Создает документ Word из файла, расположенного по пути path. Параметр autoSave определяет будет ли создаваемый документ автоматически сохраняться |
По умолчанию, новый документ Word сохраняется автоматически. Чтобы убедиться в этом, достаточно посмотреть на исходный код приложения из предыдущей части — там мы не использовали никаких методов сохранения документа, а для создания документа воспользовались методом Create() с двумя параметрами. Продемонстрируем работу по созданию документа Word с использованием потока Stream.
using Stream stream = new FileStream("hello.docx", FileMode.OpenOrCreate);
using WordprocessingDocument doc = WordprocessingDocument.Create(stream, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart mainPart = doc.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text("Hello World"));
Также стоит отметить, что WordprocessingDocument позволяет создавать новые документа на основании шаблона. Для этого используются методы
public static WordprocessingDocument CreateFromTemplate(string path);
или
public static WordprocessingDocument CreateFromTemplate(string path, bool isTemplateAttached);
В параметре path, при этом, указывается путь к шаблону документа, а сам новый документ создается в потоке MemoryStream.
Методы открытия существующего документа Word
Аналогично тому, как мы создаем новый документ Word, у WordprocessingDocument имеется ряд статических методов для открытия уже существующего документа Word:
| Метод | Описание |
public static WordprocessingDocument Open(string path, bool isEditable, OpenSettings openSettings); |
Открывает документ Word расположенный по пути path. Для того, чтобы редактировать содержимое документа, необходимо установить параметр isEditable в значение true. Объект типа OpenSettings содержит дополнительные настройки открытия документа, такие как автосохранение изменений в документе, режим совместимости и т.д. |
public static WordprocessingDocument Open(Stream stream, bool isEditable, OpenSettings openSettings); |
Аналогично предыдущей версии метода открывает документ Word, при этом, данные документа должны быть предварительно загружены в поток stream. |
public static WordprocessingDocument Open(string path, bool isEditable); |
Открывает документ Word расположенный по пути path. |
public static WordprocessingDocument Open(Stream stream, bool isEditable);
|
Открывает документ Word, при этом, данные документа должны быть предварительно загружены в поток stream |
В первых двух версиях метода Open() используется объект типа OpenSettings. Это довольно простой класс, который содержит следующие свойства:
| Свойство | Тип | Описание |
AutoSave |
bool |
Указывает, следует ли автоматически сохранять изменения в документе. Значение по умолчанию — true. |
CompatibilityLevel |
CompatibilityLevel |
Версия Open XML для обеспечения совместимости. Может принимать следующие значения:
|
MarkupCompatibilityProcessSettings |
MarkupCompatibilityProcessSettings |
Представляет собой объект с настройками совместимости разметки и может использоваться для указания сохранения документа в форматах Office 2007, Office 2021, Microsoft365 и т.д. |
MaxCharactersInPart |
long |
Значение, указывающее максимальное количество допустимых символов в части Open XML. Нулевое (0) значение указывает на отсутствие ограничений на размер части. Ненулевое значение указывает максимальный размер в символах |
После того, как м откроем документ методом Open() мы можем его либо просто прочитать, либо внести в него изменения. Но, опять же, чтобы внести какие-либо изменения в документ мы должны знать структуру документа. Например, откроем файл, созданный в предыдущем примере и добавим в него ещё один абзац текста:
private static void AddTextToWord(string text)
{
using WordprocessingDocument doc = WordprocessingDocument.Open("hello.docx", true);
MainDocumentPart main = doc.MainDocumentPart ?? doc.AddMainDocumentPart();
Body body = main.Document.Body ?? main.Document.AppendChild(new Body());
Paragraph paragraph = body.AppendChild(new Paragraph());
paragraph.AppendChild(new Run(new Text(text)));
}
В этом примере мы, опять же, последовательно выполнили следующие операции:
- Создали объект
WordprocessingDocumentиз файла - Получили объект главной истории в документе
- Получили основной контейнер элементов документа (тело)
- Добавили новый параграф в конец документа.
При этом, так как файл может быть пустым, то мы проверяем наличие той или иной части в документе и, при необходимости, создаем её. Например:
MainDocumentPart main = doc.MainDocumentPart ?? doc.AddMainDocumentPart();
В результате, мы получим документ как показано на рисунке:
Итого
В этой части мы познакомились со структурой документа Word, а также изучили методы создания объекта класса WordprocessingDocument — основного объекта для работы с документами Word. Используя эти методы, мы можем открывать или создавать файлы Word, используя физическое расположение файла, работать с файлами в потоке (Stream) или создавать новые файлы на основе шаблона.
