Извлечение содержимого между узлами документа

При работе с документами важно иметь возможность легко извлекать содержимое из определенного диапазона в документе. Однако содержимое может состоять из сложных элементов, таких как абзацы, таблицы, изображения и т.д.

Независимо от того, какой контент необходимо извлечь, метод извлечения этого контента всегда будет определяться тем, какие узлы выбраны для извлечения содержимого между ними. Это могут быть целые текстовые фрагменты или простые текстовые фрагменты.

Существует множество возможных ситуаций и, следовательно, множество различных типов узлов, которые следует учитывать при извлечении содержимого. Например, вы можете захотеть извлечь содержимое между:

  • Два конкретных пункта
  • Конкретные фрагменты текста
  • Поля различных типов, такие как поля слияния
  • Начальный и конечный диапазоны закладки или комментария
  • Различные тексты, содержащиеся в отдельных разделах

В некоторых ситуациях вам может даже потребоваться объединить различные типы узлов, например, для извлечения содержимого из абзаца и поля или из запуска и закладки.

В этой статье приводится реализация кода для извлечения текста между различными узлами, а также примеры распространенных сценариев.

Зачем извлекать контент

Часто целью извлечения содержимого является дублирование или сохранение его отдельно в новом документе. Например, вы можете извлечь содержимое и:

  • Скопируйте его в отдельный документ
  • Преобразуйте определенную часть документа в PDF или изображение
  • Дублируйте содержимое документа много раз
  • Работайте с извлеченным содержимым отдельно от остальной части документа

Этого можно легко достичь, используя Aspose.Words и приведенную ниже реализацию кода.

Алгоритм извлечения содержимого

Приведенный в этом разделе код рассматривает все возможные ситуации, описанные выше, с помощью одного обобщенного метода, который можно использовать повторно. В общих чертах этот метод включает:

  1. Сбор узлов, которые определяют область содержимого, которая будет извлечена из вашего документа. Поиск этих узлов осуществляется пользователем в его коде в зависимости от того, что он хочет извлечь.
  2. Передаем эти узлы методу ExtractContent, представленному ниже. Вы также должны передать логический параметр, который указывает, должны ли эти узлы, действующие как маркеры, быть включены в извлечение или нет.
  3. Получение списка клонированного содержимого (скопированных узлов), указанного для извлечения. Вы можете использовать этот список узлов любым применимым способом, например, создать новый документ, содержащий только выбранное содержимое.

Как извлечь контент

В этой статье мы будем работать с документом, представленным ниже. Как вы можете видеть, он содержит разнообразный контент. Также обратите внимание, что документ содержит второй раздел, начинающийся с середины первой страницы. Закладка и комментарий также присутствуют в документе, но не видны на скриншоте ниже.

extract-content-aspose-words-java

Чтобы извлечь содержимое из вашего документа, вам нужно вызвать метод ExtractContent, приведенный ниже, и передать соответствующие параметры.

В основе этого метода лежит поиск узлов на уровне блоков (абзацев и таблиц) и их клонирование для создания идентичных копий. Если переданные маркерные узлы относятся к уровню блоков, то метод может просто скопировать содержимое на этом уровне и добавить его в массив.

Однако, если узлы-маркеры являются встроенными (дочерними по отношению к абзацу), ситуация становится более сложной, поскольку необходимо разделить абзац на встроенном узле, будь то прогон, поля закладок и т.д. Содержимое в клонированных родительских узлах, отсутствующее между маркерами, удаляется. Этот процесс используется для обеспечения того, чтобы встроенные узлы по-прежнему сохраняли форматирование родительского абзаца.

