🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
HtmlReport
This page was created by Lars.olofsson on 2020-06-18. Last edited by Wikiadmin on 2026-07-29.

You can generate XHTML, HTML-shaped output, or XML from a ViewModel by placing ViewModel values into an XHTML/XML template; use this page when you need a data-driven report as a string, BLOB, or browser output.

Overview

HtmlReport processes a template and replaces tags with data from a ViewModel. The result is XHTML as a string or BLOB, or it can be opened in the browser.

The report processor works with XHTML and XML. XHTML is XML-compatible HTML and has one root node. This matters because the template is processed as a DOM (Document Object Model): tags must occur inside valid XML/XHTML nodes to be found and replaced.

HtmlReport shares much of its processing logic with OpenDocument reporting. Use HtmlReport when your output is XHTML or XML; use OpenDocument when you need an OpenDocument file such as an ODT or ODS template.

What you need

  1. A report ViewModel that exposes the values to insert and, where applicable, identifies the template location.
  2. An XHTML or XML template containing report tags.
  3. An OCL or EAL expression that invokes the appropriate report operation.

A ViewModel is the contract between the template and your model. If the template contains %Customername%, the report ViewModel must provide a column named Customername in the relevant ViewModel context.

Create a basic HTML report

1. Create the report ViewModel

In ViewModel Editor, create a ViewModel that obtains the report root object and add the columns required by the template.

For example, a report ViewModel can expose these scalar columns:

ViewModel column Example value Template tag
String John %String%
Text Thank you for your order. %Text%

The ViewModel also supplies the information needed to retrieve the template. A template can be retrieved from:

  • A String attribute in a modeled class.
  • A BLOB attribute in a modeled class. The BLOB content is Base64 encoded.
  • A URL.
  • The local file system.

2. Create a well-formed template

Put each scalar ViewModel column name between percent signs. The following template replaces %String% and %Text% with the corresponding ViewModel values:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <body>
    <p>Hello %String%</p>
    <p>%Text%</p>
  </body>
</html>

For the example values above, the report output includes:

<html>
  <body>
    <p>Hello John</p>
    <p>Thank you for your order.</p>
  </body>
</html>

3. Run the report

Use the report operation that matches the input and desired output. In the following examples:

  • self becomes the root object of the reporting ViewModel.
  • ReportRoot is the class that owns the reporting ViewModel.
  • ViewModels retrieves the class ViewModels.
  • ReportingViewmodel is the report ViewModel name.

Choose a report operation

Operation Use it when Result
XHtmlReportAsString Your template input is a string and you need XHTML as a string. A string. No Base64 encoding of input HTML is required.
opendocumentreportasblob Your template and output are handled as byte arrays. A BLOB. Content is UTF-8 encoded and Base64 formatted.
opendocumentreportshow You want to generate the BLOB-based report and open the resulting HTML in the browser. Browser output.

Return XHTML as a string

ResultHtmlAsString := self.XHtmlReportAsString(ReportRoot.ViewModels.ReportingViewmodel)

XHtmlReportAsString is the easiest option when the template is already a string. For operator-specific information, see Documentation:OCLOperators XHtmlReportAsString.

Return XHTML as a BLOB

ResultHtmlAsBlob := self.opendocumentreportasblob(ReportRoot.ViewModels.ReportingViewmodel)

For BLOB processing, content must be UTF-8 encoded and in Base64 format. Use BlobToBase64 to obtain a Base64 string from a BLOB, or StringToBase64 to obtain one from a String. The resulting Base64 string is then used as the BLOB content.

Open the report in the browser

self.opendocumentreportshow(ReportRoot.ViewModels.ReportingViewmodel)

Insert scalar values

A scalar tag is a ViewModel column name surrounded by percent signs:

<p>Invoice date: %Date%</p>
<p>Customer: %Customername%</p>

If the current ViewModel object has Date and Customername columns, each tag is replaced by that column's value. You can use the same tag more than once in the template.

Repeat markup for a multi-link

A multi-link is a ViewModel relationship that supplies multiple objects. Mark the containing XML/XHTML element with %%+MultiLinkName% to repeat that element once for every object in the multi-link.

For example, if Invoices is a multi-link and every invoice provides Date and Customername, place the repeat tag in the table row:

<table>
  <tbody>
    <tr>
      <td>Date</td>
      <td>Customer</td>
    </tr>
    <tr>%%+Invoices%
      <td>%Date%</td>
      <td>%Customername%</td>
    </tr>
  </tbody>
</table>

The processor repeats the <tr> element, including its contents, for each object in Invoices. Within the repeated row, %Date% and %Customername% are evaluated for the current invoice.

Render a collection of strings

