You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:28:10