How to insert html into an existing word doc with fillable fields

Hi Support Team,

I am working on vacation request form page, i already have word doc template that has fillable fields on it and i am setting up values on code behind upon export. What i want here is i want to insert html rendered in some part of my page to the existing word document together with the fillable fields (as of now i am getting the html from an html file), specifically the calendar (see Vacation_Request.xlsx) it should appear in the right position as in the excel file. Please help me, i really need to achieve this.

Please note that the desired output should look like (Vacation_Request.xlsx) Calendar Sheet but in pdf and word format.

Hope for your quick response.

Thanks and God Bless!!!

Hi Support Team,

Any update on this?

Thanks,

Hi Felix,

Thanks for your inquiry and sorry for the delayed response.

Calenders in your HTML document are represented by Tables when loaded in Aspose.Words’ DOM. You can pick either of these Tables from DOM and insert them at any valid position in another document. For example, please see the following code which picks first Calender from HTML file, places it right before the first FORMFIELD and removes the field at the end.

Document dstDoc = new Document(MyDir + @"Vacation-RequestFinal.docx");
Document srcDoc = new Document(MyDir + @"vr_template.html");
NodeCollection fieldStarts = dstDoc.GetChildNodes(NodeType.FieldStart, true);
foreach(FieldStart start in fieldStarts)
{
    if (start.FieldType == FieldType.FieldFormTextInput)
    {
        Table calenderTab = (Table) dstDoc.ImportNode(srcDoc.FirstSection.Body.Tables[0], true);
        start.ParentParagraph.ParentNode.InsertBefore(calenderTab, start.ParentParagraph);
        start.GetField().Remove();
        break;
    }
}
dstDoc.Save(MyDir + @"out.docx");

I hope, this helps.

Best regards,

Hi,

I’m getting error from this line:

Table calenderTab = (Table) dstDoc.ImportNode(srcDoc.FirstSection.Body.Tables[0], true);

THis is the error:

Table is an ambiguouse reference between system.web.ui.webcontrols.table and aspose.pdf.table

Thanks

I tried it but it shows on top of the page, how can i insert it to the position like the one in screenshot (output.png)

Hi Felix,

Thanks for your inquiry. Please upgrade to the latest version of Aspose.Words 14.6.0 from the following link:
https://releases.aspose.com/words/net

In case the problem still remains, please attach your 1) input document (you’re getting this problem with), 2) output Word document which shows the undesired behavior, 3) expected document showing the correct result here for testing? We will investigate the issue on our end and provide you more information.

Best regards,

Hi Support Team,

I think there’s no need with updating the aspose word dll, what i need to achieve here is how can i go to a certain position in the document and insert the calendars which is an html. I attached some screenhshots for the wrong output (wrong output.png), input document (Vacation-Request Final.docx) and the desired output (right output.png).

Hi Felix,

What I understand is you want to insert calenders after the second table. You can achieve this using the following code:

Document dstDoc = new Document(MyDir + @"Vacation-RequestFinal.docx ");
Document srcDoc = new Document(MyDir + @"vr_template.html");
Table tab = dstDoc.FirstSection.Body.Tables[1];
Paragraph para = tab.NextSibling.NextSibling as Paragraph;
DocumentBuilder builder = new DocumentBuilder(dstDoc);
builder.MoveTo(para);
ArrayList cells = new ArrayList();
Table targetTab = builder.StartTable();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
builder.EndTable();
for (int i = 0; i <12; i++)
{
    Table calenderTab = (Table) dstDoc.ImportNode(srcDoc.FirstSection.Body.Tables[i], true);
    ((Cell) cells[i]).AppendChild(calenderTab);
}
dstDoc.Save(MyDir + @"out.docx");

I hope, this helps.

PS: out.docx i.e.generated on my end is attached with this post

Best regards,

Hi Support Team,

I tried the above code, it successfully inserts the calendars inside but again in not in my desired position? May i know how did you know where the calendar is being inserted as below code?

Table calenderTab = (Table) dstDoc.ImportNode(srcDoc.FirstSection.Body.Tables[i], true);

As of now it inserted below.

Hi Support Team,

I was able to find a solution for my problem using below code, this code finds a text in a certain position of my document and replaces it with the html, by that i can load my html to a specifi position in my document.

