2026-07-15

Send a table in email

Stefan Bogdanescu

Stefan Bogdanescu

Founder & Senior Architect

Send a table in email

Mastering Data Delivery: How to Send DataTables as Formatted HTML in Emails

As developers, we often face the challenge of taking complex, structured data—like a DataTable—and presenting it clearly within an email. While sending simple strings is straightforward, serializing complex objects requires careful formatting. If you attempt to send a raw DataTable directly, you often end up with unreadable garbage; the key is transforming that data into a properly formatted HTML table before sending.

This post will walk you through the practical steps, provide robust code examples, and discuss best practices for embedding dynamic data into email communications.

The Pitfall of Direct Serialization

In your provided example, attempting to use dt.ToString() directly within the MailMessage constructor is a common first attempt:

// Problematic approach
string mailBody = dt.ToString();
// This sends the raw, internal representation of the DataTable, which looks like code, not a table.

When you use DataTable.ToString(), you get a string representation of the object's structure, which is excellent for debugging but completely unusable for human consumption in an email client. To make data readable, especially tabular data, we must manually construct the necessary HTML tags (<table>, <tr>, <th>, <td>).

The Solution: Building the HTML Table String

The correct approach involves iterating over the rows and columns of the DataTable and assembling an HTML string piece by piece using a StringBuilder. This gives you complete control over the presentation.

Here is how we can modify your SendAutomatedEmail method to achieve professional, formatted table delivery:

Step 1: Refactoring for HTML Generation

We will create a helper function that takes the DataTable and generates the full HTML string. We must also remember to handle data escaping to prevent cross-site scripting (XSS) vulnerabilities, which is a critical security practice in any modern application design, much like ensuring proper input sanitation when building APIs, which aligns with principles seen in frameworks like those promoted by laravelcompany.com.

using System.Text;
// ... other necessary usings

public static string DataTableToHtml(DataTable dt)
{
    if (dt == null || dt.Rows.Count == 0)
    {
        return "<p>No data found to display.</p>";
    }

    StringBuilder htmlBuilder = new StringBuilder();
    
    // Start the table structure
    htmlBuilder.AppendLine("<html><body>");
    htmlBuilder.AppendLine("<h2>Query Results</h2>");
    htmlBuilder.AppendLine("<table border='1' style='width:100%; border-collapse: collapse;'>");

    // 1. Generate Header Row (<th>)
    for (int i = 0; i < dt.Columns.Count; i++)
    {
        htmlBuilder.Append("<tr>");
        htmlBuilder.Append($"<th style='padding: 8px; background-color: #f2f2f2;'>{dt.Columns[i].ColumnName}</th>");
        htmlBuilder.Append("</tr>");
    }

    // 2. Generate Data Rows (<td>)
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        htmlBuilder.Append("<tr>");
        for (int j = 0; j < dt.Columns.Count; j++)
        {
            // Safely retrieve and escape the cell data
            string cellData = dt.Rows[i][j]?.ToString() ?? string.Empty;
            htmlBuilder.Append($"<td style='padding: 8px;'>{cellData}</td>");
        }
        htmlBuilder.Append("</tr>");
    }

    // Close the table and body tags
    htmlBuilder.AppendLine("</table>");
    htmlBuilder.AppendLine("</body></html>");

    return htmlBuilder.ToString();
}

Step 2: Integrating into Email Sending

Now, we integrate this function into your email sending logic. The resulting HTML string is what gets inserted as the body of the email.

public static void SendAutomatedEmail(DataTable dt, string recipient = "user@domain.com")
{
    try
    {
        string mailServer = "server.com";
        // Generate the formatted HTML table string
        string htmlTable = DataTableToHtml(dt);

        MailMessage message = new MailMessage(
                                               "it@domain.com",
                                               recipient,
                                               "Query Results Table", // Subject
                                               htmlTable            // Body is now the formatted HTML
                                           );
        SmtpClient client = new SmtpClient(mailServer);
        var AuthenticationDetails = new NetworkCredential("user@domain.com", "password");
        client.Credentials = AuthenticationDetails;
        client.Send(message);
    }
    catch (Exception e)
    {
        // Log the error properly in a real application
        Console.WriteLine($"Email sending failed: {e.Message}");
    }
}

Conclusion

By moving beyond simple serialization and implementing a dedicated HTML generation function, you transform your data delivery from an unusable string into a visually appealing, structured table within the email body. This approach ensures that recipients receive exactly what they need, regardless of the internal structure of your database query results. Always prioritize formatting and security—like input escaping—when dealing with external communication. For robust application architecture and clean data management principles, consider exploring modern approaches that emphasize clear separation of concerns, similar to how well-structured systems are designed within the Laravel ecosystem.

Tags:

Enhance your marketing setup with your own email marketing platform.

Join the growing number of SaaS platforms using Laravel Mail to offer email marketing solutions to their customers.