Hi Dale,
Thanks for your patience. I think, you can use the following code snippet to be able to merge the formatting that is specified inside HTML string with the formatting of MergeField:
Document doc = new Document(@"C:\test\mf.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToMergeField("mf", false, false);
InsertHtmlWithBuilderFormatting(builder, "plain html string");
// InsertHtmlWithBuilderFormatting(builder, "formatted html string");
// Just to remove the mergefield
builder.MoveToMergeField("mf");
doc.Save(@"C:\test\out.docx");
public static void InsertHtmlWithBuilderFormatting(DocumentBuilder builder, string html)
{
ArrayList nodes = new ArrayList();
Document doc = builder.Document;
// Store any callback already set on this document
INodeChangingCallback origCallback = doc.NodeChangingCallback;
// Stores nodes inserted during the InsertHtml call.
doc.NodeChangingCallback = new HandleNodeChanging(nodes);
// Some properties may be changed during InsertHTML, try using a brand new builder instead.
DocumentBuilder htmlBuilder = new DocumentBuilder(doc);
// Move to current paragraph of the original builder
if (builder.CurrentParagraph != null)
htmlBuilder.MoveTo(builder.CurrentParagraph);
// Check if a specific inline node is selected move to this instead
if (builder.CurrentNode != null)
htmlBuilder.MoveTo(builder.CurrentNode);
// Insert HTML.
htmlBuilder.InsertHtml(html);
// Restore the original callback
doc.NodeChangingCallback = origCallback;
// Go through every inserted node and copy formatting from the DocumentBuilder to the apporpriate nodes.
foreach (Node node in nodes)
{
if (node.NodeType == NodeType.Run)
{
Run run = (Run)node;
// Copy formatting of the builder's font to the font of the run.
CopyFormatting(builder.Font, run.Font, htmlBuilder.Font);
}
else if (node.NodeType == NodeType.Paragraph)
{
Paragraph para = (Paragraph)node;
// Copy formatting of the builder's paragraph and list formatting to the formatting of the paragraph.
CopyFormatting(builder.ParagraphFormat, para.ParagraphFormat, htmlBuilder.ParagraphFormat);
CopyFormatting(builder.ListFormat, para.ListFormat, htmlBuilder.ListFormat);
}
else if (node.NodeType == NodeType.Cell)
{
Cell cell = (Cell)node;
// Copy formatting of the builder's cell formatting to the cell.
CopyFormatting(builder.CellFormat, cell.CellFormat, htmlBuilder.CellFormat);
}
else if (node.NodeType == NodeType.Row)
{
Row row = (Row)node;
// Copy formatting of the builder's row formatting to the row
CopyFormatting(builder.RowFormat, row.RowFormat, htmlBuilder.RowFormat);
}
}
// Move the original builder to where the temporary builder ended up
if (htmlBuilder.CurrentParagraph != null)
builder.MoveTo(htmlBuilder.CurrentParagraph);
// Move to specific inline node if possible.
if (htmlBuilder.CurrentNode != null)
builder.MoveTo(htmlBuilder.CurrentNode);
}
public class HandleNodeChanging : INodeChangingCallback
{
ArrayList mNodes;
public HandleNodeChanging(ArrayList nodes)
{
mNodes = nodes;
}
void INodeChangingCallback.NodeInserted(NodeChangingArgs args)
{
mNodes.Add(args.Node);
}
void INodeChangingCallback.NodeInserting(NodeChangingArgs args)
{
// Do Nothing
}
void INodeChangingCallback.NodeRemoved(NodeChangingArgs args)
{
// Do Nothing
}
void INodeChangingCallback.NodeRemoving(NodeChangingArgs args)
{
// Do Nothing
}
}
public static void CopyFormatting(Object source, Object dest, Object compare)
{
if (source.GetType() != dest.GetType() && source.GetType() != compare.GetType())
throw new ArgumentException("All objects must be of the same type");
// Iterate through each property in the source object.
foreach (PropertyInfo prop in source.GetType().GetProperties())
{
// Skip indexed access items. Skip setting the internals of a style as these should not be changed.
if (prop.Name == "Item" || prop.Name == "Style")
continue;
object value;
// Wrap this call as it can throw an exception. Skip if thrown
try
{
value = prop.GetValue(source, null);
}
catch (Exception)
{
continue;
}
// Skip if value can not be retrieved.
if (value != null)
{
// If this property returns a class which belongs to the
if (value.GetType().IsClass && prop.GetGetMethod().ReturnType.Assembly.ManifestModule.Name == "Aspose.Words.dll")
{
// Recurse into this class.
CopyFormatting(prop.GetValue(source, null), prop.GetValue(dest, null), prop.GetValue(compare, null));
}
else if (prop.CanWrite)
{
// dest value != default dont copy
if (prop.GetValue(dest, null).Equals(prop.GetValue(compare, null)))
{
// If we can write to this property then copy the value across.
prop.SetValue(dest, prop.GetValue(source, null), null);
}
}
}
}
}
Moreover, I have attached the sample documents here for you to play with.
I hope, this will help.
Best Regards,