@akondewar The problem here is with decimal and grouping separators. In invariant English culture dot is used as a decimal separator on other hand om Dutch culture coma is used as decimal separator. Aspose.Words use this information while parsing double values from the strings passed in XML. in your XML you have the following:
<SO_Qty>5.0</SO_Qty>
<SOL_Unit_price>150.000000</SOL_Unit_price>
In invariant English culture the values will be parsed as:
SO_Qty = 5.0
SOL_Unit_price = 150.0
but in Dutch culture where dot is a grouping separator the values will be parsed as
SO_Qty = 50.0
SOL_Unit_price = 150000000.0
This is the first problem.
The second is the number format code. Suppose in the template you have field like this:
{ MERGEFIELD SO_Qty \# "#,##0.00" }
Depending on the culture coma and dot are treated as grouping or decimal separator. The specified format #,##0.00
is valid for invariant English culture, but is not valid for Dutch culture, where coma is a decimal separator. To make it valid for Dutch culture it is required to swap coma and dot in the number format.
You can fix both issues using IFieldMergingCallback
:
// Set locale for the current thread.
Locale current = CurrentThreadSettings.getLocale();
CurrentThreadSettings.setLocale(Locale.forLanguageTag("nl-NL"));
DataSet ds = new DataSet();
ds.readXml("C:\\Temp\\data.xml");
Document doc = new Document("C:\\Temp\\in.docx");
doc.getMailMerge().setFieldMergingCallback(new CorrectFormatCallback());
doc.getMailMerge().execute(ds.getTables().get(0));
doc.save("C:\\temp\\out.docx")
// Restore locale.
CurrentThreadSettings.setLocale(current);
private static class CorrectFormatCallback implements IFieldMergingCallback
{
@Override
public void fieldMerging(FieldMergingArgs args) throws Exception {
// Get the merge field
FieldMergeField mf = (FieldMergeField)args.getField();
// check whether the merge field has numeric format.
if(mf.getFormat().getNumericFormat()!=null && !mf.getFormat().getNumericFormat().equals("")) {
// FIX of the first problem. Parse the value and reset parsed as field value.
double parsedValue = Double.parseDouble((String) args.getFieldValue());
args.setFieldValue(parsedValue);
// Check whether dot is used as decimal separator in current culture.
DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(CurrentThreadSettings.getLocale());
if(format.getDecimalFormatSymbols().getDecimalSeparator() != '.')
{
// FIX of the second problem. Change the field format code
mf.getFormat().setNumericFormat("#.##0,00");
}
}
}
@Override
public void imageFieldMerging(ImageFieldMergingArgs args) throws Exception {
// Do nothing.
}
}
Here is simplified data source, simplified template and output:
data.zip (223 Bytes)
in.docx (14.5 KB)
out.docx (10.3 KB)