Hi,
We have an issue with merge fields mixing the font when the document is merged. I have attached an example of the code we are using to generate the merged document along with the ‘template’ document itself.
Basically what is happening is that the merge field containing the text “2013 Residual Tax to Pay” mixes the font so that “2013 Residual Tax” appears in Arial while the “to Pay” part appears in Times New Roman. Interestingly I have found that if the Word document is opened in MS Word, a minor change is added, deleted and then the document is saved, the same merge field updates correctly via the test application.
In this instance, we have recently upgraded from version 8.0.0.0 to version 13.8.0.0 of the library.
Hi Nicholas,
Thanks for your inquiry.
While using the latest version of Aspose.Words i.e. 13.8.0, I managed to reproduce this issue on my side. I have logged this issue in our bug tracking system. The ID of this issue is WORDSNET-9008. Your request has also been linked to this issue and you will be notified as soon as it is resolved. Sorry for the inconvenience.
Best regards,
Hi Nicholas,
Thank for being patient. I’m very sorry to share with you that on further investigation our development team came to know that they won’t be able to implement the fix to your issue. Your issue is now closed with ‘‘Won’t Fix’’ resolution. This means the issue is not actually fixed but closed because Aspose.Words correctly mimics the behavior of Microsoft Word i.e. if you generate output document using Microsoft Word the formatting of the merge fields will be the same as the one applied by Aspose.Words. However, to overcome this problem, please don’t use MERGEFORMAT switch in merge fields. If we can help you with anything else, please feel free to ask.
Best regards,
Hi there,
I must say the response is a little disappointing, even if it is understandable. I understand the need to mimic what Microsoft Word does, even down to the bugs it has but it is a little frustrating as this used to work (albeit incorrectly) in the older version of the tool (8.0.0.0). Unfortunately we can’t go back to that version as this latest one fixes other issues we are having with Word documents in other areas of the application.
Removing the MERGEFORMAT switch doesn’t really work for us either as removing it means that the field is now rendered in the font of the underlying merge field as it is defined in the field code, rather than the font that is displayed when the field codes are hidden. We also have literally thousands of Word documents (both our own and those of our clients) which would need updating to remove the switch even if this did work as we needed it to. Oh well, we’ll just have to try to work around it some other way.
Hi Nicholas,
Thanks for the additional information. I tested your scenario with Aspose.Words 8.1.0 and have managed to reproduce a correct output. I have passed my findings to our development team and will update you as soon as I receive any additional information from the development team. We apologize for any inconvenience.
Best regards,
Hi Nicholas,
Thanks for being patient.
Unfortunately, the situation in your case is inevitable. While making Aspose.Words closer and closer to Microsoft Word, it’s behaviour will be changing a little here and there. It is acceptable to some reasonable degree. In critical cases (or when many users are affected), we may introduce options in order to support backward compatibility and avoid disappointed customers. But, it is hard to do that in this specific case. So, a workaround without template modifications could be as follows:
Iterate over the fields in a document (you can use Document.Range.Fields for the purpose) and do the following with every particular field.
- Remove MERGEFORMAT switch from the field code. We do not have any API for this yet, but this can be done by iterating runs between field starts and separators.
- Navigate to the first run of the field result and grab its font.
- Iterate over runs of the field code and set their font properties similar to the grabbed ones. Do the same for the field start, separator and end.
Please try running the following code:
…
…
string docname = "Test.docx";
MergeService svc = new MergeService();
Document doc = new Document(docname);
foreach(Field field in doc.Range.Fields)
{
if (field.GetFieldCode().Contains("\\* MERGEFORMAT"))
{
Run fieldResult = field.Separator.NextSibling as Run;
Node currentNode = field.Start;
bool flag = true;
while (currentNode != null && flag)
{
if (currentNode.NodeType == NodeType.FieldSeparator)
flag = false;
Node nextNode = currentNode.NextPreOrder(currentNode.Document);
if (currentNode.NodeType == NodeType.Run)
{
Run run = (Run) currentNode;
if (run.Text.Contains("\\* MERGEFORMAT"))
run.Text = run.Text.Replace("\\* MERGEFORMAT", "");
CopyFormatting(fieldResult.Font, run.Font);
}
currentNode = nextNode;
}
}
}
List < IMailMergeDataSource > source = new List < IMailMergeDataSource > ();
source.Add(new TestItems());
…
…
public static void CopyFormatting(Object source, Object dest)
{
if (source.GetType() != dest.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));
}
else if (prop.CanWrite)
{
prop.SetValue(dest, prop.GetValue(source, null), null);
}
}
}
}
I hope, this helps.
Best regards,
Hey, thanks very much for this. I have tested it in our scenario and initial indications are that it is working as we require. I’ll put it through our QA process and see if they can find anything but it looks good so far. We’re very much obliged for the extra effort you guys have put in on this one.
Hi there,
I’ve just been looking through the release notes for version 13.10.0 and am a little confused… The issue I brought to your attention earlier (WORDSNET-9008), which I was told was not being fixed, is listed as having been fixed in this release? Is the fix simply the code that you gave me earlier and the bug has been included in the list as being ‘resolved’ or is there an actual change in the assembly now for this?
Hi Nicholas,
Thanks for your inquiry. Yes, it’s a mistake. Unfortunately, WORDSNET-9008 was included in release notes by mistake. We apologize for this confusion. Please note that this issue was closed with ‘‘Won’t Fix’’ resolution (please use the workaround mentioned here*).
Best regards,