Извличане на съдържание между възли в документ
Когато работите с документи, е важно да можете лесно да извличате съдържание от определен диапазон в документа. Съдържанието обаче може да се състои от сложни елементи като параграфи, таблици, изображения и т.н.
Независимо от това какво съдържание трябва да бъде извлечено, методът за извличане на това съдържание винаги ще се определя от това кои възли са избрани за извличане на съдържание между. Те могат да бъдат цели текстови тела или прости текстови работи.
Има много възможни ситуации и следователно много различни типове възли, които трябва да се вземат предвид при извличане на съдържание. Например, може да искате да извлечете съдържание между:
- Два конкретни параграфа
- Специфични серии от текст
- Полета от различни видове, като например сливащи се полета
- Начални и крайни диапазони на отметка или коментар
- Различни части от текста, съдържащи се в отделни раздели
В някои ситуации може дори да се наложи да комбинирате различни типове възли, като извличане на съдържание между абзац и поле или между изпълнение и отметка.
Тази статия предоставя имплементация на код за извличане на текст между различни възли, както и примери за общи сценарии.
Защо Да Извличаме Съдържание
Често целта на извличането на съдържанието е да го дублирате или запишете отделно в нов документ. Например, можете да извличате съдържание и:
- Копирайте го в отделен документ
- Преобразуване на определена част от документ в PDF или изображение
- Дублиране на съдържанието в документа много пъти
- Работа с извлечено съдържание отделно от останалата част на документа
Това може лесно да се постигне с Aspose.Words и прилагането на кода по-долу.
Алгоритъм За Извличане На Съдържание
Кодът в този раздел разглежда всички възможни ситуации, описани по-горе, с един обобщен и многократно използваем метод. Общото описание на тази техника включва:
- Събиране на възлите, които диктуват областта на съдържанието, което ще бъде извлечено от вашия документ. Извличането на тези възли се обработва от потребителя в техния код, въз основа на това, което искат да бъдат извлечени.
- Преминаване на тези възли към метода ExtractContent, предоставен по-долу. Трябва също така да преминете булев параметър, който гласи дали тези възли, действащи като маркери, трябва да бъдат включени в екстракцията или не.
- Извличане на списък с клонирано съдържание (копирани възли), указано да бъде извлечено. Можете да използвате този списък с възли по всякакъв приложим начин, например създаване на нов документ, съдържащ само избраното съдържание.
Как да извличаме съдържание
За да извлечете съдържанието от вашия документ, трябва да се обадите на метода ExtractContent
по-долу и да подадете съответните параметри. Основната основа на този метод включва намирането на възли на ниво блок (параграфи и таблици) и клонирането им, за да се създадат идентични копия. Ако преминатите маркерни възли са на блоково ниво, методът може просто да копира съдържанието на това ниво и да го добави към масива.
Ако обаче маркерните възли са вградени (дете на абзац), тогава ситуацията става по-сложна, тъй като е необходимо да се раздели параграфът на вградения възел, било то бягане, полета за отметки и т.н. Съдържанието в клонираните родителски възли, което не присъства между маркерите, се отстранява. Този процес се използва, за да се гарантира, че вградените възли ще запазят форматирането на родителския абзац. Методът също така ще изпълнява проверки на възлите, преминали като параметри и хвърля изключение, ако някой от възлите е невалиден. Параметрите, които трябва да бъдат предадени на този метод са::
-
StartNode и EndNode. Първите два параметъра са възлите, които определят къде да започне извличането на съдържанието и да завърши съответно. Тези възли могат да бъдат както на блоково ниво (абзац, таблица), така и на вътрешно ниво (напр.бягане, FieldStart, BookmarkStart и т.н.):
- За да подадете поле, трябва да подадете съответния обект FieldStart.
- За да се премине отметките, трябва да се преминат възлите BookmarkStart и BookmarkEnd.
- За подаване на коментари трябва да се използват възли CommentRangeStart и CommentRangeEnd.
-
IsInclusive. Определя дали маркерите са включени в екстракцията или не. Ако тази опция е настроена на невярно и са предадени един и същ възел или последователни възли, ще бъде върнат празен списък.:
- Ако е подаден възел FieldStart, тази опция определя дали цялото поле трябва да бъде включено или изключено.
- Ако е подаден възел BookmarkStart или BookmarkEnd, тази опция определя дали отметката е включена или само съдържанието между диапазона на отметките.
- Ако е подаден възел CommentRangeStart или CommentRangeEnd, тази опция определя дали самият коментар трябва да бъде включен или само съдържанието в диапазона на коментара.
Прилагането на ExtractContent метод можете да намерите ето. Този метод ще бъде посочен в сценариите в тази статия.
Също така ще дефинираме персонализиран метод за лесно генериране на документ от извлечени възли. Този метод се използва в много от сценариите по-долу и просто създава нов документ и внася извлеченото съдържание в него.
Следващият пример за код показва как да вземете списък с възли и да ги вмъкнете в нов документ.
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
static SharedPtr<Document> GenerateDocument(SharedPtr<Document> srcDoc, SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> nodes) | |
{ | |
auto dstDoc = MakeObject<Document>(); | |
// Remove the first paragraph from the empty document. | |
dstDoc->get_FirstSection()->get_Body()->RemoveAllChildren(); | |
// Import each node from the list into the new document. Keep the original formatting of the node. | |
auto importer = MakeObject<NodeImporter>(srcDoc, dstDoc, ImportFormatMode::KeepSourceFormatting); | |
for (const auto& node : nodes) | |
{ | |
SharedPtr<Node> importNode = importer->ImportNode(node, true); | |
dstDoc->get_FirstSection()->get_Body()->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-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto startPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->get_Body()->GetChild(NodeType::Paragraph, 6, true)); | |
auto endPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->get_Body()->GetChild(NodeType::Paragraph, 10, true)); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara, endPara, true); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenParagraphs.docx"); |
Извличане на съдържание Между различни видове възли
Можем да извлечем съдържание между всякакви комбинации от блокове или инлайн възли. В този сценарий по-долу ще извлечем съдържанието между първия параграф и таблицата във втория раздел включително. Получаваме възлите на маркерите, като извикаме метода Body.FirstParagraph
и GetChild във втория раздел на документа, за да извлечем съответните възли на абзаца и таблицата. За лека вариация нека вместо това да дублираме съдържанието и да го вмъкнем под оригинала.
Следният пример за код показва как да извлечете съдържанието между абзац и таблица, като използвате метода ExtractContent
:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto startPara = System::ExplicitCast<Paragraph>(doc->get_LastSection()->GetChild(NodeType::Paragraph, 2, true)); | |
auto endTable = System::ExplicitCast<Table>(doc->get_LastSection()->GetChild(NodeType::Table, 0, true)); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara, endTable, true); | |
// Let's reverse the array to make inserting the content back into the document easier. | |
extractedNodes->Reverse(); | |
for (SharedPtr<Node> extractedNode : extractedNodes) | |
// Insert the last node from the reversed list. | |
endTable->get_ParentNode()->InsertAfter(extractedNode, endTable); | |
doc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBlockLevelNodes.docx"); |
Извличане на съдържание между абзаците въз основа на стила
Може да се наложи да извлечете съдържанието между абзаци от едни и същи или различни стилове, например между абзаци, маркирани със заглавни стилове. Кодът по-долу показва как да се постигне това. Това е прост пример, който ще извлече съдържанието между първата инстанция на стиловете “Heading 1” и “заглавка 3”, без да извлича и заглавията. За да направим това, задаваме последния параметър на невярно, което указва, че маркерните възли не трябва да бъдат включени.
При правилно изпълнение това трябва да се изпълнява в цикъл, за да се извлече съдържание между всички параграфи на тези стилове от документа. Извлеченото съдържание се копира в нов документ.
Следващият пример за код показва как да извличате съдържание между абзаци с конкретни стилове, като използвате метода ExtractContent
:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
// Gather a list of the paragraphs using the respective heading styles. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> parasStyleHeading1 = ParagraphsByStyleName(doc, u"Heading 1"); | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> parasStyleHeading3 = ParagraphsByStyleName(doc, u"Heading 3"); | |
// Use the first instance of the paragraphs with those styles. | |
SharedPtr<Node> startPara1 = parasStyleHeading1->idx_get(0); | |
SharedPtr<Node> endPara1 = parasStyleHeading3->idx_get(0); | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara1, endPara1, false); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenParagraphStyles.docx"); |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
static SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> ParagraphsByStyleName(SharedPtr<Document> doc, System::String styleName) | |
{ | |
// Create an array to collect paragraphs of the specified style. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> paragraphsWithStyle = | |
MakeObject<System::Collections::Generic::List<SharedPtr<Paragraph>>>(); | |
SharedPtr<NodeCollection> paragraphs = doc->GetChildNodes(NodeType::Paragraph, true); | |
// Look through all paragraphs to find those with the specified style. | |
for (const auto& paragraph : System::IterateOver<Paragraph>(paragraphs)) | |
{ | |
if (paragraph->get_ParagraphFormat()->get_Style()->get_Name() == styleName) | |
{ | |
paragraphsWithStyle->Add(paragraph); | |
} | |
} | |
return paragraphsWithStyle; | |
} |
Извличане На Съдържание Между Конкретни Серии
Можете също така да извличате съдържание между инлайн възли, като Run. Runs от различни параграфи могат да се предават като маркери. Кодът по-долу показва как да извлечете конкретен текст между един и същ Paragraph възел.
Следващият пример за код показва как да извличате съдържание между конкретни серии от един и същ абзац, като използвате метода ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto para = System::ExplicitCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 7, true)); | |
SharedPtr<Run> startRun = para->get_Runs()->idx_get(1); | |
SharedPtr<Run> endRun = para->get_Runs()->idx_get(4); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startRun, endRun, true); | |
for (SharedPtr<Node> extractedNode : extractedNodes) | |
std::cout << extractedNode->ToString(SaveFormat::Text) << std::endl; |
Извличане на съдържание с помощта на поле
За да се използва поле като маркер, трябва да се премине възелът FieldStart
. Последният параметър на метода ExtractContent
ще определи дали цялото поле трябва да бъде включено или не. Нека извлечем съдържанието между полето за обединяване “FullName " и абзац в документа. Ние използваме MoveToMergeField метода на DocumentBuilder клас. Това ще върне FieldStart възела от името на полето за обединяване, предадено към него.
В нашия случай нека зададем последния параметър, предаден на метода ExtractContent, за да изключим полето от екстракцията. Ние ще превърнем извлеченото съдържание в PDF.
Следният пример за код показва как да извлечете съдържание между конкретно поле и абзац в документа, като използвате метода ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto builder = MakeObject<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(u"Fullname", false, false); | |
// The builder cursor should be positioned at the start of the field. | |
auto startField = System::ExplicitCast<FieldStart>(builder->get_CurrentNode()); | |
auto endPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->GetChild(NodeType::Paragraph, 5, true)); | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startField, endPara, false); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentUsingField.docx"); |
Извличане на съдържание от отметка
В документ Съдържанието, което е дефинирано в отметка, се капсулира от възлите BookmarkStart
и BookmarkEnd. Съдържанието, намерено между тези два възела, съставлява отметката. Можете да подавате всеки от тези възли като маркер, дори и такива от различни отметки, стига началният маркер да се показва преди крайния маркер в документа. Ще извлечем това съдържание в нов документ, като използваме кода по-долу. Опцията IsInclusive параметър показва как да запазите или отхвърлите отметката.
Следващият пример за код показва как да извлечете съдържанието, свързано с отметка, като използвате метода ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
SharedPtr<Bookmark> bookmark = doc->get_Range()->get_Bookmarks()->idx_get(u"Bookmark1"); | |
SharedPtr<BookmarkStart> bookmarkStart = bookmark->get_BookmarkStart(); | |
SharedPtr<BookmarkEnd> bookmarkEnd = bookmark->get_BookmarkEnd(); | |
// Firstly, extract the content between these nodes, including the bookmark. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesInclusive = | |
ExtractContentHelper::ExtractContent(bookmarkStart, bookmarkEnd, true); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesInclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx"); | |
// Secondly, extract the content between these nodes this time without including the bookmark. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesExclusive = | |
ExtractContentHelper::ExtractContent(bookmarkStart, bookmarkEnd, false); | |
dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesExclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx"); |
Извличане на съдържание от коментар
Коментарът се състои от възли CommentRangeStart, CommentRangeEnd и коментар. Всички тези възли са вградени. Първите два възела капсулират съдържанието в документа, към който се отнася коментарът, както се вижда на екранната снимка по-долу.
Самият възел Comment е InlineStory, който може да съдържа абзаци и да се изпълнява. Тя представлява съобщението на коментара, както се вижда като коментар балон в екрана за визуализация. Тъй като този възел е инлайн и потомък на тяло, можете също да извлечете съдържанието от това съобщение.
Коментарът съдържа заглавието, първия параграф и таблицата във втория раздел. Нека извлечем този коментар в нов документ. Опцията IsInclusive диктува дали коментарът да бъде запазен или отхвърлен.
Следващият пример за код показва как да направите това:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto commentStart = System::ExplicitCast<CommentRangeStart>(doc->GetChild(NodeType::CommentRangeStart, 0, true)); | |
auto commentEnd = System::ExplicitCast<CommentRangeEnd>(doc->GetChild(NodeType::CommentRangeEnd, 0, true)); | |
// Firstly, extract the content between these nodes including the comment as well. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesInclusive = | |
ExtractContentHelper::ExtractContent(commentStart, commentEnd, true); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesInclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx"); | |
// Secondly, extract the content between these nodes without the comment. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesExclusive = | |
ExtractContentHelper::ExtractContent(commentStart, commentEnd, false); | |
dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesExclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx"); |
Как да извлечете съдържание, като използвате DocumentVisitor
Използвайте клас DocumentVisitor, за да реализирате този сценарий на използване. Този клас съответства на добре познатия дизайн на посетителите. С DocumentVisitor, можете да дефинирате и изпълнявате персонализирани операции, които изискват изброяване върху дървото на документа.
DocumentVisitor
Всеки метод DocumentVisitor.VisitXXX връща VisitorAction стойност, която контролира изброяването на възли. Можете да поискате или да продължите изброяването, да пропуснете текущия възел (но да продължите изброяването), или да спрете изброяването на възли.
Това са стъпките, които трябва да следвате, за да определите и извлечете програмно различни части от документ.:
- Създаване на клас, получен от DocumentVisitor
- Заместете и осигурете имплементации за някои или всички методи DocumentVisitor.VisitXXX за извършване на някои персонализирани операции
- Обадете се
Node.Accept
на възела, от който искате да започнете изброяването. Например, ако искате да изброите целия документ, използвайтеDocument.Accept
DocumentVisitor
Този пример показва как да използвате Посетителския модел, за да добавите нови операции към обектния модел Aspose.Words. В този случай създаваме прост конвертор на документи в текстов формат:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto convertToPlainText = MakeObject<ExtractContent::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. | |
std::cout << convertToPlainText->GetText() << std::endl; |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
/// <summary> | |
/// Simple implementation of saving a document in the plain text format. Implemented as a Visitor. | |
/// </summary> | |
class ConvertDocToTxt : public DocumentVisitor | |
{ | |
public: | |
ConvertDocToTxt() : mIsSkipText(false) | |
{ | |
mIsSkipText = false; | |
mBuilder = MakeObject<System::Text::StringBuilder>(); | |
} | |
/// <summary> | |
/// Gets the plain text of the document that was accumulated by the visitor. | |
/// </summary> | |
String GetText() | |
{ | |
return mBuilder->ToString(); | |
} | |
/// <summary> | |
/// Called when a Run node is encountered in the document. | |
/// </summary> | |
VisitorAction VisitRun(SharedPtr<Run> run) override | |
{ | |
AppendText(run->get_Text()); | |
// Let the visitor continue visiting other nodes. | |
return VisitorAction::Continue; | |
} | |
/// <summary> | |
/// Called when a FieldStart node is encountered in the document. | |
/// </summary> | |
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override | |
{ | |
ASPOSE_UNUSED(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> | |
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override | |
{ | |
ASPOSE_UNUSED(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> | |
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override | |
{ | |
ASPOSE_UNUSED(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> | |
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override | |
{ | |
ASPOSE_UNUSED(paragraph); | |
// When outputting to plain text we output Cr+Lf characters. | |
AppendText(ControlChar::CrLf()); | |
return VisitorAction::Continue; | |
} | |
VisitorAction VisitBodyStart(SharedPtr<Body> body) override | |
{ | |
ASPOSE_UNUSED(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(u"*** Body Started ***\r\n"); | |
return VisitorAction::Continue; | |
} | |
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override | |
{ | |
ASPOSE_UNUSED(body); | |
mBuilder->Append(u"*** Body Ended ***\r\n"); | |
return VisitorAction::Continue; | |
} | |
/// <summary> | |
/// Called when a HeaderFooter node is encountered in the document. | |
/// </summary> | |
VisitorAction VisitHeaderFooterStart(SharedPtr<HeaderFooter> headerFooter) override | |
{ | |
ASPOSE_UNUSED(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::SkipThisNode; | |
} | |
private: | |
SharedPtr<System::Text::StringBuilder> mBuilder; | |
bool mIsSkipText; | |
/// <summary> | |
/// Adds text to the current output. Honors the enabled/disabled output flag. | |
/// </summary> | |
void AppendText(String text) | |
{ | |
if (!mIsSkipText) | |
{ | |
mBuilder->Append(text); | |
} | |
} | |
}; |
Как да извлечете само текст
Начините за извличане на текст от документа са::
- Използвайте 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 на възел:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(); | |
auto builder = MakeObject<DocumentBuilder>(doc); | |
builder->InsertField(u"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. | |
std::cout << (String(u"ToString() Result: ") + doc->ToString(SaveFormat::Text)) << std::endl; |
Употреба 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-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Document.docx"); | |
doc->Save(ArtifactsDir + u"BaseConversions.DocxToTxt.txt"); |
Извличане на изображения от форми
Може да се наложи да извлечете изображения на документи, за да изпълните някои задачи. Aspose.Words ви позволява да направите това, както добре.
Следният пример за код показва как да извлечете изображения от документ:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Images.docx"); | |
SharedPtr<NodeCollection> shapes = doc->GetChildNodes(NodeType::Shape, true); | |
int imageIndex = 0; | |
for (const auto& shape : System::IterateOver<Shape>(shapes)) | |
{ | |
if (shape->get_HasImage()) | |
{ | |
String imageFileName = | |
String::Format(u"Image.ExportImages.{0}_{1}", imageIndex, FileFormatUtil::ImageTypeToExtension(shape->get_ImageData()->get_ImageType())); | |
// 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->get_ImageData()->Save(ArtifactsDir + imageFileName); | |
imageIndex++; | |
} | |
} |