Работа с документами

Работа с документами

Aspose.Words FOSS for .NET представляет каждый файл Word в виде объектной модели в памяти, корневой класс — Document, при этом DocumentBuilder предоставляет высокоуровневый, основанный на курсоре API для создания контента. Это руководство охватывает создание и загрузку документов, авторинг с помощью DocumentBuilder, структуру разделов/тела, обход дерева узлов, объединение документов и их защиту.


Создание и загрузка документов

Создайте пустой документ с помощью new Document() или откройте существующий файл, передав путь или Stream в конструктор Document(fileName) или Document(stream). Перегрузки, принимающие аргумент LoadOptions, позволяют управлять поведением загрузки, например, указывая пароль для зашифрованного файла.

Перед загрузкой файла из неизвестного или ненадёжного источника FileFormatUtil.DetectFileFormat(fileName) (или перегрузка Stream) возвращает FileFormatInfo, описывающий обнаруженный LoadFormat, и то, IsEncrypted, HasDigitalSignature или HasMacros файл.


Создание контента с помощью DocumentBuilder

DocumentBuilder оборачивает Document и предоставляет курсор, которым вы перемещаетесь по документу, вставляя содержимое. Write(text) и Writeln(text) вставляют текст в позицию курсора; InsertParagraph() начинает новый абзац. Свойства форматирования в билдере — Font, ParagraphFormat, ListFormat, PageSetup — применяются к следующему записываемому материалу.

Перемещайте курсор с помощью MoveToDocumentStart(), MoveToDocumentEnd(), MoveToSection(sectionIndex), MoveToBookmark(bookmarkName) или MoveToParagraph(paragraphIndex, characterIndex). Свойства CurrentNode, CurrentParagraph и CurrentSection билдера сообщают его текущую позицию в дереве.


Структура документа: разделы и тело

Document содержит SectionCollection (Document.Sections, плюс FirstSection / LastSection); каждый Section имеет один Body, необязательную коллекцию колонтитулов и свой собственный PageSetup. Section.AppendContent(sourceSection) и PrependContent(sourceSection) копируют содержимое между разделами, а ClearContent() сбрасывает раздел, не удаляя его из документа.

Внутри Body содержимое доступно через Body.Paragraphs (это ParagraphCollection) и Body.Tables. Range — доступный из Document, Section, Paragraph и других узлов — представляет собой непрерывную область дерева; Range.Text считывает его простой текст, а Range.Replace(pattern, replacement) выполняет поиск и замену только в этой области.


Обход дерева узлов с помощью DocumentVisitor

Каждая часть документа — разделы, абзацы, runs, таблицы, fields, shapes, комментарии, footnotes — является Node в составном дереве с корнем в Document. Чтобы обработать каждый узел заданного типа без ручной рекурсии, наследуйте абстрактный DocumentVisitor и переопределите необходимые callbacks Visit*Start / Visit*End, такие как VisitParagraphStart(paragraph) или VisitRun(run), затем вызовите document.Accept(visitor). Каждый callback может вернуть VisitorAction (Continue, SkipThisNode или Stop) для управления ходом обхода.


Клонирование, импорт и добавление содержимого

Document.Clone() создает глубокую копию всего документа. Чтобы переместить содержимое между двумя разными экземплярами Document, вызовите ImportNode(srcNode, isImportChildren) в документе-получателе, чтобы импортировать узел из внешнего дерева, или вызовите Document.AppendDocument(srcDoc, importFormatMode), чтобы добавить разделы одного документа к другому, используя выбранный ImportFormatMode — KeepSourceFormatting, UseDestinationStyles или KeepDifferentStyles. DocumentBuilder.InsertDocument(srcDoc, importFormatMode) вставляет содержимое исходного документа в курсор билдера вместо конца документа-получателя.


Защита документов

Document.Protect(type, password) ограничивает редактирование в соответствии со значением ProtectionType — ReadOnly, AllowOnlyComments, AllowOnlyRevisions, AllowOnlyFormFields или NoProtection для снятия защиты. Unprotect() (с паролем или без него) отменяет её. Это ограничение редактирования, применяемое Word, отдельное от шифрования паролем OOXML, которое OoxmlSaveOptions.Password использует при сохранении файла.


