Create Content Control (SDT) at (x, y) Position in Word Document & Extract SDT Co-ordinates (C# .NET)

Hi Team,

Can we create content control at a given co-ordinate in word document. If yes , can you please help with some example code.

Also can we extract co-ordinates of content control in word document. Please help with code example.

Thanks a lot team.

@saurabh.arora,

You can place content control inside a Textbox and position that Textbox at any (x, y) coordinates in Word document:

Document doc = new Document("C:\\Temp\\input.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveTo(doc.FirstSection.Body.Paragraphs[0]);

// Configure positioning of TextBox
Shape textbox = builder.InsertShape(ShapeType.TextBox, 2.5 * 72, 0.5 * 72); // Draw a 2.5 x 0.25 inches TextBox
textbox.Left = 4 * 72; // 1 inch equals 72 points
textbox.Top = 0.5 * 72;
textbox.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
textbox.RelativeVerticalPosition = RelativeVerticalPosition.Page;
textbox.WrapType = WrapType.None;
textbox.BehindText = false;
textbox.Stroked = false;

// Insert content control inside TextBox
builder.MoveTo(textbox.FirstChild);
StructuredDocumentTag SdtCheckBox = new StructuredDocumentTag(doc, SdtType.Checkbox, MarkupLevel.Inline);
builder.InsertNode(SdtCheckBox);

doc.Save("C:\\temp\\21.6.docx");

And you can build logic on the following C# code of Aspose.Words for .NET API to extract coordinates of content control in Word document:

Document doc = new Document("C:\\Temp\\21.6.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

// Get the Content Control you want to pbtain posiiotn of 
StructuredDocumentTag sdtSdtCheckBox =
    (StructuredDocumentTag)doc.GetChildNodes(NodeType.StructuredDocumentTag, true)[0];

// insert a temporary bookmark around the content control
BookmarkStart start = builder.StartBookmark("bm_1");
BookmarkEnd end = builder.EndBookmark("bm_1");

sdtSdtCheckBox.ParentNode.InsertBefore(start, sdtSdtCheckBox);
sdtSdtCheckBox.ParentNode.InsertAfter(end, sdtSdtCheckBox);

// Following code will return the (x, y) coordinates of Content Control in Inches
LayoutCollector layoutCollector = new LayoutCollector(doc);
LayoutEnumerator layoutEnumerator = new LayoutEnumerator(doc);

layoutEnumerator.Current = layoutCollector.GetEntity(start);
layoutEnumerator.MoveNext();

Console.WriteLine("({0}, {1})", layoutEnumerator.Rectangle.Left / 72, layoutEnumerator.Rectangle.Top / 72);

Thanks for the reply. I tried the code and it is working.

But to insert content control at specific coordinate , how do i navigate to specific page as x and y coordinates are relative to page index.

My use case is that i would be given x , y coordinates and page index and i would need to insert content control at that position. Please help.

@saurabh.arora,

Please check if the following code produces desired results on your end?

int pageIndex = 9;

Document doc = new Document("C:\\Temp\\input.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

Node[] runs = doc.FirstSection.Body.GetChildNodes(NodeType.Run, true).ToArray();
for (int i = 0; i < runs.Length; i++)
{
    Run run = (Run)runs[i];
    int length = run.Text.Length;

    Run currentNode = run;
    for (int x = 1; x < length; x++)
    {
        currentNode = SplitRun(currentNode, 1);
    }
}

NodeCollection smallRuns = doc.GetChildNodes(NodeType.Run, true);
LayoutCollector collector = new LayoutCollector(doc);

foreach (Run run in smallRuns)
{
    if (collector.GetStartPageIndex(run) == pageIndex)
    {
        builder.MoveTo(run);

        // Configure positioning of TextBox
        Shape textbox = builder.InsertShape(ShapeType.TextBox, 2.5 * 72, 0.5 * 72); // Draw a 2.5 x 0.25 inches TextBox
        textbox.Left = 4 * 72; // 1 inch equals 72 points
        textbox.Top = 0.5 * 72;
        textbox.RelativeHorizontalPosition = RelativeHorizontalPosition.Page;
        textbox.RelativeVerticalPosition = RelativeVerticalPosition.Page;
        textbox.WrapType = WrapType.None;
        textbox.BehindText = false;
        textbox.Stroked = false;

        // Insert content control inside TextBox
        builder.MoveTo(textbox.FirstChild);
        StructuredDocumentTag SdtCheckBox = new StructuredDocumentTag(doc, SdtType.Checkbox, MarkupLevel.Inline);
        builder.InsertNode(SdtCheckBox);
    }
}

doc.Save("C:\\temp\\21.7.docx");

public static Run SplitRun(Run run, int position)
{
    Run afterRun = (Run)run.Clone(true);
    afterRun.Text = run.Text.Substring(position);
    run.Text = run.Text.Substring((0), (0) + (position));
    run.ParentNode.InsertAfter(afterRun, run);
    return afterRun;
}

Hi,

Thanks for the reply. Is the position of content control created inside text box fixed or will change if content in word file is changed.

My use case is that position should change if content of word document is changed as I will need to give new coordinates to the client.

Please help.

@saurabh.arora,

The textbox containing the content control will be placed at an absolute position and it will not move with the addition/removal of content. Please also share your expected Word DOCX file showing the desired output here for our reference. You can create this file manually by using MS Word. It would be great if you please also list the complete steps that you performed in MS Word to create the expected file. We will then provide you code to achieve the same output by using Aspose.Words.

Hi ,

Thanks for the reply.

I will describe my use case. Requirement is that I will be given a set of coordinates with page number and i need to insert some place holder in the document at the given coordinates. Then document will go in multiple approval iteration where it will get updated.

Then once the document is approved , i will need to return coordinates for those placeholders and they may be different from initial coordinates as document might have changed.

Please suggest how to achieve this use case using aspose.

@saurabh.arora,

How can you meet this requirement by using MS Word? Can you please compress the following resources into ZIP format and attach the .zip file here for testing?

  • Your source Word document that you want to insert placeholder in
  • The intermediate DOCX file containing the placeholder at specific coordinates in some page
  • The final DOCX file (after making some changes). You can create these documents manually by using MS Word.
  • Please also list the complete steps you performed in MS Word to produce intermediate and final DOCX files on your end.

We will then investigate the scenario further on our end and provide you code to achieve the same outputs by using Aspose.Words.

Hi,

Thanks for the reply. I do not have an example document ready.

Just wanted to get some idea on how can we achieve this use case. We need to keep some identifier in the document at a given coordinate (This will be provided by the UI which will be used for signing purpose). Then once the document is approved , we need to return updated coordinates of that identifier , which the client will send to docu sign.

I will be grateful for any insights. Thanks.

@saurabh.arora,

I think, instead of absolute coordinates, you can make use of bookmarks. Please check following article:

You can move cursor to any inline node in Word document and then insert bookmark there. If you remove or add new content in MS Word, then this bookmark will move accordingly and later on you can get the bookmark and bookmark’s position easily.