Reputation: 1257
I have a template that have some merge fields that are in side and out side a table. The values for these fields are query and cached to map then set to the field by a cusstom FieldMergingCallback, here is the java code:
// doc is a Document object
doc.getMailMerge().setFieldMergingCallback(new IFieldMergingCallback() {
@Override
public void fieldMerging(FieldMergingArgs arg0) throws Exception {
if (fieldCache.containsKey(arg0.getFieldName())) {
arg0.setText(fieldCache.get(arg0.getFieldName()));
}
}
@Override
public void imageFieldMerging(ImageFieldMergingArgs arg0) throws Exception {
return;
}
});
The problem is I lost all field format (\* Caps, \* Upper, etc…) when using setText method, I have tried to call doc.updateFields() after the call to executeWithRegions() but the format still lost.
How can I reserve format in the call back?
This is a legacy system so we are stuck in aspose word 14.5.0
Upvotes: 0
Views: 1011
Reputation: 1257
UPDATE 02-2020: Aspose word 20.2 has implemented this feature. https://forum.aspose.com/t/merge-field-format-lost-when-using-fieldmergingcallback/206900/5
According to the replies to the same question of mine on aspose forum, currently there is no support for keeping formatting in FieldMergingCallback. So, I end up with a work around, the idea is in every call back, I create a fake document and clone the current field to this fake document, excute it to get the final result, then set it back to the actual field with setText function:
doc.getMailMerge().setFieldMergingCallback(new IFieldMergingCallback(){
@Override
public void fieldMerging(FieldMergingArgs e)throws Exception{
if(cache.containsKey(e.getFieldName())){
Document fakeDoc=new Document();
DocumentBuilder builder=new DocumentBuilder(fakeDoc);
builder.insertField(e.getField().getFieldCode());
fakeDoc.getMailMerge().setFieldMergingCallback(new IFieldMergingCallback(){
@Override
public void fieldMerging(FieldMergingArgs arg)throws Exception{
DocumentBuilder innerBuilder=new DocumentBuilder(arg.getDocument());
innerBuilder.moveToMergeField(arg.getFieldName(),false,false);
innerBuilder.startBookmark(arg.getFieldName());
innerBuilder.moveToMergeField(arg.getFieldName(),true,false);
innerBuilder.endBookmark(arg.getFieldName());
}
@Override
public void imageFieldMerging(ImageFieldMergingArgs arg){
}
});
fakeDoc.getMailMerge().execute(new String[]{e.getFieldName()},new Object[]{cache.get(e.getFieldName())});
// Set the formatted text to the actual field
e.setText(fakeDoc.getRange().getBookmarks().get(0).getText());
}
}
@Override
public void imageFieldMerging(ImageFieldMergingArgs args){
}
});
Upvotes: 0
Reputation: 1960
You can use field code to get switches and format the value accordingly. Please see the following code:
doc.getMailMerge().setFieldMergingCallback(new IFieldMergingCallback() {
@Override
public void fieldMerging(FieldMergingArgs args) throws Exception {
// This is a dummy value.
String value = args.getFieldName();
// Get field code to check formatting switches.
String fieldCode = args.getField().getFieldCode(false);
// Format the value according to the switches in the field code.
if (fieldCode.contains("\\* Upper"))
value = value.toUpperCase();
if (fieldCode.contains("\\* Lower"))
value = value.toLowerCase();
args.setText(value);
}
@Override
public void imageFieldMerging(ImageFieldMergingArgs arg0) throws Exception {
return;
}
});
Hope this helps.
Disclosure: I work at Aspose.Words team.
Upvotes: 1