document.Range.Replace(new Regex(@"{{january}}"), new ReplaceWithHtmlEvaluator(), false);

Now my problem is i am using below code to process html but i can’t customize the html value, i was adding a line to call for a function that will get html values to load but i wasn’t able to call it, even my controls i can’t reference those inside this class, do you know any workaround HOW CAN I PASS AN HTML STRING TO THIS CLASS so that that’s will be inserted.

private class ReplaceWithHtmlEvaluator : IReplacingCallback
{
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        DocumentBuilder builder = new DocumentBuilder((Aspose.Words.Document)e.MatchNode.Document);
        builder.MoveTo(e.MatchNode);
        builder.InsertHtml("<table><tbody><tr><td></td></tr></tbody></table>"); 
        //Note: HTML value is just a sample


        e.Replacement = "";
        return ReplaceAction.Replace;
    }
}

Hoping for your quick response with this. Thanks and God Bless!!!

Hi Felix,

Thanks for your inquiry. You can use the following code to pass a string to replace handler:

private class ReplaceWithHtmlEvaluator : IReplacingCallback
{
    public ReplaceWithHtmlEvaluator(string str)
    {
        htmlString = str;
    }
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        DocumentBuilder builder = new DocumentBuilder((Aspose.Words.Document) e.MatchNode.Document);
        builder.MoveTo(e.MatchNode);
        builder.InsertHtml(htmlString);
        // Note: HTML value is just a sample
        e.Replacement = "";
        return ReplaceAction.Replace;
    }
    private string htmlString;
}
document.Range.Replace(new Regex(@"{{january}}"), new ReplaceWithHtmlEvaluator("<table><tbody><tr><td></td></tr></tbody></table>"), false);

Secondly, I suggest you please study Aspose.Words DOM from the following link, after that you should be able to insert a node at any valid location:
https://docs.aspose.com/words/net/aspose-words-document-object-model/

Best regards,

Hi Support Team,

Thanks for the all the help, i was able to get what i want with my document.

But i have some revision on this part, for now i am using a template doc which has form fields on it and i am inserting an html calendars on the output pdf. NOW WHAT I NEED IS TO HAVE THE DAYS IN THE CALENDAR FILLABLE in the output pdf.

Thanks

Hi Felix,

Thanks for your inquiry. Please attach your expected Word and PDF documents here for testing. You can create these documents using Microsoft Word. We will investigate this scenario and provide you more information.

Best regards,

Hi i will attach output document in pdf, no problem in word because we can directly edit it, just in pdf output, we need the days in the calendars to be fillable or it can be changed, because the rule in the document is to mark X on the dates.

This is the area where i want to make it fillable, that is a calendar, this is from the aspx page, i just get the html of every calendar and inserted it.

Hi Felix,

Thanks for the additional information. You can achieve this by using the following code:

Document dstDoc = new Document(MyDir + @"Vacation-Request+Final.docx");
Document srcDoc = new Document(MyDir + @"vr_template.html");
Table tab = dstDoc.FirstSection.Body.Tables[1];
Paragraph para = tab.NextSibling.NextSibling as Paragraph;
DocumentBuilder builder = new DocumentBuilder(dstDoc);
builder.MoveTo(para);
ArrayList cells = new ArrayList();
Table targetTab = builder.StartTable();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
builder.EndTable();
int count = 0;
for (int i = 0; i <12; i++)
{
    Table calenderTab = (Table) dstDoc.ImportNode(srcDoc.FirstSection.Body.Tables[i], true);
    ((Cell) cells[i]).AppendChild(calenderTab);
    NodeCollection fieldStarts = calenderTab.GetChildNodes(NodeType.FieldStart, true);
    foreach(FieldStart start in fieldStarts)
    {
        if (start.FieldType == FieldType.FieldHyperlink)
        {
            builder.MoveToField(start.GetField(), false);
            builder.InsertTextInput("TextInput_" + count++, TextFormFieldType.Number, "", start.GetField().Result.ToString().Trim(), 2);
            start.GetField().Remove();
        }
    }
}
PdfSaveOptions options = new PdfSaveOptions();
options.PreserveFormFields = true;
dstDoc.Save(MyDir + @"out.pdf", options);

I hope, this helps.

Bets regards,

This was the reply:

----------------------------------------------------

Hi Felix,

Thanks for the additional information. You can achieve this by using the following code:

