Estrarre il contenuto tra i nodi di un documento
Quando si lavora con i documenti, è importante essere in grado di estrarre facilmente il contenuto da un intervallo specifico all’interno di un documento. Tuttavia, il contenuto può essere costituito da elementi complessi come paragrafi, tabelle, immagini, ecc.
Indipendentemente dal contenuto che deve essere estratto, il metodo per estrarre quel contenuto sarà sempre determinato da quali nodi sono selezionati per estrarre il contenuto tra. Questi possono essere interi corpi di testo o semplici esecuzioni di testo.
Ci sono molte situazioni possibili e quindi molti tipi di nodi diversi da considerare quando si estrae il contenuto. Ad esempio, è possibile estrarre il contenuto tra:
- Due paragrafi specifici
- Esecuzioni specifiche di testo
- Campi di vario tipo, ad esempio campi di unione
- Intervalli di inizio e fine di un segnalibro o di un commento
- Vari corpi di testo contenuti in sezioni separate
In alcune situazioni, potrebbe anche essere necessario combinare diversi tipi di nodo, ad esempio l’estrazione di contenuto tra un paragrafo e un campo o tra un’esecuzione e un segnalibro.
Questo articolo fornisce l’implementazione del codice per l’estrazione di testo tra diversi nodi, nonché esempi di scenari comuni.
Perché estrarre il contenuto
Spesso l’obiettivo di estrarre il contenuto è duplicarlo o salvarlo separatamente in un nuovo documento. Ad esempio, è possibile estrarre il contenuto e:
- Copiarlo in un documento separato
- Convertire una parte specifica di un documento in PDF o immagine
- Duplicare il contenuto nel documento molte volte
- Lavorare con il contenuto estratto separato dal resto del documento
Questo può essere facilmente ottenuto usando Aspose.Words e l’implementazione del codice qui sotto.
Algoritmo di estrazione del contenuto
Il codice in questa sezione affronta tutte le possibili situazioni sopra descritte con un metodo generalizzato e riutilizzabile. Lo schema generale di questa tecnica comporta:
- Raccolta dei nodi che dettano l’area di contenuto che verrà estratta dal documento. Il recupero di questi nodi è gestito dall’utente nel loro codice, in base a ciò che vogliono essere estratti.
- Passare questi nodi al metodo ExtractContent fornito di seguito. È inoltre necessario passare un parametro booleano che indica se questi nodi, agendo come marcatori, devono essere inclusi nell’estrazione o meno.
- Recupero di un elenco di contenuti clonati (nodi copiati) specificati da estrarre. È possibile utilizzare questo elenco di nodi in qualsiasi modo applicabile, ad esempio creando un nuovo documento contenente solo il contenuto selezionato.
Come estrarre il contenuto
Per estrarre il contenuto dal documento è necessario chiamare il metodo ExtractContent
di seguito e passare i parametri appropriati. La base di questo metodo consiste nel trovare nodi a livello di blocco (paragrafi e tabelle) e clonarli per creare copie identiche. Se i nodi marker passati sono a livello di blocco, il metodo è in grado di copiare semplicemente il contenuto su quel livello e aggiungerlo all’array.
Tuttavia, se i nodi marker sono in linea (un figlio di un paragrafo), la situazione diventa più complessa, poiché è necessario dividere il paragrafo sul nodo in linea, sia esso una corsa, campi segnalibro ecc. Il contenuto nei nodi padre clonati non presenti tra i marcatori viene rimosso. Questo processo viene utilizzato per garantire che i nodi in linea conservino ancora la formattazione del paragrafo padre. Il metodo eseguirà anche controlli sui nodi passati come parametri e genera un’eccezione se uno dei due nodi non è valido. I parametri da passare a questo metodo sono:
-
StartNode e EndNode. I primi due parametri sono i nodi che definiscono dove l’estrazione del contenuto deve iniziare e terminare rispettivamente. Questi nodi possono essere sia a livello di blocco (Paragrafo, Tabella ) che a livello di linea (ad esempio Run, FieldStart, BookmarkStart ecc.):
- Per passare un campo è necessario passare l’oggetto FieldStart corrispondente.
- Per passare i segnalibri, i nodi BookmarkStart e BookmarkEnd devono essere passati.
- Per passare i commenti, è necessario utilizzare i nodi CommentRangeStart e CommentRangeEnd.
-
IsInclusive. Definisce se i marcatori sono inclusi nell’estrazione o meno. Se questa opzione è impostata su false e vengono passati lo stesso nodo o nodi consecutivi, verrà restituito un elenco vuoto:
- Se viene passato un nodo FieldStart, questa opzione definisce se l’intero campo deve essere incluso o escluso.
- Se viene passato un nodo BookmarkStart o BookmarkEnd, questa opzione definisce se il segnalibro è incluso o solo il contenuto tra l’intervallo di segnalibri.
- Se viene passato un nodo CommentRangeStart o CommentRangeEnd, questa opzione definisce se il commento stesso deve essere incluso o solo il contenuto nell’intervallo di commenti.
L’implementazione del metodo ExtractContent è possibile trovare qui. Questo metodo verrà indicato negli scenari in questo articolo.
Definiremo anche un metodo personalizzato per generare facilmente un documento dai nodi estratti. Questo metodo viene utilizzato in molti degli scenari seguenti e crea semplicemente un nuovo documento e importa il contenuto estratto in esso.
Il seguente esempio di codice mostra come prendere un elenco di nodi e inserirli in un nuovo documento.
// 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; | |
} |
Estrarre il contenuto tra i paragrafi
Questo dimostra come utilizzare il metodo sopra per estrarre il contenuto tra paragrafi specifici. In questo caso, vogliamo estrarre il corpo della lettera trovata nella prima metà del documento. Possiamo dire che questo è tra il 7esimo e l ' 11 ° paragrafo.
Il codice sottostante esegue questa attività. I paragrafi appropriati vengono estratti utilizzando il metodo GetChild sul documento e passando gli indici specificati. Passiamo quindi questi nodi al metodo ExtractContent e dichiariamo che questi devono essere inclusi nell’estrazione. Questo metodo restituirà il contenuto copiato tra questi nodi che vengono poi inseriti in un nuovo documento.
Il seguente esempio di codice mostra come estrarre il contenuto tra paragrafi specifici utilizzando il metodo ExtractContent
sopra:
// 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"); |
Estrarre il contenuto tra diversi tipi di nodi
Possiamo estrarre il contenuto tra qualsiasi combinazione di nodi a livello di blocco o in linea. In questo scenario di seguito estrarremo il contenuto tra il primo paragrafo e la tabella nella seconda sezione in modo inclusivo. Otteniamo i nodi marcatori chiamando il metodo Body.FirstParagraph
e GetChild nella seconda sezione del documento per recuperare i nodi di paragrafo e Tabella appropriati. Per una leggera variazione cerchiamo invece di duplicare il contenuto e inserirlo sotto l’originale.
L’esempio di codice seguente mostra come estrarre il contenuto tra un paragrafo e una tabella utilizzando il metodo 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"); |
Estrarre il contenuto tra i paragrafi in base allo stile
Potrebbe essere necessario estrarre il contenuto tra paragrafi dello stesso stile o di stili diversi, ad esempio tra paragrafi contrassegnati con stili di intestazione. Il codice seguente mostra come raggiungere questo obiettivo. È un semplice esempio che estrarrà il contenuto tra la prima istanza degli stili" Intestazione 1 “e” Intestazione 3 " senza estrarre anche le intestazioni. Per fare ciò impostiamo l’ultimo parametro su false, che specifica che i nodi marker non devono essere inclusi.
In una corretta implementazione, questo dovrebbe essere eseguito in un ciclo per estrarre il contenuto tra tutti i paragrafi di questi stili dal documento. Il contenuto estratto viene copiato in un nuovo documento.
L’esempio di codice seguente mostra come estrarre il contenuto tra paragrafi con stili specifici utilizzando il metodo 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; | |
} |
Estrarre il contenuto tra esecuzioni specifiche
È possibile estrarre il contenuto tra i nodi in linea come un Run pure. Runs da paragrafi diversi può essere passato come marcatori. Il codice seguente mostra come estrarre testo specifico tra lo stesso nodo Paragraph.
L’esempio di codice seguente mostra come estrarre il contenuto tra esecuzioni specifiche dello stesso paragrafo utilizzando il metodo 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; |
Estrarre il contenuto utilizzando un campo
Per utilizzare un campo come marcatore, il nodo FieldStart
deve essere passato. L’ultimo parametro del metodo ExtractContent
definirà se l’intero campo deve essere incluso o meno. Estraiamo il contenuto tra il campo di unione “FullName " e un paragrafo nel documento. Usiamo il metodo MoveToMergeField della classe DocumentBuilder. Questo restituirà il nodo FieldStart dal nome del campo di unione passato ad esso.
Nel nostro caso impostiamo l’ultimo parametro passato al metodo ExtractContent su false per escludere il campo dall’estrazione. Renderizzeremo il contenuto estratto a PDF.
L’esempio di codice seguente mostra come estrarre il contenuto tra un campo specifico e un paragrafo nel documento utilizzando il metodo 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"); |
Estrarre il contenuto da un segnalibro
In un documento, il contenuto definito all’interno di un segnalibro viene incapsulato dai nodi BookmarkStart
e BookmarkEnd. Il contenuto trovato tra questi due nodi costituisce il segnalibro. È possibile passare uno di questi nodi come qualsiasi marcatore, anche quelli provenienti da segnalibri diversi, purché il marcatore iniziale appaia prima del marcatore finale nel documento. Estrarremo questo contenuto in un nuovo documento utilizzando il codice sottostante. L’opzione del parametro IsInclusive mostra come conservare o eliminare il segnalibro.
L’esempio di codice seguente mostra come estrarre il contenuto a cui fa riferimento un segnalibro utilizzando il metodo 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"); |
Estrarre il contenuto da un commento
Un commento è costituito dai nodi CommentRangeStart, CommentRangeEnd e Comment. Tutti questi nodi sono in linea. I primi due nodi incapsulano il contenuto del documento a cui fa riferimento il commento, come si vede nello screenshot qui sotto.
Il nodo Comment stesso è un InlineStory che può contenere paragrafi ed esecuzioni. Rappresenta il messaggio del commento visto come una bolla di commento nel riquadro di anteprima. Poiché questo nodo è in linea e un discendente di un corpo, puoi anche estrarre il contenuto dall’interno di questo messaggio.
Il commento incapsula l’intestazione, il primo paragrafo e la tabella nella seconda sezione. Estraiamo questo commento in un nuovo documento. L’opzione IsInclusive determina se il commento stesso viene mantenuto o scartato.
Il seguente esempio di codice mostra come eseguire questa operazione:
// 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"); |
Come estrarre il contenuto usando DocumentVisitor
Utilizzare la classe DocumentVisitor per implementare questo scenario di utilizzo. Questa classe corrisponde al ben noto modello di progettazione dei visitatori. Con DocumentVisitor, è possibile definire ed eseguire operazioni personalizzate che richiedono l’enumerazione sull’albero dei documenti.
DocumentVisitor
Ogni metodo DocumentVisitor.VisitXXX restituisce un valore VisitorAction che controlla l’enumerazione dei nodi. È possibile richiedere di continuare l’enumerazione, saltare il nodo corrente (ma continuare l’enumerazione) o interrompere l’enumerazione dei nodi.
Questi sono i passaggi da seguire per determinare ed estrarre a livello di codice varie parti di un documento:
- Creare una classe derivata da DocumentVisitor
- Sovrascrivere e fornire implementazioni per alcuni o tutti i metodi DocumentVisitor.VisitXXX per eseguire alcune operazioni personalizzate
- Chiamare
Node.Accept
sul nodo da cui si desidera avviare l’enumerazione. Ad esempio, se si desidera enumerare l’intero documento, utilizzareDocument.Accept
DocumentVisitor
Questo esempio mostra come utilizzare il modello Visitatore per aggiungere nuove operazioni al modello a oggetti Aspose.Words. In questo caso, creiamo un semplice convertitore di documenti in un formato di testo:
// 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); | |
} | |
} | |
}; |
Come estrarre solo testo
I modi per recuperare il testo dal documento sono:
- Utilizzare Document.Save con SaveFormat.Text per salvare come testo normale in un file o flusso
- Utilizzare Node.ToString e passare il parametro SaveFormat.Text. Internamente, questo richiama salva come testo in un flusso di memoria e restituisce la stringa risultante
- Utilizzare Node.GetText per recuperare il testo con tutti i caratteri di controllo Microsoft Word inclusi i codici di campo
- Implementare un DocumentVisitor personalizzato per eseguire l’estrazione personalizzata
Usando Node.GetText
e Node.ToString
Un documento Word può contenere caratteri di controllo che designano elementi speciali come campo, fine della cella, fine della sezione, ecc. L’elenco completo dei possibili caratteri di controllo delle parole è definito nella classe ControlChar. Il metodo Node.GetText restituisce il testo con tutti i caratteri del carattere di controllo presenti nel nodo.
La chiamata a ToString restituisce la rappresentazione in testo normale del documento solo senza caratteri di controllo.
Il seguente esempio di codice mostra la differenza tra la chiamata dei metodi GetText e ToString su un nodo:
// 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; |
Usando SaveFormat.Text
Questo esempio salva il documento come segue:
- Filtra i caratteri di campo e i codici di campo, la forma, la nota a piè di pagina, la nota di chiusura e i riferimenti ai commenti
- Sostituisce la fine del paragrafo ControlChar.Cr caratteri con ControlChar.CrLf combinazioni
- Utilizza la codifica UTF8
Il seguente esempio di codice mostra come salvare un documento in formato 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"); |
Estrai immagini da Forme
Potrebbe essere necessario estrarre le immagini del documento per eseguire alcune attività. Aspose.Words ti permette di fare anche questo.
Il seguente esempio di codice mostra come estrarre immagini da un documento:
// 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++; | |
} | |
} |