Советы и лучшие практики

  • Предпочитайте DocumentBuilder при создании нового контента; переходите к прямому управлению узлами (AppendChild, InsertAfter, Clone), когда требуется тонкий контроль над существующим деревом.
  • Вызовите FileFormatUtil.DetectFileFormat перед загрузкой файла из ненадёжного или пользовательского источника, чтобы проверить LoadFormat и заранее отклонить неподдерживаемый или зашифрованный ввод.
  • При объединении документов с помощью AppendDocument или InsertDocument выбирайте ImportFormatMode осознанно — KeepSourceFormatting сохраняет внешний вид исходного документа, UseDestinationStyles соответствует набору стилей целевого документа.
  • Используйте подкласс DocumentVisitor вместо ручного рекурсивного обхода дерева, когда необходимо последовательно обрабатывать каждый экземпляр типа узла.
  • Document.Protect — это ограничение редактирования, а не шифрование — комбинируйте его с OoxmlSaveOptions.Password, если сам сохраняемый файл должен требовать пароль для открытия.

Общие проблемы

ПроблемаПричинаИсправление
Document(fileName) выдает ошибку для файла, который открывается без проблем в WordФормат файла не поддерживается этой редакцией для загрузкиСначала вызовите FileFormatUtil.DetectFileFormat и проверьте возвращённый LoadFormat перед загрузкой
При добавлении содержимого оно наследует неправильные шрифты или стилиНесоответствие ImportFormatMode между наборами стилей источника и назначенияПередайте KeepSourceFormatting или UseDestinationStyles явно, а не полагайтесь на значение по умолчанию
Обход DocumentVisitor останавливается преждевременно или пропускает содержимоеПереопределение Visit*Start / Visit*End возвращает SkipThisNode или Stop непреднамеренноВозвращайте VisitorAction.Continue из каждого переопределения, если только вы специально не намерены пропустить или остановить
Unprotect() не оказывает никакого влиянияДокумент не был защищён паролем, либо был указан неверный парольВызовите Unprotect() без аргументов, если Protect был вызван без пароля, иначе передайте соответствующий пароль

FAQ

В чём разница между Document.Clone() и ImportNode?

Clone() копирует весь документ в новый экземпляр Document. ImportNode(srcNode, isImportChildren) переносит отдельный узел (и при желании его дочерние элементы) из дерева одного документа в другой, что используется при комбинировании конкретного содержания, а не целых документов.

Какие форматы файлов может загружать Document(fileName)?

Document(fileName) загружает DOCX, DOCM, DOTX, DOTM, Flat OPC (включая макрос-поддерживаемые и шаблонные варианты), Markdown и обычный текст. Более старые форматы обработки текста и веб-форматы исключены из загрузчиков этой версии.

Как узнать, где в данный момент расположен DocumentBuilder?

Прочитайте CurrentNode, CurrentParagraph или CurrentSection на экземпляре builder.

Шифрует ли Document.Protect сохранённый файл?

Нет — это ограничение редактирования, наложенное Word при открытии файла. Чтобы требовать пароль только для открытия файла, установите OoxmlSaveOptions.Password при сохранении.

Как прочитать только абзацы в теле документа?

Используйте коллекцию Body.Paragraphs или Body.GetChildNodes(nodeType, isDeep) для других типов узлов.


API Reference Сводка

Класс/МетодОписание:
DocumentКорень модели объектного документа; конструкторы загружают из файла или потока, либо создают пустой документ.
Document.SaveЗаписывает документ в файл, поток или HTTP ответ в выбранном формате.
Document.Clone()Создаёт глубокую копию всего документа.
Document.Protect(type, password) / Unprotect()Применяет или удаляет ограничение редактирования.
Document.AppendDocument(srcDoc, importFormatMode)Добавляет разделы другого документа к этому.
DocumentBuilderКурсорный API для написания текста и вставки содержимого в документ.
DocumentBuilder.InsertDocument(srcDoc, importFormatMode)Вставляет содержимое исходного документа в позицию курсора.
Section / SectionCollectionОдин раздел документа и совокупность всех разделов.
BodyКонтейнер для основного текста (абзацев и таблиц) раздела.
RangeНепрерывная область дерева документа; поддерживает Text и Replace.
DocumentVisitorАбстрактный базовый класс для обхода каждого узла дерева документа.
ProtectionTypeПеречисление ограничений редактирования на уровне документа.
FileFormatUtil.DetectFileFormatОпределяет формат файла или потока перед загрузкой.

См. также:

 Русский