Format of a insert rtf field with mail merge

Hello,I am wondering if there is any coding measures that need to be undertaken to get a rtf field inserted into a mailmerge field in a doc.MailMerge.ExecuteRegions call.

Will just sticking the rtf in a object will do? Do I need to create a wrapper or anything?

Thank you

Andrew

Sorry, I don’t quite understand what do you mean by RTF field. If you need a way of inserting text in RTF format into a document, like DocumentBuilder.InsertHtml method for inserting HTML, then it is not implemented yet but we will implement it later.

Hello miklovan, Is there any way to insert rtf at all?

What measures do you suggest when requirements dictate this?

Any there any work arounds for this?

Thank you Andrew

Yes, I think we can make a workaround for this one. Hold on., I will ask our lead RTF developer to help you in this matter.

Hi Andrew,

First of all, could you please post the RTF code of the field to review? Is it a fragment of RTF text or a complete RTF document? The point is that an RTF document consists of two major parts - document header and document body. Document header contains some important tables like color table, font table, stylesheet etc so if the header is omitted, it’s impossible to determine the color of the text, the font of the text, and so on. However, if it is suitable for you, you can surely insert RTF fragments without the header - our RTF importer is resilient enough to accept such fragments. Here is a sample code showing the idea:

[Test]
public void TestInsertRtf()
{
    Document doc = TestUtil.Open(@"Defects\TestInsertRtf.doc");
    DocumentBuilder builder = new DocumentBuilder(doc);
    builder.MoveToBookmark("bm1", true, true);
    InsertRtf(builder, @"{\b\i Hello}");
    builder.MoveToBookmark("bm2", true, true);
    InsertRtf(builder, @"\pard \qc {Good-bye\par}");
    TestUtil.SaveShow(doc, @"Defects\TestInsertRtf Out.doc");
}

private void InsertRtf(DocumentBuilder builder, string rtf)
{
    string rtfDocumentHead = @"{\rtf1";
    string rtfDocumentEnd = @"}";
    string rtfDocumentString = rtfDocumentHead + rtf + rtfDocumentEnd;
    MemoryStream stream = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(rtfDocumentString));
    Document doc = new Document(stream, null, LoadFormat.Rtf, null);
    builder.Writeln();
    foreach (Node srcNode in doc.FirstSection.Body)
    {
        Node importedNode = builder.Document.ImportNode(srcNode, true, ImportFormatMode.KeepSourceFormatting);
        builder.CurrentParagraph.ParentNode.InsertBefore(importedNode, builder.CurrentParagraph);
    }
}

Hello DimtryV, thank you for you last post it cleared a lot of issues in my mind.I see that I can work successfully with rtf.

I have the job to process data to building a table with data of fields of text and one of Rich text.

With the loading of a document,can I use an existing document in building process, rather than using this call you have placed:

Document doc = new Document(stream, null, LoadFormat.Rtf, null);

I want to just pass into the insertRtf method the document object and use it on the field within it.

Such that I have a bunch of fields in my document and one of them can be a rtf filed if I choose,so dynamically I select it to be rtf and send across the Document object in build proecss and the field value .

Thank you

Andrew

Andrew,

