Spring Boot中如何将ResultSet映射转为HTML表格并邮件发送
问题描述
我正在构建一个执行SQL查询的Spring Boot应用,已实现查询结果的保存与展示。现在需要将该结果转换为HTML表格并通过邮件发送,但卡在了HTML转换环节。我了解过Thymeleaf,疑惑该如何将查询得到的Map集合传入generateMailHtml方法,希望获取解决方案(可使用Thymeleaf或其他方式)。
现有代码
Java业务代码
public void resultSet(Exchange exchange) { Connection connection = null; Map < String, List < nl.placeholder.databasemailer.ResultSet >> valueMap; try { connection = dataSource.getConnection(); Statement stmt = connection.createStatement(); List < Map < String, Object >> rows = new ArrayList < Map < String, Object >> (); ResultSet rs = stmt.executeQuery("select bridgeid, containername from baseintegrationheaders"); //valueMap = new HashMap<>(); ResultSetMetaData md = rs.getMetaData(); int columnCount = md.getColumnCount(); while (rs.next()) { Map < String, Object > columns = new LinkedHashMap < String, Object > (); for (int i = 1; i <= columnCount; i++) { columns.put(md.getColumnLabel(i), rs.getObject(i)); } rows.add(columns); exchange.getIn().setBody(columns); // 此处会多次覆盖body,建议移除 System.out.println(columns); } exchange.getIn().setBody(rows); } catch (SQLException e) { throw new RuntimeException(e); } } public String generateMailHtml(String text) { Map < String, Object > variables = new HashMap < > (); variables.put("mailtext", text); final String templateFileName = "mail"; String output = this.templateEngine.process(templateFileName, new Context(Locale.getDefault(), variables)); return output; }
Thymeleaf模板(mail.html)
<!DOCTYPE html> <html> <div> <table class=" table table-bordered table-striped table-hover table-responsive-xl " > <thead class="thead-dark"> <tr> <th>Date</th> <th>BridgeId</th> <th>RequestType</th> <th>RequestSpecification</th> <th>FaultDescription</th> <th>SourceSystem</th> <th>EventId</th> <th>MessageId</th> <th>RelatesTo</th> <th>SysTimeStamp</th> </tr> </thead> <tbody> <tr th:each="rows :${rows}"> <td> [[${rows.date}]] </td> <td> [[${rows.bridgeid}]] </td> <td> [[${rows.requesttype}]] </td> <td> [[${rows.requestspecification}]] </td> <td> [[${rows.faultdescription}]] </td> <td> [[${rows.sourcesystem}]] </td> <td> [[${rows.eventid}]] </td> <td> [[${rows.messageid}]] </td> <td> [[${rows.relatesto}]] </td> <td> [[${rows.systimestamp}]] </td> </tr> </tbody> </table> </div> </html>
解决方案
方案一:使用Thymeleaf实现(推荐)
1. 修改generateMailHtml方法
将方法参数改为接收查询得到的List<Map<String, Object>>,并将该集合作为变量传入Thymeleaf上下文:
public String generateMailHtml(List<Map<String, Object>> rows) { Map<String, Object> variables = new HashMap<>(); variables.put("rows", rows); // 将查询结果集合传入模板变量 final String templateFileName = "mail"; return this.templateEngine.process(templateFileName, new Context(Locale.getDefault(), variables)); }
2. 调整Thymeleaf模板与SQL查询匹配
注意你的SQL查询仅返回bridgeid和containername两个字段,但模板中定义了大量不匹配的表头和字段引用,需要统一两者:
- 要么修改SQL查询,获取模板中需要的所有字段(
date、requesttype等); - 要么调整模板,只保留与SQL查询对应的表头和字段:
<!DOCTYPE html> <html> <div> <table class=" table table-bordered table-striped table-hover table-responsive-xl " > <thead class="thead-dark"> <tr> <th>BridgeId</th> <th>ContainerName</th> </tr> </thead> <tbody> <tr th:each="row : ${rows}"> <!-- 变量名改为row,语义更清晰 --> <td>[[${row.bridgeid}]]</td> <td>[[${row.containername}]]</td> </tr> </tbody> </table> </div> </html>
3. 调用生成HTML
在resultSet方法中,获取到查询结果rows后,直接调用修改后的generateMailHtml方法:
// 在exchange.getIn().setBody(rows);之后添加 String mailHtmlContent = generateMailHtml(rows); // 后续使用mailHtmlContent发送邮件即可
方案二:手动拼接HTML表格(适合简单场景)
如果不想依赖Thymeleaf,可以直接通过字符串拼接生成HTML表格:
public String generateHtmlTableManually(List<Map<String, Object>> rows) { if (rows.isEmpty()) { return "<p>暂无查询结果</p>"; } StringBuilder htmlBuilder = new StringBuilder(); // 构建表格容器和表头 htmlBuilder.append("<div><table class='table table-bordered table-striped table-hover table-responsive-xl'>"); htmlBuilder.append("<thead class='thead-dark'><tr>"); // 取第一条数据的key作为表头(自动适配SQL返回的字段) Map<String, Object> firstRow = rows.get(0); for (String columnName : firstRow.keySet()) { htmlBuilder.append("<th>").append(columnName).append("</th>"); } htmlBuilder.append("</tr></thead><tbody>"); // 构建表体数据行 for (Map<String, Object> row : rows) { htmlBuilder.append("<tr>"); for (Object value : row.values()) { htmlBuilder.append("<td>").append(value != null ? value : "").append("</td>"); } htmlBuilder.append("</tr>"); } htmlBuilder.append("</tbody></table></div>"); return htmlBuilder.toString(); }
内容的提问来源于stack exchange,提问作者Beerus239
相关产品推荐
相关产品推荐