Метод также выполняет проверку узлов, переданных в качестве параметров, и генерирует исключение, если какой-либо из узлов является недопустимым. В этот метод передаются следующие параметры:

  1. StartNode и EndNode. Первые два параметра - это узлы, которые определяют, где должно начинаться и заканчиваться извлечение содержимого соответственно. Эти узлы могут быть как блочного уровня (Paragraph, Table ), так и встроенного (например, Run, FieldStart, BookmarkStart и т.д.).:

    1. Чтобы передать поле, вы должны передать соответствующий объект FieldStart.
    2. Чтобы передать закладки, необходимо передать узлы BookmarkStart и BookmarkEnd.
    3. Для передачи комментариев следует использовать узлы CommentRangeStart и CommentRangeEnd.
  2. IsInclusive. Определяет, будут ли маркеры включены в извлечение или нет. Если для этого параметра установлено значение false и передается один и тот же узел или последовательные узлы, то будет возвращен пустой список:

    1. Если передается узел FieldStart, то этот параметр определяет, следует ли включать или исключать все поле целиком.
    2. Если передан узел BookmarkStart или BookmarkEnd, этот параметр определяет, включена ли закладка или только содержимое между диапазонами закладок.
    3. Если передан узел CommentRangeStart или CommentRangeEnd, этот параметр определяет, должен ли быть включен сам комментарий или только содержимое в диапазоне комментариев.

Реализацию метода ExtractContent вы можете найти здесь. Этот метод будет описан в сценариях, описанных в этой статье.

Мы также определим пользовательский метод, позволяющий легко создавать документ из извлеченных узлов. Этот метод используется во многих сценариях, описанных ниже, и просто создает новый документ и импортирует в него извлеченное содержимое.

В следующем примере кода показано, как взять список узлов и вставить их в новый документ:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
public static Document generateDocument(Document srcDoc, ArrayList<Node> nodes) throws Exception
{
Document dstDoc = new Document();
// Remove the first paragraph from the empty document.
dstDoc.getFirstSection().getBody().removeAllChildren();
// Import each node from the list into the new document. Keep the original formatting of the node.
NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KEEP_SOURCE_FORMATTING);
for (Node node : nodes)
{
Node importNode = importer.importNode(node, true);
dstDoc.getFirstSection().getBody().appendChild(importNode);
}
return dstDoc;
}

Извлекайте содержимое между абзацами

Это демонстрирует, как использовать описанный выше метод для извлечения содержимого между определенными абзацами. В данном случае мы хотим извлечь текст письма, найденного в первой половине документа. Мы можем сказать, что это между 7-м и 11-м абзацами.

Приведенный ниже код выполняет эту задачу. Соответствующие абзацы извлекаются с использованием метода getChild в документе и с передачей указанных индексов. Затем мы передаем эти узлы методу ExtractContent и указываем, что они должны быть включены в извлечение. Этот метод вернет скопированное содержимое между этими узлами, которое затем будет вставлено в новый документ.

В следующем примере кода показано, как извлечь содержимое между определенными абзацами, используя метод ExtractContent, описанный выше:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
Paragraph startPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 6, true);
Paragraph endPara = (Paragraph) doc.getFirstSection().getBody().getChild(NodeType.PARAGRAPH, 10, true);
// Extract the content between these nodes in the document. Include these markers in the extraction.
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startPara, endPara, true);
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes);
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphs.docx");

Итоговый документ содержит два абзаца, которые были извлечены из него.

extract-content-result-aspose-words-java

Извлекать содержимое между различными типами узлов

Мы можем извлекать содержимое между любыми комбинациями узлов на уровне блоков или встроенных узлов. В приведенном ниже сценарии мы будем извлекать содержимое между первым абзацем и таблицей во втором разделе включительно. Мы получаем узлы-маркеры, вызывая методы getFirstParagraph и getChild во втором разделе документа, чтобы получить соответствующие узлы Paragraph и Table. Для небольшого изменения давайте вместо этого продублируем содержимое и вставим его под оригинал.

В следующем примере кода показано, как извлечь содержимое из абзаца и таблицы с помощью метода ExtractContent:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
Paragraph startPara = (Paragraph) doc.getLastSection().getChild(NodeType.PARAGRAPH, 2, true);
Table endTable = (Table) doc.getLastSection().getChild(NodeType.TABLE, 0, true);
// Extract the content between these nodes in the document. Include these markers in the extraction.
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startPara, endTable, true);
// Let's reverse the array to make inserting the content back into the document easier.
Collections.reverse(extractedNodes);
for (Node extractedNode : extractedNodes)
// Insert the last node from the reversed list.
endTable.getParentNode().insertAfter(extractedNode, endTable);
doc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBlockLevelNodes.docx");

Содержание между абзацем и таблицей было продублировано, ниже приведен результат.

