user2185592
user2185592

Reputation: 388

Inserting RTF content in existing text range in Word using Interop assemblies

I'm working on generating the complex report from my WPF application in word format. Some of the content, I need to insert in the report is of RTF type. I'm not able to figure out the way to insert the RTF content at the end of particular text range.

As of now, I only know one way of adding the RTF content to word document programmatically and that is by setting the RTF content in clipboard and then paste the data back. But I'm not able to find the way to paste the content exactly after the existing content of text range.

I tried to add the paragraph at the end of text range and paste my RTF content to it but after looping through multiple paste operation final content I see in document is jumbled up and not in correct order.

enter image description here

Following is the code snippet I have tried :

        public partial class MainWindow : System.Windows.Window
{
    private List<TestData> TestDatas = new List<TestData>();

    public MainWindow()
    {
        InitializeComponent();

        TestDatas.Add(new TestData() { Title = "Phrase 01", Description = @"Any RTF Text" });
        TestDatas.Add(new TestData() { Title = "Phrase 02", Description = @"Any RTF Text" });
        TestDatas.Add(new TestData() { Title = "Phrase 03", Description = @"Any RTF Text" });
        TestDatas.Add(new TestData() { Title = "Phrase 04", Description = @"Any RTF Text" });
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {

        Object oMissing = System.Reflection.Missing.Value;

        var templateFilePath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Report Template\"));
        Object oTemplatePath = templateFilePath + @"phrases.dotx";
        Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
        Document wordDoc = new Document();

        wordDoc = wordApp.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing);
        Selection sel = null;

        foreach (Field myMergeField in wordDoc.Fields)
        {
            myMergeField.Select();
            sel = wordApp.Selection;
            sel.Delete();

            Range initialRange = sel.Range;

            foreach (var data in TestDatas)
            {
                Range appendedRange;
                var textRange = AppendToRange(initialRange, data.Title + Environment.NewLine, out appendedRange, wordDoc);
                appendedRange.Bold = 1;
                appendedRange.Font.Size = 11;
                appendedRange.Underline = WdUnderline.wdUnderlineSingle;

                var para = textRange.Paragraphs.Add();
            }
        }

        wordDoc.SaveAs("myfile.doc");
        wordApp.Application.Quit();
    }

    private Range AppendToRange(Range range, string appendText, out Range appendedRange, Document wordDoc)
    {
        // Fetch indexes
        object oldStartPosition = range.Start;
        object oldEndPosition = range.End;
        object newEndPosition = (int)oldEndPosition + appendText.Length;

        // Append the text
        range.InsertAfter(appendText);

        // Define the range of the appended text
        appendedRange = wordDoc.Range(ref oldEndPosition, ref newEndPosition);

        // Return the range of the new combined range
        return wordDoc.Range(ref oldStartPosition, ref newEndPosition);
    }

}

public class TestData
{
    public string Title { get; set; }

    public string Description { get; set; }
}

Is there a way to insert RTF content properly at particular location in text range?

Upvotes: 0

Views: 1842

Answers (1)

Cindy Meister
Cindy Meister

Reputation: 25693

Try working with a Range object and "collapse" the Range as you go. I haven't tested the following, just off the top of my head...

var para = textRange.Paragraphs.Add();
var rng = para.Range;
Clipboard.SetData(System.Windows.DataFormats.Rtf, text);
rng.PasteSpecial(DataType: Microsoft.Office.Interop.Word.WdPasteDataType.wdPasteRTF);
rng.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
//Alternative to insert a new paragraph
rng.Text = "\n";
//prepare for the next entry, for illustration - of course you'd built this into a loop
rng.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
Clipboard.SetData(System.Windows.DataFormats.Rtf, otherText);
rng.PasteSpecial(DataType: Microsoft.Office.Interop.Word.WdPasteDataType.wdPasteRTF);

Upvotes: 1

Related Questions