0

I have seen few codes to bold a part of range but those are specific to those examples. In my case I am writing datagridview values to word using Microsoft.Office.Interop.Word. I want to bold a specific value to be bold/italic. I am using following code.

        Microsoft.Office.Interop.Word.Application objword = new Microsoft.Office.Interop.Word.Application();
        objword.WindowState = Microsoft.Office.Interop.Word.WdWindowState.wdWindowStateNormal;
        Microsoft.Office.Interop.Word.Document objDoc = objword.Documents.Add();

        Microsoft.Office.Interop.Word.Paragraph para1;
        para1 = objDoc.Paragraphs.Add();
        String text = "";
        for (int r = 0; r < dgvlib.RowCount; r++)
        {
            text = text + dgvlib.Rows[r].Cells[1].Value.ToString();
            if (dgvlib.Rows[r].Cells[11].Value.ToString()!="")
                text = text +  " Comments:" + dgvlib.Rows[r].Cells[11].Value.ToString() + " ";
            if (dgvlib.Rows[r].Cells[10].Value.ToString() != "")
                text = text +  " ( Bold Text:" + dgvlib.Rows[r].Cells[10].Value.ToString() + ")";
            text = text + "\n";
        }
        para1.Range.Font.Size = 9;
        para1.Range.Font.Name = "Arial";
        para1.Range.Text = text;
        para1.Range.Paragraphs.Add();
        objDoc.SaveAs2(fNameExportWord);
        objword.Visible = true;

I want to bold only this text dgvlib.Rows[r].Cells[10].Value.ToString() (second if condition). If I use different ranges or para then it creates new paragraphs.

In fact datagrid view dgblib rows are being written line by line so in each new line the value to be bold is dynamic. Sample to be written is below (if rows are 3).

this is row to be written to the word. Comments: these are comments. (Bold Text: 456)

this is row2 to be written to the word. Comments: these are comments. (Bold Text: 789)

this is row3 to be written to the word. Comments: these are comments. (Bold Text: 123)

Kanjoo
  • 111
  • 1
  • 8
  • There are also options to paste or insert HTML formatted string https://stackoverflow.com/questions/2363993/adding-html-text-to-word-using-interop/34814793#34814793 – Slai Oct 28 '18 at 18:27

1 Answers1

3

As always, there's more than one way to solve a problem with text insertion and formatting. One way would be to store or mark the values that need to be formatted differently and, after inserting them, use Find to locate them and apply that formatting.

Another way, that the sample code below demonstrates, is basically what the code in the question is trying to do: format as the text is inserted. This does not allow inserting the entire text as a string, however. The text needs to be broken down: each section requiring different formatting needs to be inserted individually.

In order to do this, it's necessary to work with Range objects. The sample code uses two Range objects: one for the entire new content and one for inserting the sections of text. When appending new content to a Range, as long as nothing needs to be done to it, the InsertAfter method can be used.

As soon as the new content needs to be manipulated in some way it's necessary to first "collapse" the Range to a "point", then append the new content. At this point, the Rangecontains only the new content so any formatting applied affects only the new content.

In the sample code I've tried to stay as close to the original as possible in order to make it easier to follow and understand in relation to the original - so it's not optimized...

    Microsoft.Office.Interop.Word.Application objword = new Microsoft.Office.Interop.Word.Application();
    objword.WindowState = Microsoft.Office.Interop.Word.WdWindowState.wdWindowStateNormal;
    Microsoft.Office.Interop.Word.Document objDoc = objword.Documents.Add();

    Microsoft.Office.Interop.Word.Range rngFull = objDoc.Content;
    Microsoft.Office.Interop.Word.Range rngTarget = rngFull.Duplicate;
    rngTarget.InsertAfter("\n");
    object oCollapseEnd = Word.WdCollapseDirection.wdCollapseEnd;
    rngTarget.Collapse(ref oCollapseEnd);

    String text = "";
    for (int r = 0; r < dgvlib.RowCount; r++)
    {
        text = text + dgvlib.Rows[r].Cells[1].Value.ToString();
        if (dgvlib.Rows[r].Cells[11].Value.ToString()!="")
        {
            text = text +  " Comments:" + dgvlib.Rows[r].Cells[11].Value.ToString() + " ";
            rngTarget.InsertAfter(text);
            text = "";
            rngTarget.Collapse(ref oCollapseEnd);
        }
        else if (dgvlib.Rows[r].Cells[10].Value.ToString() != "")
        {
            text = text +  " ( Bold Text:";
            rngTarget.InsertAfter(text);
            text = "";
            rngTarget.Collapse(ref oCollapseEnd);
            rngTarget.Text = dgvlib.Rows[r].Cells[10].Value.ToString();
            rngTarget.Font.Bold = -1;
            rngTarget.Collapse(ref oCollapseEnd);
            rngTarget.InsertAfter(")");
            rngTarget.Font.Bold = 0;
        }
        text = text + "\n";
    }
    rngFull.Font.Size = 9;
    rngFull.Font.Name = "Arial";
    //para1.Range.Text = text;
    //rngFull.Paragraphs.Add();
    objDoc.SaveAs2(fNameExportWord);
    objword.Visible = true;
Cindy Meister
  • 25,071
  • 21
  • 34
  • 43
  • Can you please elaborate the variable lst[r]? – Kanjoo Oct 28 '18 at 07:31
  • I have updated the question.. Becasue dgvlib values are dynamic so I can replace "456" with 'dgvlib.Rows[r].Cells[10].Value.ToString()'. But it is doing bold all the text below the first bold text i.e. producing all the text bold below 456. – Kanjoo Oct 28 '18 at 07:59
  • Apologies, @Kanjoo. I couldn't use your code when working out my sample since I couldn't use your datagrid. And then I forgot to change that one line. I've also added a line to go back to "not bold" (at the end of the `else if`). – Cindy Meister Oct 28 '18 at 16:31
  • @CindyMeister I see that you're setting rngTarget.Font.Bold = -1, in many other places this value is 1. When analyzing text in Word documents I see values for Range.Font.Bold that are 0 (no bold), -1 (all bold), and 9,999,999 (mixed). Is the problem that the Font.Bold value is unsigned? Why the difference? – P. Hinker May 26 '19 at 14:28
  • 1
    @P.Hinker In the Word object library (COM) the values are given as True/False; in the Office COM world, False is always evaluates to 0, even when interpreted by the PIAs for .NET. True is more problematic and the value depends to a certain extent historically how old a property is. The really old things, that originated in the Word Basic days, evaluate to -1 when passed into PIAs for C#; newer properties may evaluate to 1. Bold falls into the "very old" category. *Why* you'd need to address to the Word developers of the eighties and nineties, who worked with C... (A matter of convention?) – Cindy Meister May 26 '19 at 20:43