extract-content-between-paragraphs-aspose-words-java

Извлекайте содержимое из абзацев в зависимости от стиля

Возможно, вам потребуется извлечь содержимое между абзацами одного и того же или разного стиля, например, между абзацами, помеченными стилями заголовков.

Приведенный ниже код показывает, как этого добиться. Это простой пример, который позволяет извлекать содержимое между первым экземпляром стилей “Heading 1” и “Заголовок 3” без извлечения заголовков. Для этого мы устанавливаем последнему параметру значение false, которое указывает, что узлы-маркеры не должны быть включены.

При правильной реализации это должно выполняться в цикле для извлечения содержимого между всеми абзацами этих стилей из документа. Извлеченное содержимое копируется в новый документ.

В следующем примере кода показано, как извлекать содержимое между абзацами с определенными стилями, используя метод ExtractContent:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
// Gather a list of the paragraphs using the respective heading styles.
ArrayList<Paragraph> parasStyleHeading1 = paragraphsByStyleName(doc, "Heading 1");
ArrayList<Paragraph> parasStyleHeading3 = paragraphsByStyleName(doc, "Heading 3");
// Use the first instance of the paragraphs with those styles.
Node startPara1 = parasStyleHeading1.get(0);
Node endPara1 = parasStyleHeading3.get(0);
// Extract the content between these nodes in the document. Don't include these markers in the extraction.
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startPara1, endPara1, false);
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes);
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenParagraphStyles.docx");
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
public static ArrayList<Paragraph> paragraphsByStyleName(Document doc, String styleName)
{
// Create an array to collect paragraphs of the specified style.
ArrayList<Paragraph> paragraphsWithStyle = new ArrayList<Paragraph>();
NodeCollection paragraphs = doc.getChildNodes(NodeType.PARAGRAPH, true);
// Look through all paragraphs to find those with the specified style.
for (Paragraph paragraph : (Iterable<Paragraph>) paragraphs)
{
if (paragraph.getParagraphFormat().getStyle().getName().equals(styleName))
paragraphsWithStyle.add(paragraph);
}
return paragraphsWithStyle;
}

Ниже приведен результат предыдущей операции.

extract-content-between-paragraph-style-aspose-words-java

Извлекать содержимое Между Определенными Запусками

Вы также можете извлекать содержимое между встроенными узлами, такими как Run. в качестве маркеров можно использовать Runs из разных абзацев. В приведенном ниже коде показано, как извлекать определенный текст из одного и того же узла Paragraph.

В следующем примере кода показано, как извлекать содержимое между конкретными запусками одного и того же абзаца, используя метод ExtractContent:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
Paragraph para = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 7, true);
Run startRun = para.getRuns().get(1);
Run endRun = para.getRuns().get(4);
// Extract the content between these nodes in the document. Include these markers in the extraction.
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startRun, endRun, true);
for (Node extractedNode : extractedNodes)
System.out.println(extractedNode.toString(SaveFormat.TEXT));

Извлеченный текст отображается на консоли.

extract-content-between-runs-aspose-words-java

Извлекать содержимое с помощью поля

Чтобы использовать поле в качестве маркера, необходимо передать узел FieldStart. Последний параметр метода ExtractContent определяет, следует ли включать все поле целиком или нет. Давайте выделим содержимое между полем слияния “FullName” и абзацем в документе. Мы используем метод moveToMergeField класса DocumentBuilder. Он вернет узел FieldStart из имени переданного ему поля слияния.

В нашем случае давайте установим для последнего параметра, переданного методу ExtractContent, значение false, чтобы исключить поле из извлечения. Мы преобразуем извлеченное содержимое в PDF.

В следующем примере кода показано, как извлечь содержимое из определенного поля и абзаца в документе с помощью метода ExtractContent:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
// Pass the first boolean parameter to get the DocumentBuilder to move to the FieldStart of the field.
// We could also get FieldStarts of a field using GetChildNode method as in the other examples.
builder.moveToMergeField("Fullname", false, false);
// The builder cursor should be positioned at the start of the field.
FieldStart startField = (FieldStart) builder.getCurrentNode();
Paragraph endPara = (Paragraph) doc.getFirstSection().getChild(NodeType.PARAGRAPH, 5, true);
// Extract the content between these nodes in the document. Don't include these markers in the extraction.
ArrayList<Node> extractedNodes = ExtractContentHelper.extractContent(startField, endPara, false);
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodes);
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentUsingField.docx");