A collection of strings needs a small ViewModel wrapper so that every string can be addressed as a value during repetition.

  1. Create a ViewModel column that returns the collection of strings. For example, it may return values produced from a comma-separated list.
  2. Create another ViewModel class without setting its type; it is derived from ViewModel.
  3. Add a column in that ViewModel class with self as its expression. This column represents the current string value.
  4. Repeat the collection in the template and insert the current value column.

For example:

<p>%%+Viewmodel.AttributeOfCollection% %NameOfValueAttribute%</p>

The processor iterates Viewmodel.AttributeOfCollection and fills %NameOfValueAttribute% for each string.

Use HTML and XML templates safely

Provide one document root

Use a well-formed XHTML or XML document with one root node. Valid XHTML typically uses an <html> root and places visible content inside <body>.

XHtmlReportAsString attempts to compensate when a template has no <root>, <body>, or <html> element. For example, this fragment has two top-level elements:

<p>Hello %String%</p>
<p>You need to do this....</p>

The operation adds an <html> wrapper:

<html>
  <p>Hello John</p>
  <p>You need to do this....</p>
</html>

Treat this wrapping as a fallback. Author a complete, single-root XHTML template when you control the template.

Put tags inside valid elements

The DOM processor only sees valid nodes. A tag that is not inside a valid element may not be detected or replaced.

Use a containing element:

<html>
  <p>%myTag%</p>
</html>

Do not rely on the <html> element alone to make an otherwise invalid fragment usable. If tags are left unchanged in the output, validate the XHTML/XML structure first and ensure that the tag occurs inside a valid node.

Generate XML

The same tag and repeat logic applies to XML. You can use tags in element text and attributes, and repeat an XML element for a multi-link:

<SomeXml attrib='%SomeVMColumnAsAttributeresult%'>
  %SomeOtherVMColumnAsXMLTextresult%
  <Items>
    <Item>%%+TheVMNestingColumn%
      <ContentInItem someattrib='%VMColInNesting%'>
        %StuffFromViewModelNesting%
      </ContentInItem>
    </Item>
  </Items>
</SomeXml>

In this example, %SomeVMColumnAsAttributeresult% supplies an attribute value, and the <Item> element repeats for each object in TheVMNestingColumn.

Discover the available tags

Use %meta% while developing a template to obtain the exact tags available from the report ViewModel.

  1. Add %meta% as the first string in an element.
  2. Run the report.
  3. Copy the generated tag names, including their percent signs, into the template.

For HTML, use a holder element such as:

<meta>%meta%</meta>

A generated result can contain a list such as:

<html>
  <meta>%TemplateHtml%, %TemplateBlob%, %ReportFileName%, %String%, %Text%,</meta>
</html>

The %meta% token must be the first string in its element to be recognized. Use the generated spelling and casing exactly when creating tags.

Troubleshooting

Symptom Check
Tags remain as %Name% in the output. Confirm that the ViewModel provides a column named Name, that the tag is in a valid XHTML/XML element, and that the template has a valid document structure.
A repeated row or element does not appear. Confirm that the multi-link name in %%+MultiLinkName% matches the ViewModel multi-link and that the multi-link has objects to iterate.
You do not know the tag spelling. Add %meta% as the first string in an element, run the report, and copy the generated tags.
The template is plain HTML from an editor. Check that it has one root node and is well-formed enough for DOM processing. Prefer XHTML/XML when possible.
You need report-generated HTML inside a user interface. See Documentation:Column.DataIsHtml. A column marked DataIsHtml can use HTML directly, including HTML produced through HtmlReport.

See also

Report templates and ViewModel data

Report templates and ViewModel data

HtmlReport creates output by processing an XHTML template and adding data from a ViewModel. The resulting XHTML can then be returned as a string or handled as blob-based content, depending on the function used.

To prepare an HtmlReport:

  1. Create a ViewModel that extracts the data needed for the report.
  2. Provide an XHTML template containing tags that correspond to attributes in the ViewModel.
  3. Configure where the template is retrieved from. Templates can be retrieved from a string attribute, a base64-encoded BLOB attribute, a URL, or the local filesystem.
  4. Use the applicable HtmlReport function for the input and output format.

The same functionality also applies when XML is needed. XHTML is required to have one root node.

Authoring and self-service reporting

This page documents template-based report generation using a ViewModel and XHTML or XML input. It does not, in the available documentation, describe who is expected to author report templates or whether users can create or modify reports at runtime.

For requirements involving end-user report design, ad hoc data selection, dashboards, report security, or external reporting tools, verify the supported approach for the relevant MDriven version before making an implementation decision.

See also

  • ViewModel documentation
  • OpenDocument functionality