Prerequisites: I would strongly encourage you to read the official documentation about how to write a plugin if you’re not familiar with plugin development.
The support of Rich Text format in Single / Multiple line(s) of text fields in Model-Driven App / Dynamics 365 was a great enhancement delivered few years ago. The content can be easily edited in forms thanks to a native rich text editor control that is using CKEditor. In views, the formatted text is automatically converted to a plain text version to provide an easier to read display of data.
On the other hand, when using the native export to Excel feature the HTML content of rich text fields is exported instead of a plain text version. That behavior makes perfect sense to me since it allows for easy export / import of data from one environment to another. But in certain circumstances you want to export the data to analyze it and an easy-to-read version of those rich text fields would be welcomed. Though no out-of-the box option exists, it is quite easy to implement such logic with a plugin.
The code of the sample project can be foud here.
Out-of-the box behavior
By default, text fields formatted as rich text are displayed and edited using a WYSIWYG editor:
The formatting is removed from the views without any additional configuration:
The Export to Excel feature returns the actual fields values that contain HTML:
The proposed solution involves the development of a plugin that will be triggered when the RetrieveMultiple message is sent regarding the specified entity. The plugin detects if the result set contains Rich Text fields and removes the HTML tags from the fields values. Also, the plugin detects if it’s called by the Export to Excel action.
Detecting the Export to Excel action
It is primordial to only remove the HTML markup when the values are retrieved by an Export to Excel action to avoid any side effects. Therefore, registering the plugin step to be called whenever the RetrieveMultiple message is triggered for the specified entity is not enough. Fortunately, the parent context’s message can be checked.
Removing the HTML markup
Since there is no official method provided by the .Net framework to convert HTML to plain text an external library must be used, or we can add some custom logic. Just for fun let’s call ChatGPT to the rescue:
This method is extremely basic and won’t cover some cases as stated by ChatGTP:
Let’s improve the generated code:
This implementation is fine for my example, but you may want to improve it depending on your use case. Here is the code:
Finding the Rich Text Fields
Another aspect that must be handled is the detection of the rich text fields. The attributes’ metadata can be read to filter the ones configured to be formatted as rich text.
Putting all the pieces together
Now that all the logic blocks have been figured out, we can put them together in a plugin class:
Disclaimer: you should not use this sample in production. Exception handling is missing, and the code has not been thoroughly tested.
Registering the step
Once the plugin is built and the assembly is registered you can register a new step for each entity that needs to be handled:
- Message: RetrieveMultiple
- Stage of execution: PostOperation
- Execution mode: Synchronous
After registering the step and exporting the view to Excel again we can see the fields values as plain text: