DocumentVisitorVisitCellEnd Method |
Namespace: Aspose.Words
public void TableToText() { // Open the document that has tables we want to print the info of Document doc = new Document(MyDir + "DocumentVisitor-compatible features.docx"); // Create an object that inherits from the DocumentVisitor class TableInfoPrinter visitor = new TableInfoPrinter(); // Accepting a visitor lets it start traversing the nodes in the document, // starting with the node that accepted it to then recursively visit every child doc.Accept(visitor); // Once the visiting is complete, we can retrieve the result of the operation, // that in this example, has accumulated in the visitor Console.WriteLine(visitor.GetText()); } /// <summary> /// This Visitor implementation prints information about and contents of all tables encountered in the document. /// </summary> public class TableInfoPrinter : DocumentVisitor { public TableInfoPrinter() { mBuilder = new StringBuilder(); mVisitorIsInsideTable = false; } /// <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 override VisitorAction VisitRun(Run run) { // We want to print the contents of runs, but only if they consist of text from cells // So we are only interested in runs that are children of table nodes if (mVisitorIsInsideTable) IndentAndAppendLine("[Run] \"" + run.GetText() + "\""); return VisitorAction.Continue; } /// <summary> /// Called when a Table is encountered in the document. /// </summary> public override VisitorAction VisitTableStart(Table table) { int rows = 0; int columns = 0; if (table.Rows.Count > 0) { rows = table.Rows.Count; columns = table.FirstRow.Count; } IndentAndAppendLine("[Table start] Size: " + rows + "x" + columns); mDocTraversalDepth++; mVisitorIsInsideTable = true; return VisitorAction.Continue; } /// <summary> /// Called when the visiting of a Table node is ended. /// </summary> public override VisitorAction VisitTableEnd(Table table) { mDocTraversalDepth--; IndentAndAppendLine("[Table end]"); mVisitorIsInsideTable = false; return VisitorAction.Continue; } /// <summary> /// Called when a Row node is encountered in the document. /// </summary> public override VisitorAction VisitRowStart(Row row) { string rowContents = row.GetText().TrimEnd(new []{ '\u0007', ' ' }).Replace("\u0007", ", "); int rowWidth = row.IndexOf(row.LastCell) + 1; int rowIndex = row.ParentTable.IndexOf(row); string rowStatusInTable = row.IsFirstRow && row.IsLastRow ? "only" : row.IsFirstRow ? "first" : row.IsLastRow ? "last" : ""; if (rowStatusInTable != "") { rowStatusInTable = $", the {rowStatusInTable} row in this table,"; } IndentAndAppendLine($"[Row start] Row #{++rowIndex}{rowStatusInTable} width {rowWidth}, \"{rowContents}\""); mDocTraversalDepth++; return VisitorAction.Continue; } /// <summary> /// Called when the visiting of a Row node is ended. /// </summary> public override VisitorAction VisitRowEnd(Row row) { mDocTraversalDepth--; IndentAndAppendLine("[Row end]"); return VisitorAction.Continue; } /// <summary> /// Called when a Cell node is encountered in the document. /// </summary> public override VisitorAction VisitCellStart(Cell cell) { Row row = cell.ParentRow; Table table = row.ParentTable; string cellStatusInRow = cell.IsFirstCell && cell.IsLastCell ? "only" : cell.IsFirstCell ? "first" : cell.IsLastCell ? "last" : ""; if (cellStatusInRow != "") { cellStatusInRow = $", the {cellStatusInRow} cell in this row"; } IndentAndAppendLine($"[Cell start] Row {table.IndexOf(row) + 1}, Col {row.IndexOf(cell) + 1}{cellStatusInRow}"); mDocTraversalDepth++; return VisitorAction.Continue; } /// <summary> /// Called when the visiting of a Cell node is ended in the document. /// </summary> public override VisitorAction VisitCellEnd(Cell cell) { mDocTraversalDepth--; IndentAndAppendLine("[Cell end]"); return VisitorAction.Continue; } /// <summary> /// Append a line to the StringBuilder and indent it depending on how deep the visitor is into the document tree. /// </summary> /// <param name="text"></param> private void IndentAndAppendLine(string text) { for (int i = 0; i < mDocTraversalDepth; i++) { mBuilder.Append("| "); } mBuilder.AppendLine(text); } private bool mVisitorIsInsideTable; private int mDocTraversalDepth; private readonly StringBuilder mBuilder; }
public void RemoveHiddenContentFromDocument() { // Open the document we want to remove hidden content from. Document doc = new Document(MyDir + "Hidden content.docx"); // Create an object that inherits from the DocumentVisitor class RemoveHiddenContentVisitor hiddenContentRemover = new RemoveHiddenContentVisitor(); // This is the well known Visitor pattern. Get the model to accept a visitor // The model will iterate through itself by calling the corresponding methods // on the visitor object (this is called visiting) // We can run it over the entire the document like so doc.Accept(hiddenContentRemover); // Or we can run it on only a specific node Paragraph para = (Paragraph) doc.GetChild(NodeType.Paragraph, 4, true); para.Accept(hiddenContentRemover); // Or over a different type of node like below Table table = (Table) doc.GetChild(NodeType.Table, 0, true); table.Accept(hiddenContentRemover); doc.Save(ArtifactsDir + "Font.RemoveHiddenContentFromDocument.doc"); } /// <summary> /// This class when executed will remove all hidden content from the Document. Implemented as a Visitor. /// </summary> public class RemoveHiddenContentVisitor : DocumentVisitor { /// <summary> /// Called when a FieldStart node is encountered in the document. /// </summary> public override VisitorAction VisitFieldStart(FieldStart fieldStart) { // If this node is hidden, then remove it. if (IsHidden(fieldStart)) fieldStart.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a FieldEnd node is encountered in the document. /// </summary> public override VisitorAction VisitFieldEnd(FieldEnd fieldEnd) { if (IsHidden(fieldEnd)) fieldEnd.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a FieldSeparator node is encountered in the document. /// </summary> public override VisitorAction VisitFieldSeparator(FieldSeparator fieldSeparator) { if (IsHidden(fieldSeparator)) fieldSeparator.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a Run node is encountered in the document. /// </summary> public override VisitorAction VisitRun(Run run) { if (IsHidden(run)) run.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a Paragraph node is encountered in the document. /// </summary> public override VisitorAction VisitParagraphStart(Paragraph paragraph) { if (IsHidden(paragraph)) paragraph.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a FormField is encountered in the document. /// </summary> public override VisitorAction VisitFormField(FormField formField) { if (IsHidden(formField)) formField.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a GroupShape is encountered in the document. /// </summary> public override VisitorAction VisitGroupShapeStart(GroupShape groupShape) { if (IsHidden(groupShape)) groupShape.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a Shape is encountered in the document. /// </summary> public override VisitorAction VisitShapeStart(Shape shape) { if (IsHidden(shape)) shape.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a Comment is encountered in the document. /// </summary> public override VisitorAction VisitCommentStart(Comment comment) { if (IsHidden(comment)) comment.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a Footnote is encountered in the document. /// </summary> public override VisitorAction VisitFootnoteStart(Footnote footnote) { if (IsHidden(footnote)) footnote.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when visiting of a Table node is ended in the document. /// </summary> public override VisitorAction VisitTableEnd(Table table) { // At the moment there is no way to tell if a particular Table/Row/Cell is hidden. // Instead, if the content of a table is hidden, then all inline child nodes of the table should be // hidden and thus removed by previous visits as well. This will result in the container being empty // so if this is the case we know to remove the table node. // // Note that a table which is not hidden but simply has no content will not be affected by this algorithm, // as technically they are not completely empty (for example a properly formed Cell will have at least // an empty paragraph in it) if (!table.HasChildNodes) table.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when visiting of a Cell node is ended in the document. /// </summary> public override VisitorAction VisitCellEnd(Cell cell) { if (!cell.HasChildNodes && cell.ParentNode != null) cell.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when visiting of a Row node is ended in the document. /// </summary> public override VisitorAction VisitRowEnd(Row row) { if (!row.HasChildNodes && row.ParentNode != null) row.Remove(); return VisitorAction.Continue; } /// <summary> /// Called when a SpecialCharacter is encountered in the document. /// </summary> public override VisitorAction VisitSpecialChar(SpecialChar specialChar) { if (IsHidden(specialChar)) specialChar.Remove(); return VisitorAction.Continue; } /// <summary> /// Returns true if the node passed is set as hidden, returns false if it is visible. /// </summary> private static bool IsHidden(Node node) { switch (node) { case Inline currentNode: // If the node is Inline then cast it to retrieve the Font property which contains the hidden property return currentNode.Font.Hidden; default: switch (node.NodeType) { case NodeType.Paragraph: { // If the node is a paragraph cast it to retrieve the ParagraphBreakFont which contains the hidden property Paragraph para = (Paragraph) node; return para.ParagraphBreakFont.Hidden; } default: switch (node) { case ShapeBase shape: // Node is a shape or groupshape return shape.Font.Hidden; case InlineStory inlineStory: // Node is a comment or footnote return inlineStory.Font.Hidden; } break; } break; } // A node that is passed to this method which does not contain a hidden property will end up here // By default nodes are not hidden so return false return false; } }