Извлеченное содержимое между полем и абзацем без узлов-маркеров поля и абзаца, отображаемых как PDF.

extract-content-using-field-aspose-words-java

Извлечение содержимого из закладки

В документе содержимое, определенное в закладке, инкапсулируется узлами BookmarkStart и BookmarkEnd. Содержимое, находящееся между этими двумя узлами, составляет закладку. Вы можете передать любой из этих узлов в качестве любого маркера, даже из разных закладок, при условии, что начальный маркер отображается в документе перед конечным маркером.

В нашем примере документа у нас есть одна закладка с именем “Bookmark1”. Содержимое этой закладки является выделенным содержимым в нашем документе:

extract-content-from-bookmark-aspose-words-java-1

Мы извлекем это содержимое в новый документ, используя приведенный ниже код. Параметр IsInclusive показывает, как сохранить или удалить закладку.

В следующем примере кода показано, как извлечь содержимое, на которое ссылается закладка, используя метод ExtractContent:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
Bookmark bookmark = doc.getRange().getBookmarks().get("Bookmark1");
BookmarkStart bookmarkStart = bookmark.getBookmarkStart();
BookmarkEnd bookmarkEnd = bookmark.getBookmarkEnd();
// Firstly, extract the content between these nodes, including the bookmark.
ArrayList<Node> extractedNodesInclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, true);
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive);
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx");
// Secondly, extract the content between these nodes this time without including the bookmark.
ArrayList<Node> extractedNodesExclusive = ExtractContentHelper.extractContent(bookmarkStart, bookmarkEnd, false);
dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive);
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx");

Извлеченный результат с параметром IsInclusive, равным true. В копии также будет сохранена закладка.

extract-content-from-bookmark-aspose-words-java-2

Извлеченный результат с параметром IsInclusive, равным false. Копия содержит содержимое, но без закладки.

extract-content-from-bookmark-aspose-words-java-3

Извлекать содержимое из комментария

Комментарий состоит из узлов CommentRangeStart, CommentRangeEnd и Comment. Все эти узлы являются встроенными. Первые два узла инкапсулируют содержимое документа, на который ссылается комментарий, как показано на скриншоте ниже.

Узел Comment сам по себе является узлом InlineStory, который может содержать абзацы и заголовки. Он представляет собой сообщение комментария, отображаемое в виде пузырька комментариев на панели просмотра. Поскольку этот узел является встроенным и является потомком тела, вы также можете извлечь содержимое из этого сообщения.

В нашем документе есть один комментарий. Давайте отобразим его, показав разметку на вкладке Обзор:

extract-content-from-comment-aspose-words-java-1

Комментарий содержит заголовок, первый абзац и таблицу во втором разделе. Давайте перенесем этот комментарий в новый документ. Параметр IsInclusive определяет, следует ли сохранить сам комментарий или удалить его.

В следующем примере кода показано, как это сделать, приведенном ниже:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
CommentRangeStart commentStart = (CommentRangeStart) doc.getChild(NodeType.COMMENT_RANGE_START, 0, true);
CommentRangeEnd commentEnd = (CommentRangeEnd) doc.getChild(NodeType.COMMENT_RANGE_END, 0, true);
// Firstly, extract the content between these nodes including the comment as well.
ArrayList<Node> extractedNodesInclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, true);
Document dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesInclusive);
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx");
// Secondly, extract the content between these nodes without the comment.
ArrayList<Node> extractedNodesExclusive = ExtractContentHelper.extractContent(commentStart, commentEnd, false);
dstDoc = ExtractContentHelper.generateDocument(doc, extractedNodesExclusive);
dstDoc.save(getArtifactsDir() + "ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx");

Сначала извлеките выходные данные с параметром IsInclusive, равным true. Копия также будет содержать комментарий.

extract-content-from-comment-aspose-words-java-2

Во-вторых, извлеченный вывод с значением isInclusive, равным false. Копия содержит содержимое, но без комментария.