Document dstDoc = new Document(MyDir + @"Vacation-Request+Final.docx");
Document srcDoc = new Document(MyDir + @"vr_template.html");
Table tab = dstDoc.FirstSection.Body.Tables[1];
Paragraph para = tab.NextSibling.NextSibling as Paragraph;
DocumentBuilder builder = new DocumentBuilder(dstDoc);
builder.MoveTo(para);
ArrayList cells = new ArrayList();
Table targetTab = builder.StartTable();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
builder.EndTable();
int count = 0;
for (int i = 0; i <12; i++)
{
    Table calenderTab = (Table) dstDoc.ImportNode(srcDoc.FirstSection.Body.Tables[i], true);
    ((Cell) cells[i]).AppendChild(calenderTab);
    NodeCollection fieldStarts = calenderTab.GetChildNodes(NodeType.FieldStart, true);
    foreach(FieldStart start in fieldStarts)
    {
        if (start.FieldType == FieldType.FieldHyperlink)
        {
            builder.MoveToField(start.GetField(), false);
            builder.InsertTextInput("TextInput_" + count++, TextFormFieldType.Number, "", start.GetField().Result.ToString().Trim(), 2);
            start.GetField().Remove();
        }
    }
}
PdfSaveOptions options = new PdfSaveOptions();
options.PreserveFormFields = true;
dstDoc.Save(MyDir + @"out.pdf", options);

I hope, this helps.

Bets regards,

Hi Support Team,

Thanks for that solution, that’s what i really wanted, a fillable days on the calendar, but it seems its not in the right position, can you help me again to place the calendars to its correct location in the document?

I believe that you’re creating new tables wherein you insert the calendar, what i need is to insert the calendar to a specific cell, is it possible to find a cell by a tag or in any way that currently exist in the working document then after you find it then insert the calendar in that particular cell?

I have attached the screenshot (wrong location.png) using your code where the calendars is located below the page.
I also attached a screenshot (correct location.png) where you can see where i want to position every calendar, i have a table which has calendar name like {{january}} on each cell, i want to put the calendar in that position for every month.

This is the reply:

Hi Felix,

Thanks for the additional information. You can achieve this by using the following code:

Document dstDoc = new Document(MyDir + @"Vacation-Request+Final.docx");
Document srcDoc = new Document(MyDir + @"vr_template.html");
Table tab = dstDoc.FirstSection.Body.Tables[1];
Paragraph para = tab.NextSibling.NextSibling as Paragraph;
DocumentBuilder builder = new DocumentBuilder(dstDoc);
builder.MoveTo(para);
ArrayList cells = new ArrayList();
Table targetTab = builder.StartTable();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
cells.Add(builder.InsertCell());
builder.EndRow();
builder.EndTable();
int count = 0;
for (int i = 0; i <12; i++)
{
    Table calenderTab = (Table) dstDoc.ImportNode(srcDoc.FirstSection.Body.Tables[i], true);
    ((Cell) cells[i]).AppendChild(calenderTab);
    NodeCollection fieldStarts = calenderTab.GetChildNodes(NodeType.FieldStart, true);
    foreach(FieldStart start in fieldStarts)
    {
        if (start.FieldType == FieldType.FieldHyperlink)
        {
            builder.MoveToField(start.GetField(), false);
            builder.InsertTextInput("TextInput_" + count++, TextFormFieldType.Number, "", start.GetField().Result.ToString().Trim(), 2);
            start.GetField().Remove();
        }
    }
}
PdfSaveOptions options = new PdfSaveOptions();
options.PreserveFormFields = true;
dstDoc.Save(MyDir + @"out.pdf", options);

I hope, this helps.

Bets regards,

Hi Felix,

Thanks for your inquiry. Yes, you can insert calenders at any valid place in your document e.g. inside an existing Cell. For example, you can use the following code if you have a bookmark inside Cell where you want to insert calender:

Bookmark bm = doc.Range.Bookmarks["IAmInsideCell"];
Cell cell = bm.BookmarkStart.GetAncestor(NodeType.Cell) as Cell;
cell.AppendChild(calenderTab);

Please also visit the following links:
https://docs.aspose.com/words/net/navigation-with-cursor/
https://docs.aspose.com/words/net/aspose-words-document-object-model/

Best regards,