This example implements an extension method for RichEditDocumentServer.Document and specify a delegate that will be executed for each SubDocument in a document. This approach allows you to modify the entire document content in a single place.
Implementation Details
RichEditDocumentServer's document is split into logical parts - SubDocuments. The document body, text boxes, comments, headers and footers for different document sections are stored in separate SubDocuments. Each SubDocument contains its own textual content, fields, bookmarks, hyperlinks, images, and shapes. In scenarios when such document elements should be edited for the entire document, it's necessary to get all document SubDocuments and edit each SubDocument separately.
Files to Review
C# | Visual Basic |
---|---|
Program.cs | Program.vb |
SubDocumentHelper.cs | SubDocumentHelper.vb |
Documentation
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using System;
using DevExpress.XtraRichEdit.API.Native;
using DevExpress.XtraRichEdit;
using System.Drawing;
using System.Diagnostics;
namespace SubDocumentIterator
{
class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
using (RichEditDocumentServer wordProcessor = new RichEditDocumentServer())
{
wordProcessor.LoadDocument("template.docx");
Document document = wordProcessor.Document;
AskAction(document);
wordProcessor.SaveDocument("Modified.docx", DocumentFormat.OpenXml);
}
var p = new Process();
p.StartInfo = new ProcessStartInfo(@"Modified.docx")
{
UseShellExecute = true
};
p.Start();
}
static private void AskAction(Document document)
{
Console.WriteLine("Enter a command's index.\r\nAvailable commands:\r\n1. Update Fields\r\n2. Remove Bookmarks\r\n3. Replace Text\r\n4. Highlight Text");
var answer = Console.ReadLine();
switch (answer)
{
case "1": { document.ForEachSubDocument((subdoc => { subdoc.Fields.Update(); })); break; }
case "2":
{
document.ForEachSubDocument((subdoc =>
{
for (int i = subdoc.Bookmarks.Count - 1; i >= 0; i--)
subdoc.Bookmarks.Remove(subdoc.Bookmarks[i]);
}));
break;
}
case "3": { document.ForEachSubDocument((subdoc => { subdoc.ReplaceAll("test text", "Hello!!!", SearchOptions.None); })); break; }
case "4":
{
document.ForEachSubDocument((subdoc =>
{
DocumentRange[] ranges = subdoc.FindAll("time", SearchOptions.None);
foreach (DocumentRange range in ranges)
{
CharacterProperties cp = subdoc.BeginUpdateCharacters(range);
cp.ForeColor = Color.Red;
cp.BackColor = Color.Lavender;
subdoc.EndUpdateCharacters(cp);
}
}));
break;
}
}
Console.WriteLine("Do you want to perform another action? If no, the document is saved and opened in the Word. Y/N");
var answerReply = Console.ReadLine()?.ToLower();
if (answerReply == "y")
{
AskAction(document);
}
}
}
}
C#using DevExpress.XtraRichEdit.API.Native;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SubDocumentIterator
{
public static class SubDocumentHelper
{
public delegate void SubDocumentDelegate(SubDocument subDocument);
public static void ForEachSubDocument(this Document document, SubDocumentDelegate subDocumentProcessor)
{
subDocumentProcessor(document);
ProcessShapes(document.Shapes, subDocumentProcessor);
ProcessComments(document.Comments, subDocumentProcessor);
foreach (Section section in document.Sections)
{
ProcessSection(section, HeaderFooterType.First, subDocumentProcessor);
ProcessSection(section, HeaderFooterType.Odd, subDocumentProcessor);
ProcessSection(section, HeaderFooterType.Even, subDocumentProcessor);
}
}
private static void ProcessSection(Section section, HeaderFooterType headerFooterType, SubDocumentDelegate subDocumentProcessor)
{
if (section.HasHeader(headerFooterType))
{
SubDocument header = section.BeginUpdateHeader(headerFooterType);
subDocumentProcessor(header);
ProcessShapes(header.Shapes, subDocumentProcessor);
section.EndUpdateHeader(header);
}
if (section.HasFooter(headerFooterType))
{
SubDocument footer = section.BeginUpdateFooter(headerFooterType);
subDocumentProcessor(footer);
ProcessShapes(footer.Shapes, subDocumentProcessor);
section.EndUpdateFooter(footer);
}
}
private static void ProcessShapes(ShapeCollection shapes, SubDocumentDelegate subDocumentProcessor)
{
foreach (Shape shape in shapes)
if (shape.ShapeFormat.TextBox != null)
subDocumentProcessor(shape.ShapeFormat.TextBox.Document);
}
private static void ProcessComments(CommentCollection comments, SubDocumentDelegate subDocumentProcessor)
{
foreach (Comment comment in comments)
{
SubDocument commentSubDocument = comment.BeginUpdate();
subDocumentProcessor(commentSubDocument);
comment.EndUpdate(commentSubDocument);
}
}
}
}