extract-content-from-comment-aspose-words-java-12

Извлеките содержимое с помощью DocumentVisitor

Aspose.Words может использоваться не только для создания Microsoft Word документов путем их динамического создания или объединения шаблонов с данными, но и для синтаксического анализа документов с целью извлечения отдельных элементов документа, таких как верхние и нижние колонтитулы, абзацы, таблицы, изображения и другие. Другая возможная задача - найти весь текст определенного формата или стиля.

Используйте класс DocumentVisitor для реализации этого сценария использования. Этот класс соответствует хорошо известному шаблону оформления посетителей. С помощью DocumentVisitor вы можете определять и выполнять пользовательские операции, которые требуют перечисления в дереве документа.

DocumentVisitor предоставляет набор из VisitXXX методов, которые вызываются при обнаружении определенного элемента документа (узла). Например, VisitParagraphStart вызывается при обнаружении начала текстового абзаца, а VisitParagraphEnd вызывается при обнаружении конца текстового абзаца. Каждый метод DocumentVisitor.VisitXXX принимает соответствующий объект, с которым он сталкивается, чтобы вы могли использовать его по мере необходимости (скажем, восстановить форматирование), например, как VisitParagraphStart, так и VisitParagraphEnd принимают объект Paragraph.

Каждый метод DocumentVisitor.VisitXXX возвращает значение VisitorAction, которое управляет перечислением узлов. Вы можете запросить либо продолжить перечисление, пропустить текущий узел (но продолжить перечисление), либо остановить перечисление узлов.

Вот шаги, которые вы должны выполнить, чтобы программно определить и извлечь различные части документа:

  • Создайте класс, производный от DocumentVisitor.
  • Переопределите и предоставьте реализации для некоторых или всех методов DocumentVisitor.VisitXXX для выполнения некоторых пользовательских операций.
  • Вызовите Node.accept на узле, с которого вы хотите начать перечисление. Например, если вы хотите перечислить весь документ, используйте accept(DocumentVisitor).

DocumentVisitor предоставляет реализации по умолчанию для всех методов DocumentVisitor.VisitXXX. Это упрощает создание новых посетителей документа, поскольку необходимо переопределять только методы, необходимые для конкретного посетителя. Нет необходимости переопределять все методы посетителя.

