Feature request: Aspose.Words - hook for data source values formatting

Aspose.Words has a hook that can be used to format MS Word fields IFieldResultFormatter

Would be nice to have similar hook for data source values too, to be able to format data source values. In addition to greater flexibility, this would also help to workaround issues like WORDSJAVA-2097 - it would be possible to format dates in desired timezone on a per document basis from the code and not wait for WORDSJAVA-2097 issue fix.

@zuzuzu

It is to inform you that the issue WORDSJAVA-2097 has been resolved and its fix will be available in next version of Aspose.Words i.e. 19.7 (July 2019 release).

Your query was related to LINQ Reporting instead of date Field in Word document. You can Implement IFieldResultFormatter interface if you want to control how the field result is formatted.

Yes, i understand that IFieldResultFormatter can be used to format MS Word fields. What I’m talking about in this feature request is that it would be nice to have a way to do the same with datasource values used by LINQ Reporting.

Example:

MS Word

template created with DATE field in it. During document generation i can hook/format date field using IFieldResultFormatter.

LINQ Reporting

template created with <<[car.manufactureDate]>> field in it. During document generation i cannot hook/format date because IFieldResultFormatter is only for fields. I have to define format on each date field that is in template.
And feature request is to have a formatter for LINQ Reporting fields, like there is IFieldResultFormatter for MS Word fields.

@zuzuzu

In your case, we suggest you please read the following article.
Outputting Expression Results

Thank you, but that article describes how to apply format separately to each field. Defining format on multiple fields makes template hard to read because it becomes filled with tags. If I follow the article, template would contain a lot of repetitive formatting
Created: <<[item.created]:"yyyy.MM.dd hh:mm a">> Updated: <<[item.updated]:"yyyy.MM.dd hh:mm a">> Closed: <<[item.closed]:"yyyy.MM.dd hh:mm a">> Due Date: <<[item.dueDate]:"yyyy.MM.dd hh:mm a">>

if there was some kind of IDatasourceResultFormatter for datasource values (like there is IFieldResultFormatter for MS Word fields), template would be more readable, and formatting could be done in java code
Created: <<[item.created]>> Updated: <<[item.updated]>> Closed: <<[item.closed]>> Due Date: <<[item.dueDate]>>

Moreover, if you want to show some default value like N/A instead of null, readability becomes even worse:
Created: <<if [item.created == null]>>N/A<<else>><<[item.created]:"yyyy.MM.dd hh:mm a">><</if>> Updated: <<if [item.updated == null]>>N/A<<else>><<[item.updated]:"yyyy.MM.dd hh:mm a">><</if>> Closed: <<if [item.closed == null]>>N/A<<else>><<[item.closed]:"yyyy.MM.dd hh:mm a">><</if>> Due Date: <<if [item.dueDate == null]>>N/A<<else>><<[item.dueDate]:"yyyy.MM.dd hh:mm a">><</if>>

if there was some kind of IDatasourceResultFormatter for datasource values, template would be just
Created: <<[item.created]>> Updated: <<[item.updated]>> Closed: <<[item.closed]>> Due Date: <<[item.dueDate]>>

and IDatasourceResultFormatter could handle replacing nulls with desired default value, as well as provide default formatting:

  private class DatasourceResultFormatter implements IDatasourceResultFormatter {
    private String formatValue(Object value, String format) {
      if (value == null) return "N/A";
      return String.format(format == null ? "yyyy.MM.dd hh:mm a" : format, value);
    }

    public String formatNumeric(Double value, String format) {
      formatValue(value, format);
    }

    public String formatDateTime(Date value, String format) {
      formatValue(value, format);
    }

    public String formatString(String value, String format) {
      formatValue(value, format);
    }
  }

In case of Time zone or locale issues, such a formatter would allow to workaround it easily in formatDateTime method for all existing templates by applying timezone, that is why i had referenced WORDSJAVA-2097 in this context before.

To summarize, this is more about flexibility and readability of template. I understand that this all can be done by adding more tags and methods calls to templates. But having such a formatter would allow to apply changes without any changes in templates, and would provide one entry point for default data formatting and workarounds.

Not sure if that is possible, just a proposal for feature.

@zuzuzu

We suggest you please read the following article.
Setting up Known External Types

You can write your own Java code to format the date according to your requirement and use it in LINQ Reporting. E.g. following code example shows how to format the date. Hope this helps you.

DocumentBuilder builder = new DocumentBuilder();
builder.write("<<[MyDate.getOrdinalDate()]>>");
ReportingEngine engine = new ReportingEngine();
engine.getKnownTypes().add(MyDate.class);
engine.buildReport(builder.getDocument(), "");

builder.getDocument().save(MyDir + "Out.docx");

public class MyDate {
    public static String getDayNumberSuffix(int n) {
        switch (n % 10) {
            case 1:  return "st";
            case 2:  return "nd";
            case 3:  return "rd";
            default: return "th";
        }
    }

    public static String getOrdinalDate()
    {
        String dayNumberSuffix = getDayNumberSuffix(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
        SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM dd'" + dayNumberSuffix + "' yyyy");
        return  dateFormat.format(Calendar.getInstance().getTime());
    }
}

Yes, this helps, thank you!

@zuzuzu

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