InsertHTML font issues

Our word document supports themes which defines the font to use for the whole document.


When an export is done the Inserthtml font is always Times Roman.

Have used the InsertHtmlWithBuilderFormatting code below but it changes all the font characteristics including whether the font is bold, italic etc.

This will remove any formatting that was currently set in the text.

Would like to just be able to change the font name only and leave the rest of the formatting alone.

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);
}
}
}
}
}
Hi Paul,

Thanks for your inquiry. I suggest you please use latest version of Aspose.Words for .NET 14.12.0. We introduced a new overload of DocumentBuilder.InsertHtml method which allows you to choose what formatting will be used as a base for inserted HTML fragments.

The new overload has an argument useBuilderFormatting which when is false, formatting specified in DocumentBuilder is ignored, and formatting of inserted text is based on default HTML formatting. In this case, inserted text looks as in browsers.

When useBuilderFormatting is true, formatting of inserted text is based on formatting specified in DocumentBuilder. Note that useBuilderFormatting chooses only base formatting of inserted text, and do not affect formatting directly specified in the HTML fragment.

The following example illustrates the difference between the two modes:

DocumentBuilder builder = new DocumentBuilder();

builder.ParagraphFormat.LeftIndent = 72;

builder.Font.Name = "Arial";

builder.Font.Size = 24;

bool useBuilderFormatting = ...

builder.InsertHtml("

Text

"
, useBuilderFormatting);

In this example, if useBuilderFormatting is false, the inserted paragraph will have no left indent and will use the 'Times New Roman' 12pt font, which is the default HTML font and indent. If useBuilderFormatting is true, the inserted paragraph will be indented by 1 inch (72 points) and will use the 'Arial' 24pt font, as specified in DocumentBuilder. However, in both cases the inserted text will be bold and red, as specified in the HTML fragment.

So, please try using this method as follows:

builder.InsertHtml("Some text before ", true);


Hope this helps you. Please let us know if you have any more queries.

Got things working by doing the following:


builder.InsertHtml("

" + expData.Tables[“BoilerPlate”].Rows[0][“Description”].ToString() + "

");

This will ensure that the font and font size is consistent with the theme that was selected.

I will have a look at the technique that you have provided.

Regards
Paul
Hi Paul,

Thanks for your feedback. Please feel free to ask if you have any question about Aspose.Words, we will be happy to help you.