I composed the code sample in order to show you how to insert a fragment of RTF into your document. So does the RTF you need to insert represent a part of the document or a whole document (starts with {rtf1)?

Also, correct me if I misunderstood your scenario: during mail merge, you need to insert into some merge fields document nodes created from an RTF text instead of a simple text string.

Please make clear these two points and we will proceed.

Hello DmitryV, thank you

I am using the DocumentBuilder object to build the document.I am building a table and inserting cells.

Yes the rtf fields start with prefix {rtf1.

  1. I need to insert a rtf fragment from data that represents only a document fragment.
  2. I am building my document with a builder creating a table with simple text and rtf text nodes created from an RTF text instead of a simple text string. (I am not using Merge Fileds for the rtf and all fields in the table where rtf will be used)

I am using a seperate SuppDoc Document objects to be built seperately and appended.

So I need to use the SuppDoc Document object to use when I insert the rtf text into a table call with a WriteLn() call.

Thank you

Andrew

Andrew,

So, as far as I understand, all comes to the task of inserting a document object to a table cell, doesn’t it? At least, since you claim your RTF does represent a complete document (starts with {\rtf1), you can easily load it into a document without any tricks in a way like this:

string rtf = @"{\rtf1 {\b\i Very sparse but valid RTF.}}";
MemoryStream stream = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(rtf));
Document rtfDoc = new Document(stream);

Then you need to insert this document into a table cell, don’t you? If so, please read the pollowing topic first:

https://docs.aspose.com/words/net/insert-and-append-documents/

See the section Inserting the content of one document to another at different locations. Consider the code sample from there. It contains the InsertDocument method which you should copy to your code. Now if you have a DocumentBuilder object that has just inserted a table cell, call InsertDocument as follows:

InsertDocument(builder.CurrentNode, rtfDoc);

If you experience any problems implementing this solution, please let me know.

Hello DmitryV, I have recieved an exception on trying to execute the rtf processing method you have provided.

Of that:

[System.NotSupportedException] = {"The file is in RTF format and importing RTF files is not yet supported."}

on processing rich text fragment from

MemoryStream stream = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(rtf));
// recieved a valid rtf fragment
// exception caused at this line.
Document rtfDoc = new Document(stream); //here error was raised.

Is there some case of preparation or settings that are not marked here?

The rtf fragment is:

"{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil Arial;}}\n{\\colortbl ;\\red0\\green0\\blue0;}\n\\viewkind4\\uc1\\pard\\b\\fs20 Medical underwriting requirements\\b0\\f1\\par\n\\par\n\\ul\\f0 Life Cover, TP... etc

If you could help me solve this problem most appreciated in advance.

Andrew

Hi Andrew,

Apparently you are using an old version of Aspose.Words. Please upgrade to the latest v4.1.1.

Hello DmitryV, thank you the rtf shows in the cell. I want to add a line of text underneath this rtf in the cell.

When I do this it is added to the top of the cell even when I add a special line break under the rtf text.

Is there some special method to do this like insertAfterNode.ParentNode;?

Thank you Andrew

Andrew,

You can use a document builder to move to the end of the cell and insert the text. To move to the end of the cell, use something like this:

builder.MoveToCell(tableIndex, rowIndex, columnIndex, -1);

If it does not work in your case, please post your code used for the insertion.

Hello DimtryV, I am creating my table dynamically and do not know how to gain the tableIndex, rowIndex, columnIndex indexs for the builder.MoveToCell(tableIndex, rowIndex, columnIndex, -1); call on the current cell as I do not have the row and cell, column number. How do I gain these indexs if I am using builder in the current cell where I wish this call to proceed for?

Regards Andrew

Please post a snippet of code used to insert the cell and I will try to modify it as appropriate.

Hello DimtryV, I have this code to perform the insert rtf text and the score text underneath it in the Same Cell.As discussed there is an issue where I cannot put the text below the rtf text following a rtf insert.The Text just stays above the rtf text obviously I need to position some cursor to below the rtf text but how?

aspLibUtil.InsertRtf( suppDoc, builder, productTextFeaturesStr ); //write line
public void InsertRtf(Document suppDoc, DocumentBuilder builder, string rtf)
{
    MemoryStream stream = new MemoryStream(System.Text.Encoding.ASCII.GetBytes(rtf));
    Document rtfDoc = new Document(stream);
    Paragraph paragraph = builder.InsertParagraph();
    InsertDocument(paragraph, rtfDoc);
}

public void InsertDocument(Node insertAfterNode, Document srcDoc)
{
    // We need to make sure that the specified node is either pargraph or table.
    if (!((insertAfterNode.NodeType == NodeType.Paragraph) || (insertAfterNode.NodeType == NodeType.Table)))
        throw new ArgumentException("The destination node should be either paragraph or table.");
    // We will be inserting into the parent of the destination paragraph.
    CompositeNode dstStory = insertAfterNode.ParentNode;
    // This object will be translating styles and lists during the import.
    NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting);
    // Loop through all sections in the source document.
    foreach (Section srcSection in srcDoc.Sections)
    {
        // Loop through all block level nodes (paragraphs and tables) in the body of the section.
        foreach (Node srcNode in srcSection.Body)
        {
            // Do not insert node if it is a last empty paragarph in the section.
            Paragraph para = srcNode as Paragraph;
            if ((para != null) && para.IsEndOfSection && !para.HasChildNodes)
                break;
            // This creates a clone of the node, suitable for insertion into the destination document.
            Node newNode = importer.ImportNode(srcNode, true);
            // Insert new node after the reference node.
            dstStory.InsertAfter(newNode, insertAfterNode);
            insertAfterNode = newNode;
        }
    }
    // Ensure that destination story ends with a paragraph.
    if (!(dstStory.LastChild is Paragraph))
        dstStory.AppendChild(new Paragraph(dstStory.Document));
}

Here the code to put the formatting on the text of score.Score Text must be under the rtf inserted text.

if (rtfField && featChkCommonF.isScoreable)
{
    // builder.MoveToCell(0, 0, 0, -1);
    builder.Write(scoreText);
}

I am inserting the rtf into a cell from a selected amount of options on selection choices, here it is dynamic and I just populate on the choices made by the client.

Thank You

Andrew

If you have a reference to the cell you are inserting into then you can reposition the document builder in the following way:

builder.MoveTo(cell.LastParagraph.LastChild)

Please let me know if it helps,

Hello Vladimir, thanks for the code snippet. How do you find the reference to the current cell.When I am just calling builder.InsertCell(); ?

Thank you

Andrew

Just memorize the cell you are inserteing. For example:

Cell insertedCell = builder.IncertCell();

And use this reference later to reposition the builder.

Hope this helps,

Hello miklovan,I have implemented the code you defined but I still can`t position the text below the rtf field here I am:

insertedCell = omniRptLib.InsertCellReplyCellInstance( builder ); //insert cell return the reference to inserted cell as marker

To omniRptLib

public Cell InsertCellReplyCellInstance(DocumentBuilder builder)
{
    Cell insertedCell;
    insertedCell = builder.InsertCell();
    return insertedCell;
}
builder.MoveTo(insertedCell.LastParagraph.LastChild);
builder.Writeln(scoreText );

Am I using the code in the right manner?

Thank You Andrew