none
Remove Content control and place a text RRS feed

  • Question

  • I have a word template with content control in it. I need to write a program to generate report out of it. The report should delete the content control and place a given text.

    I am trying to acheive this using Open XML. I am looking for some help on this.


    Thursday, July 14, 2011 8:39 AM

Answers

  • Hi Vidya,

    I recommond you a nice tool which you can look into the structure of the word document and get the reflection code:

    http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5124

    I found if the content control is in the table, it is the SdtCell element, then we need to create the TableCell after removing the SdtCell, below is the code which I have coded for you to reference:

    using System.Linq;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    using DocumentFormat.OpenXml;
     
    namespace OpenXmlReplaceContentControlWithText
    {
        class Program
        {
            static void Main(string[] args)
            {
     
     
                using (WordprocessingDocument document = WordprocessingDocument.Open(
                  @"tablecontentcontrol.docx"true))
                {
                    MainDocumentPart mainPart = document.MainDocumentPart;
                    SdtCell[] sdtList = mainPart.Document.Body.Descendants<SdtCell>().ToArray();
                    foreach (SdtCell sdt in sdtList)
                    {
                        Paragraph newP = new Paragraph();
                        Run newR = new Run();
                        Text text = new Text();
                        text.Text = "hello";
                        newR.Append(text);
                        newP.Append(newR);
     
                        OpenXmlElement parent = sdt.Parent;                   // get TableRow
                        sdt.Remove();                                         // delete SdtCell
                        TableCell tc = GenerateTableCell("Your Text");        // create table cell
                        parent.Append(tc);                                    // append table cell
                    }
                }
            }
     
            // Creates an TableCell instance and adds its children.
            public static TableCell GenerateTableCell(string text)
            {
                TableCell tableCell1 = new TableCell();
     
                TableCellProperties tableCellProperties1 = new TableCellProperties();
                TableCellWidth tableCellWidth1 = new TableCellWidth() { Width = "4428", Type = TableWidthUnitValues.Dxa };
     
                tableCellProperties1.Append(tableCellWidth1);
     
                Paragraph paragraph1 = new Paragraph() { RsidParagraphAddition = "001677F0", RsidRunAdditionDefault = "00DE3A9E" };
     
                Run run1 = new Run();
     
                RunProperties runProperties1 = new RunProperties();
                RunFonts runFonts1 = new RunFonts() { Hint = FontTypeHintValues.EastAsia };
     
                runProperties1.Append(runFonts1);
                Text text1 = new Text();
                text1.Text = text;
     
                run1.Append(runProperties1);
                run1.Append(text1);
                BookmarkStart bookmarkStart1 = new BookmarkStart() { Name = "_GoBack", Id = "0" };
                BookmarkEnd bookmarkEnd1 = new BookmarkEnd() { Id = "0" };
     
                paragraph1.Append(run1);
                paragraph1.Append(bookmarkStart1);
                paragraph1.Append(bookmarkEnd1);
     
                tableCell1.Append(tableCellProperties1);
                tableCell1.Append(paragraph1);
                return tableCell1;
            }
     
        }
    }
    

    Hope this can help you and just feel free to follow up after you have tried. Wish you a nice day.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Bruce Song Tuesday, August 9, 2011 6:03 PM
    Thursday, July 21, 2011 9:21 AM

All replies

  • Hi Vidya,

    You can iterator all the content controls and then replace each one with the text. Here is the code snippet which I have tested for you to reference:

    using System.Linq;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    using DocumentFormat.OpenXml;
     
    namespace OpenXmlReplaceContentControlWithText
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (WordprocessingDocument document = WordprocessingDocument.Open(
                   @"test.docx"true))
                {
                    MainDocumentPart mainPart = document.MainDocumentPart;
                    SdtBlock[] sdtList = mainPart.Document.Body.Descendants<SdtBlock>().ToArray();
                    foreach (SdtBlock sdt in sdtList)
                    {
                        //SdtContentBlock sdtContentBlock = sdt.GetFirstChild<SdtContentBlock>();
                        //Paragraph p = sdtContentBlock.GetFirstChild<Paragraph>();
                        //Run r = p.GetFirstChild<Run>();
     
                        Paragraph newP = new Paragraph();
                        Run newR = new Run();
                        Text text = new Text();
                        text.Text = "hello";
                        newR.Append(text);
                        newP.Append(newR);
     
                        OpenXmlElement parent = sdt.Parent;
                        sdt.Remove(); // delete SdtBlock
                        parent.Append(newP);
                    }
                }
            }
        }
    }
    

    Hope this can help you and just feel free to follow up after you have tried. Wish you a nice day.

    Best Regards, 


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Monday, July 18, 2011 8:23 AM
  • Hi Bruce,

    Thanks for the code snippet. This didnt work for my scenario. I have a table in Word template. Each cell of the table has a content control. I want to replace all of the with some text. Since the code creates a new paragraph the paragraph gets appended after the table and hence didnt satisfy my need. Can you help me in this case?

     

    Wednesday, July 20, 2011 6:39 AM
  • Hi Vidya,

    I recommond you a nice tool which you can look into the structure of the word document and get the reflection code:

    http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5124

    I found if the content control is in the table, it is the SdtCell element, then we need to create the TableCell after removing the SdtCell, below is the code which I have coded for you to reference:

    using System.Linq;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    using DocumentFormat.OpenXml;
     
    namespace OpenXmlReplaceContentControlWithText
    {
        class Program
        {
            static void Main(string[] args)
            {
     
     
                using (WordprocessingDocument document = WordprocessingDocument.Open(
                  @"tablecontentcontrol.docx"true))
                {
                    MainDocumentPart mainPart = document.MainDocumentPart;
                    SdtCell[] sdtList = mainPart.Document.Body.Descendants<SdtCell>().ToArray();
                    foreach (SdtCell sdt in sdtList)
                    {
                        Paragraph newP = new Paragraph();
                        Run newR = new Run();
                        Text text = new Text();
                        text.Text = "hello";
                        newR.Append(text);
                        newP.Append(newR);
     
                        OpenXmlElement parent = sdt.Parent;                   // get TableRow
                        sdt.Remove();                                         // delete SdtCell
                        TableCell tc = GenerateTableCell("Your Text");        // create table cell
                        parent.Append(tc);                                    // append table cell
                    }
                }
            }
     
            // Creates an TableCell instance and adds its children.
            public static TableCell GenerateTableCell(string text)
            {
                TableCell tableCell1 = new TableCell();
     
                TableCellProperties tableCellProperties1 = new TableCellProperties();
                TableCellWidth tableCellWidth1 = new TableCellWidth() { Width = "4428", Type = TableWidthUnitValues.Dxa };
     
                tableCellProperties1.Append(tableCellWidth1);
     
                Paragraph paragraph1 = new Paragraph() { RsidParagraphAddition = "001677F0", RsidRunAdditionDefault = "00DE3A9E" };
     
                Run run1 = new Run();
     
                RunProperties runProperties1 = new RunProperties();
                RunFonts runFonts1 = new RunFonts() { Hint = FontTypeHintValues.EastAsia };
     
                runProperties1.Append(runFonts1);
                Text text1 = new Text();
                text1.Text = text;
     
                run1.Append(runProperties1);
                run1.Append(text1);
                BookmarkStart bookmarkStart1 = new BookmarkStart() { Name = "_GoBack", Id = "0" };
                BookmarkEnd bookmarkEnd1 = new BookmarkEnd() { Id = "0" };
     
                paragraph1.Append(run1);
                paragraph1.Append(bookmarkStart1);
                paragraph1.Append(bookmarkEnd1);
     
                tableCell1.Append(tableCellProperties1);
                tableCell1.Append(paragraph1);
                return tableCell1;
            }
     
        }
    }
    

    Hope this can help you and just feel free to follow up after you have tried. Wish you a nice day.

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Bruce Song Tuesday, August 9, 2011 6:03 PM
    Thursday, July 21, 2011 9:21 AM
  • Why not replace the text within the table cell rather than the whole cell?                      

    TableCell tc = sdtCCell.Elements<TableCell>().First();
    if (tc != null)
    {
        // simple text, assume 1 paragraph to handle
        para = tc.Elements<Paragraph>().First();
        if (para != null)
        {
            // simple text, assume 1 run to handle
            Run r = para.Elements<Run>().First();
            if (r != null)
            {
                Text t = r.Elements<Text>().First();
                if (t == null)
                {
                    t = new Text(Message);
                    r.Append(t);
                }
                else
                {
                    t.Text = Message;
                }
            }
        }
    }

    Wednesday, April 11, 2012 8:02 AM
  • Hi Vidya,

    What you are trying to do seems very simple but it is not. I know this beacause we created Docentric toolkit (you might want to check it out) which does exactly what you try to do (and much more). The problem is that placeholders (content controls) can sometimes be directly in a paragraph and sometimes are in table cells (like in your case). When you place a content control (CC) into a cell there are several possible cases/outcomes:

    - CC is wrapped by a cell, CC wraps the paragraph

    - CC is wrapping the cell

    - CC is wrapped by the paragraph in the cell (this occurs when there is some other content besides the CC)

    - CC is wrapping table row (can occure when table only has 1 column - very rare)

    This part of our product was one of the most tedious and we needed a lot of time and testing to cover all the cases. As a result the method that handles this is veary complex. Sometimes you need to create a new paragraph, sometimes not. Sometimes you need to create several new paragraphs if you are replacing CC with a multiline text. You should also be careful how to delete the CC after the text has been inserted. The snippet that Bruce posted works only for the first case which is the most simple, but not for others. Once again, take a look at our product. it might be a better choice over creating your custom solution.

    Thursday, April 12, 2012 12:07 PM