В следующем примере показано, как использовать шаблон посетителя для добавления новых операций в объектную модель Aspose.Words. В этом случае мы создаем простой конвертер документов в текстовый формат:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Extract content.docx");
ConvertDocToTxt convertToPlainText = new ConvertDocToTxt();
// Note that every node in the object model has the accept method so the visiting
// can be executed not only for the whole document, but for any node in the document.
doc.accept(convertToPlainText);
// Once the visiting is complete, we can retrieve the result of the operation,
// That in this example, has accumulated in the visitor.
System.out.println(convertToPlainText.getText());
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
/// <summary>
/// Simple implementation of saving a document in the plain text format. Implemented as a Visitor.
/// </summary>
static class ConvertDocToTxt extends DocumentVisitor {
public ConvertDocToTxt() {
mIsSkipText = false;
mBuilder = new StringBuilder();
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
public String getText() {
return mBuilder.toString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
public int visitRun(Run run) {
appendText(run.getText());
// Let the visitor continue visiting other nodes.
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a FieldStart node is encountered in the document.
/// </summary>
public int visitFieldStart(FieldStart fieldStart) {
// In Microsoft Word, a field code (such as "MERGEFIELD FieldName") follows
// after a field start character. We want to skip field codes and output field.
// Result only, therefore we use a flag to suspend the output while inside a field code.
// Note this is a very simplistic implementation and will not work very well.
// If you have nested fields in a document.
mIsSkipText = true;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a FieldSeparator node is encountered in the document.
/// </summary>
public int visitFieldSeparator(FieldSeparator fieldSeparator) {
// Once reached a field separator node, we enable the output because we are
// now entering the field result nodes.
mIsSkipText = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a FieldEnd node is encountered in the document.
/// </summary>
public int visitFieldEnd(FieldEnd fieldEnd) {
// Make sure we enable the output when reached a field end because some fields
// do not have field separator and do not have field result.
mIsSkipText = false;
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when visiting of a Paragraph node is ended in the document.
/// </summary>
public int visitParagraphEnd(Paragraph paragraph) {
// When outputting to plain text we output Cr+Lf characters.
appendText(ControlChar.CR_LF);
return VisitorAction.CONTINUE;
}
public int visitBodyStart(Body body) {
// We can detect beginning and end of all composite nodes such as Section, Body,
// Table, Paragraph etc and provide custom handling for them.
mBuilder.append("*** Body Started ***\r\n");
return VisitorAction.CONTINUE;
}
public int visitBodyEnd(Body body) {
mBuilder.append("*** Body Ended ***\r\n");
return VisitorAction.CONTINUE;
}
/// <summary>
/// Called when a HeaderFooter node is encountered in the document.
/// </summary>
public int visitHeaderFooterStart(HeaderFooter headerFooter) {
// Returning this value from a visitor method causes visiting of this
// Node to stop and move on to visiting the next sibling node
// The net effect in this example is that the text of headers and footers
// Is not included in the resulting output
return VisitorAction.SKIP_THIS_NODE;
}
/// <summary>
/// Adds text to the current output. Honors the enabled/disabled output flag.
/// </summary>
private void appendText(String text) {
if (!mIsSkipText)
mBuilder.append(text);
}
private StringBuilder mBuilder;
private boolean mIsSkipText;
}

Извлекать только текст

Существуют следующие способы извлечения текста из документа:

  • Используйте Document.save вместо SaveFormat для сохранения в виде обычного текста в файл или поток
  • Используйте Node.toString и передайте параметр SaveFormat.Text. Внутренне это вызывает функцию сохранения в виде текста в потоке памяти и возвращает результирующую строку
  • Используйте Node.getText для извлечения текста, содержащего все управляющие символы Microsoft Word, включая коды полей
  • Реализуйте пользовательский параметр DocumentVisitor для выполнения индивидуального извлечения

Используя Node.GetText и Node.ToString

Документ Word может содержать управляющие символы, которые обозначают специальные элементы, такие как поле, конец ячейки, конец раздела и т.д. Полный список возможных управляющих символов Word определен в классе ControlChar. Метод GetText возвращает текст со всеми управляющими символами, присутствующими в узле.

Вызов ToString возвращает только текстовое представление документа без управляющих символов. Дополнительную информацию об экспорте в виде обычного текста смотрите в Using SaveFormat.Text.

В следующем примере кода показана разница между вызовом методов GetText и ToString на узле:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.insertField("MERGEFIELD Field");
// When converted to text it will not retrieve fields code or special characters,
// but will still contain some natural formatting characters such as paragraph markers etc.
// This is the same as "viewing" the document as if it was opened in a text editor.
System.out.println("ToString() Result: " + doc.toString(SaveFormat.TEXT));

Используя SaveFormat.Text

В этом примере документ сохраняется следующим образом:

  • Отфильтровывает символы полей и коды полей, форму, сноски, концевые примечания и ссылки на комментарии
  • Заменяет символы конца абзаца ControlChar.Cr комбинациями ControlChar.CrLf
  • Использует кодировку UTF8

В следующем примере кода показано, как сохранить документ в формате TXT:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Document.docx");
doc.save(getArtifactsDir() + "BaseConversions.DocxToTxt.txt");

Извлечение изображений из фигур

Для выполнения некоторых задач вам может потребоваться извлечь изображения из документов. Aspose.Words это также позволяет это сделать.

В следующем примере кода показано, как извлекать изображения из документа:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Images.docx");
NodeCollection shapes = doc.getChildNodes(NodeType.SHAPE, true);
int imageIndex = 0;
for (Shape shape : (Iterable<Shape>) shapes) {
if (shape.hasImage()) {
String imageFileName =
MessageFormat.format("Image.ExportImages.{0}_{1}", imageIndex, FileFormatUtil.imageTypeToExtension(shape.getImageData().getImageType()));
// Note, if you have only an image (not a shape with a text and the image),
// you can use shape.getShapeRenderer().save(...) method to save the image.
shape.getImageData().save(getArtifactsDir() + imageFileName);
imageIndex++;
}
}