Витяг вмісту між вузлами документа
При роботі з документами важливо мати можливість легко витягувати вміст з певного діапазону в документі. Однак вміст може складатися зі складних елементів, таких як абзаци, таблиці, зображення і т. д.
Незалежно від того, який вміст потрібно витягти, метод вилучення цього вмісту завжди визначатиметься тим, які вузли вибрані для отримання вмісту між ними. Це можуть бути цілі текстові фрагменти або прості текстові фрагменти.
Існує багато можливих ситуацій і, отже, багато різних типів вузлів, які слід враховувати при отриманні вмісту. Наприклад, ви можете захотіти витягти вміст між:
- Два конкретні пункти
- Конкретні фрагменти тексту
- Поля різних типів, такі як поля злиття
- Початковий і кінцевий діапазони закладки або коментаря
- Різні тексти, що містяться в окремих розділах
У деяких ситуаціях вам може знадобитися навіть об’єднати різні типи вузлів, наприклад, для вилучення вмісту з абзацу та поля або з запуску та закладки.
У цій статті наводиться реалізація коду для вилучення тексту між різними вузлами, а також приклади поширених сценаріїв.
Навіщо витягувати контент
Часто метою вилучення вмісту є дублювання або збереження його окремо в новому документі. Наприклад, ви можете витягти вміст і:
- Скопіюйте його в окремий документ
- Перетворіть певну частину документа на PDF або зображення
- Повторюйте вміст документа багато разів
- Працюйте з витягнутим вмістом окремо від решти документа
Цього можна легко досягти, використовуючи Aspose.Words та реалізацію коду нижче.
Алгоритм вилучення вмісту
Наведений у цьому розділі код розглядає всі можливі ситуації, описані вище, за допомогою одного узагальненого методу, який можна використовувати повторно. Загалом цей метод включає:
- Збір вузлів, які визначають область вмісту, яка буде витягнута з вашого документа. Пошук цих вузлів здійснюється Користувачем у його коді залежно від того, що він хоче витягти.
- Передаємо ці вузли методу ExtractContent, представленому нижче. Ви також повинні передати логічний параметр, який вказує, чи повинні ці вузли, що діють як маркери, бути включені в Витяг чи ні.
- Отримання списку клонованого вмісту (скопійованих вузлів), вказаного для вилучення. Ви можете використовувати цей список вузлів будь-яким застосовним способом, наприклад, створити новий документ, що містить лише вибраний вміст.
Як витягти контент
Щоб витягти вміст із документа, вам потрібно викликати метод ExtractContent
, описаний нижче, і передати відповідні параметри. В основі цього методу лежить пошук вузлів на рівні блоків (абзаців і таблиць) і їх клонування для створення ідентичних копій. Якщо передані вузли-маркери знаходяться на рівні блоків, то метод може просто скопіювати вміст на цьому рівні і додати його в масив.
Однак, якщо вузли-маркери є вбудованими (дочірніми по відношенню до абзацу), ситуація стає більш складною, оскільки необхідно розділити абзац на вбудованому вузлі, будь то прогін, поля закладок і т.д. вміст в клонованих батьківських вузлах, відсутнє між маркерами, видаляється. Цей процес використовується для забезпечення того, щоб вбудовані вузли зберігали форматування батьківського абзацу. Метод також виконує перевірку вузлів, переданих як параметри, і видає виняток, якщо будь-який з вузлів є недійсним. В цей метод передаються наступні параметри:
-
StartNode і EndNode. Перші два параметри-це вузли, які визначають, де слід починати і закінчувати Витяг вмісту відповідно. Ці вузли можуть бути як на рівні блоків (абзац, таблиця), так і на вбудованому рівні (наприклад, Run, FieldStart, BookmarkStart і т.д.).:
- Щоб передати поле, ви повинні передати відповідний об’єкт FieldStart.
- Щоб передати закладки, необхідно передати вузли BookmarkStart і BookmarkEnd.
- Для передачі коментарів слід використовувати вузли CommentRangeStart і CommentRangeEnd.
-
IsInclusive. Визначає, чи будуть маркери включені в Витяг чи ні. Якщо для цього параметра встановлено значення false і передається один і той же вузол або послідовні вузли, то буде повернуто порожній список:
- Якщо передається вузол FieldStart, то цей параметр визначає, чи слід включати або виключати все поле цілком.
- Якщо передано вузол BookmarkStart або BookmarkEnd, Цей параметр визначає, чи включена закладка або лише вміст між діапазонами закладок.
- Якщо передано вузол CommentRangeStart або CommentRangeEnd, Цей параметр визначає, чи повинен бути включений сам коментар або лише вміст у діапазоні коментарів.
Реалізацію методу ExtractContent ви можете знайти тут. Цей метод буде описаний у сценаріях, описаних у цій статті.
Ми також визначимо метод користувача, який дозволяє легко створювати документ із витягнутих вузлів. Цей метод використовується в багатьох сценаріях, описаних нижче, і просто створює новий документ і імпортує в нього витягнутий вміст.
Наступний приклад коду показує, як взяти список вузлів і вставити їх у новий документ.
Витягуйте вміст між абзацами
Це демонструє, як використовувати описаний вище метод для вилучення вмісту між конкретними абзацами. В даному випадку ми хочемо витягти текст листа, знайденого в першій половині документа. Можна сказати, що це між 7-м і 11-м абзацами.
Наведений нижче код виконує це завдання. Відповідні абзаци витягуються з використанням методу GetChild в документі і з передачею зазначених індексів. Потім ми передаємо ці вузли методу ExtractContent і вказуємо, що вони повинні бути включені в Витяг. Цей метод поверне скопійований вміст між цими вузлами, який потім буде вставлений у новий документ.
Наступний приклад коду показує, як витягти вміст між певними абзацами, використовуючи метод ExtractContent
, описаний вище:
Витягувати вміст між різними типами вузлів
Ми можемо витягувати вміст між будь-якими комбінаціями вузлів на рівні блоків або вбудованих вузлів. У наведеному нижче сценарії ми будемо витягувати вміст між першим абзацом та таблицею у другому розділі включно. Ми отримуємо вузли маркерів, викликаючи методи Body.FirstParagraph
та GetChild у другому розділі документа, щоб отримати відповідні вузли абзацу та таблиці. Для невеликої зміни давайте замість цього продублюємо вміст і вставимо його під оригінал.
Наступний приклад коду показує, як витягти вміст з абзацу та таблиці за допомогою методу ExtractContent
:
Витягуйте вміст з абзаців залежно від стилю
Можливо, вам доведеться витягти вміст з абзаців одного або різних стилів, наприклад, з абзаців, позначених стилями заголовків. Наведений нижче код показує, як цього досягти. Це простий приклад, який дозволяє витягувати вміст між першим екземпляром стилів “Heading 1” та “Header 3” без вилучення заголовків. Для цього ми встановлюємо останньому параметру значення false, яке вказує, що вузли-маркери не повинні включатися.
При правильній реалізації це повинно виконуватися в циклі для вилучення вмісту між усіма абзацами цих стилів з документа. Витягнутий вміст копіюється в новий документ.
Наступний приклад коду показує, як витягувати вміст між абзацами з певними стилями за допомогою методу ExtractContent
:
Витягуйте вміст між певними Запусками
Ви також можете витягувати вміст між вбудованими вузлами, такими як Run. Як маркери можна використовувати Runs з різних абзаців. У наведеному нижче коді показано, як витягувати певний текст з одного вузла Paragraph.
Наступний приклад коду показує, як витягувати вміст між конкретними запусками одного абзацу, використовуючи метод ExtractContent:
Витягувати вміст за допомогою поля
Щоб використовувати поле як маркер, необхідно передати вузол FieldStart
. Останній параметр методу ExtractContent
визначає, чи слід включати все поле цілком чи ні. Давайте виділимо вміст між полем злиття “FullName” та абзацом у документі. Ми використовуємо метод MoveToMergeField класу DocumentBuilder. Це поверне вузол FieldStart з переданого йому поля name of merge.
У нашому випадку давайте встановимо для останнього параметра, переданого методу ExtractContent, значення false, щоб виключити поле з вилучення. Ми перетворимо витягнутий вміст у PDF.
Наступний приклад коду показує, як витягти вміст із певного поля та абзацу в документі за допомогою методу ExtractContent:
Витяг вмісту з закладки
У документі вміст, визначений у закладці, інкапсулюється вузлами BookmarkStart
та BookmarkEnd. Вміст, що знаходиться між цими двома вузлами, становить закладку. Ви можете використовувати будь-який із цих вузлів як будь-який маркер, навіть із різних закладок, за умови, що початковий маркер відображається перед кінцевим маркером у документі. Ми витягнемо цей вміст у новий документ, використовуючи наведений нижче код. Параметр IsInclusive показує, як зберегти або видалити закладку.
Наступний приклад коду показує, як витягти вміст, на який посилається закладка, використовуючи метод ExtractContent:
Витягувати вміст з коментаря
Коментар складається з вузлів CommentRangeStart, CommentRangeEnd та Comment. Всі ці вузли є вбудованими. Перші два вузли містять вміст документа, на який посилається коментар, як показано на скріншоті нижче.
Вузол Comment сам по собі є вузлом InlineStory, який може містити абзаци та заголовки. Він являє собою повідомлення коментаря, що відображається у вигляді бульбашки коментарів на панелі попереднього перегляду. Оскільки цей вузол є вбудованим і є нащадком тіла, ви також можете витягти вміст із цього повідомлення.
Коментар містить заголовок, перший абзац та таблицю у другому розділі. Давайте перенесемо цей коментар до нового документа. Параметр IsInclusive визначає, чи слід зберігати сам коментар чи видаляти його.
Наступний приклад коду показує, як це зробити:
Як витягти вміст за допомогою DocumentVisitor
Використовуйте клас DocumentVisitor для реалізації цього сценарію використання. Цей клас відповідає добре відомому шаблону оформлення відвідувачів. За допомогою DocumentVisitor, ви можете визначати та виконувати спеціальні операції, які потребують переліку в дереві документа.
DocumentVisitor
Кожен метод DocumentVisitor.VisitXXX повертає значення VisitorAction, яке керує перерахуванням вузлів. Ви можете запросити або продовжити перерахування, пропустити поточний вузол (але продовжити перерахування), або зупинити перерахування вузлів.
Ось кроки, які ви повинні виконати, щоб програмно визначити та витягти різні частини документа:
- Створіть клас, похідний від DocumentVisitor
- Перевизначте та надайте реалізації для деяких або всіх методів DocumentVisitor.VisitXXX для виконання деяких операцій користувача
- Викличте
Node.Accept
на вузлі, з якого ви хочете почати перерахування. Наприклад, якщо ви хочете перерахувати весь документ, використовуйтеDocument.Accept
DocumentVisitor
Цей приклад показує, як використовувати шаблон відвідувача для додавання нових операцій до об’єктної моделі Aspose.Words. В даному випадку ми створюємо простий конвертер документів в текстовий формат:
Як витягти лише текст
Існують наступні способи вилучення тексту з документа:
- Використовуйте Document.Save замість SaveFormat.Text, щоб зберегти як звичайний текст у файл або потік
- Використовуйте Node.ToString і передайте параметр SaveFormat.Text. Внутрішньо це викликає функцію збереження як текст у потоці пам’яті та повертає отриманий рядок
- Використовуйте Node.GetText для вилучення тексту, що містить усі символи управління Microsoft Word, включаючи коди полів
- Реалізуйте користувацький параметр DocumentVisitor для виконання індивідуального вилучення
Використання Node.GetText
та Node.ToString
Документ Word може містити Керуючі символи, які позначають спеціальні елементи, такі як поле, кінець комірки, кінець розділу і т.д. повний список можливих Word керуючих символів визначено в класі ControlChar. Метод Node.GetText повертає текст із усіма контрольними символами, присутніми у вузлі.
Виклик ToString повертає лише текстове представлення документа без контрольних символів.
Наступний приклад коду показує різницю між викликом методів GetText та ToString на вузлі:
Використовуючи SaveFormat.Text
У цьому прикладі документ зберігається наступним чином:
- Відфільтровує символи полів і коди полів, форму, виноски, кінцеві примітки і посилання на коментарі
- Замінює символи кінця абзацу ControlChar.Cr комбінаціями ControlChar.CrLf
- Використовує кодування UTF8
Наступний приклад коду показує, як зберегти документ у форматі TXT:
Витяг зображень з фігур
Для виконання деяких завдань вам може знадобитися витягти зображення з документів. Aspose.Words це також дозволяє це зробити.
Наступний приклад коду показує, як витягувати зображення з документа: