Format Entire Barcode Merge Fields in Word Document with a Single Font using Java

Aspose Words Version: aspose-words.20.3 (Java JDK)
Environment: macOS Catalina 10.15.3
Development Environment: IntelliJ IDEA 2019.3
Microsoft Word for Mac: Version 16.35

Using the following MERGEFIELD tags:
«IMB»
«MailRecipient»
«Address1»
«City», «State» «ZipCode»

The “IMB” field value is “TFTADDFDDDFTDAFTTTFTFFAFDDFDFFFFFFTTDATFAFDFDFAFFDAFAFFFTDAFTFDAA” with the USPSIMBStandard font specified in the Word document.

The other values are using “Proxima Nova” True Type font.

The output PDF embeds the “Proxima Nova” and “USPSIMBStandard” fonts however, the <> tag is using “Arial Unicode MS” font when inspecting the PDF using Acrobat Pro DC (Properties->Fonts).

Within the Word document (docx) I placed the encoded IMB string as static text and specified the USPSIMBStandard font from the pull-down fonts and it renders correctly. The dynamic string for the field “IMB” does not.

Console Output:
strKey:[ZipCode][96813-2900]
strKey:[State][HI]
strKey:[FirstName][Ronon]
strKey:[LastName][Dex]
strKey:[IMB][TFTADDFDDDFTDAFTTTFTFFAFDDFDFFFFFFTTDATFAFDFDFAFFDAFAFFFTDAFTFDAA]
strKey:[City][HONOLULU]
strKey:[Address1][364 S KING STREET]
strKey:[MailRecipient][RONON DEX]

Reviewing the available cases similar I’ve added the following code:
File fCustomFonts = new File( “CustomerFonts/” );
if ( fCustomFonts.exists() ) {
ArrayList fontSources = new ArrayList(Arrays.asList(FontSettings.getDefaultInstance().getFontsSources()));

System.out.println( “CUSTOMER FONTS:[” + fCustomFonts.getAbsolutePath() + “]” );

FolderFontSource folderFontSource = new FolderFontSource( fCustomFonts.getAbsolutePath(), true );
fontSources.add( folderFontSource );
FontSourceBase[] updatedFontSources = (FontSourceBase[]) fontSources.toArray( new FontSourceBase[ fontSources.size() ] );

FontSettings.getDefaultInstance().setFontsSources( updatedFontSources );
fontSetting.setFontsSources( updatedFontSources );
}

Hashtable dataMap = getMergeData();

LoadOptions loadOptions = new LoadOptions();
loadOptions.setFontSettings( fontSetting );

Document doc = new Document( strWordDoc, loadOptions );

// Execute mail merge.
doc.getMailMerge().execute( mergeKeys, dataMap.values().toArray() );

HandleDocumentWarnings callback = new HandleDocumentWarnings();
doc.setWarningCallback( callback );

doc.save( strOutput, pdfOptions );

The callback method returns:
Font substitution: Font ‘Cambria’ has not been found. Using ‘Arial Unicode MS’ font instead. Reason: font info substitution.

Any suggestions would be greatly appreciated.

Bill Sanders

I believe the issue was identified by the ‘callback’ method referencing the ‘Arial Unicode MS’ font substitution.
I isolated the IMB field and found the first character ‘<<’ calling USPSIMBStandard and the next character calling the ‘Cambria’ and the rest calling USPSIMBStandard. I removed the characters and re-applied the USPSIMBStandard font selection and then performed an update field and the IMB font rendered as expected in the PDF output. Not sure if this was a Microsoft Word issue or not.

@bill.sanders,

I think, before executing mail merge, you need to pre-process your document and apply same font name to all Run nodes belonging to merge fields.

Document doc = new Document("E:\\Temp\\mf.docx");

foreach (Field field in doc.Range.Fields)
{
    if (field.Type.Equals(Aspose.Words.Fields.FieldType.FieldMergeField))
    {
        Node currentNode = field.Start;
        bool isContinue = true;

        while (currentNode != null && isContinue)
        {
            if (currentNode.NodeType.Equals(NodeType.FieldEnd))
                isContinue = false;

            if (currentNode.NodeType.Equals(NodeType.Run))
            {
                Run run = (Run)currentNode;
                run.Font.Name = "Times New Roman";
            }

            Node nextNode = currentNode.NextPreOrder(currentNode.Document);
            currentNode = nextNode;
        }
    }
}

// doc.MailMerge.Execute(...);
// ...

Hope, this helps.