Sample below of relevant section of the GEL script to create the HTML table:
<gel:parse var="htmlMessage">
<message><![CDATA[<html><head><title>${email_subject}</title><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /><style type="text/css">
.s {
height: 0;
line-height: 1;
position: relative;
top: -0.6em;
vertical-align: baseline;
vertical-align: bottom;
font-size: xx-small;
}
.b {
font-weight: bold;
}
.r {
color: rgb(255,0,0);
}
</style></head><body><font face="Arial"><h2><u>${email_subject}</u></h2><table border="1" cellpadding="5"><font size="2"><tr border="0"><th border="0">Item</th><th border="0">Status</th><th border="0">Comments</th></tr><tr border="0"><td border="0">PMO Checks</td><td border="0">Completed with ${proc_errors} process error(s) and ${xog_fails} XOG failure(s).]]><core:if
test="${v_queryresult1.rowCount gt 0 }"><![CDATA[Projects need reviewing are : <br /><ul>]]><core:forEach items="${v_queryresult1.rows}"
var="v_row"><![CDATA[<li>${v_row.PRJ_CODE} </li>]]></core:forEach><![CDATA[</ul>]]></core:if><![CDATA[</td><td border="0">Finish Time =${fin_time} <br />
******</td></td></tr><tr border="0"><td border="0">Data Exceptions</td><td border="0">${num_excepts} exceptions <br />
${ex_crit}-Critical <br/>
${ex_sever}-Severe <br/>
${ex_mild}-Mild <br/>
${ex_warn}-Warning
</td></td></tr></font></table><p/>
<p/></font></body></html>]]></message>
</gel:parse>
I have stripped out a significant amount of the GEL for confidentiality reasons, and not undertaken any verification if it is still correct, but hopefully it will give you an idea of what is required, and if you want to go down this path.
It is basically using HTML for the email content, and wrapping the 'table' section around a 'core:for each' to read required data which is creating required rows/columns.
There may be other ways to achieve the above, but as the above was a once-off, which we have never been requested to repeat, this is how we achieved it.