简体   繁体   中英

Beautify Table layout in plain text email

I have the following routine for converting a DataBable to plain text for presenting in an email. However, as you see from the included layout image, the header rows are out of alignment with the column data. Is there any way of getting it to align correctly?

在此处输入图片说明

Function MakeHtmlEmailFromDataTable(dt As DataTable) As System.Text.StringBuilder
    Dim retVal As String = ""
    Dim html As New System.Text.StringBuilder

    For Each col As System.Data.DataColumn In dt.Columns
        html.Append(col.Caption & vbTab & vbTab)
    Next

    For Each dr As System.Data.DataRow In dt.Rows

        For i = 0 To dr.ItemArray.Length - 1
            html.Append(dr.ItemArray(i).ToString & vbTab & vbTab & vbTab & vbTab)
        Next
        html.Append(vbTab & vbCrLf)
    Next

    Return html
End Function

First thing I noticed is that you have two tabs between column in the header, and four tabs between columns in the data.

But going deeper, plain text will not automatically respect tab stops to make columns. The only way you can fix this is if you have some idea of how long your data will be, relative to how long a tab stop is. This means you have a big problem, because tab stops can be set differently on different systems and even in different applications within the same system. Even if you have a perfect understanding of your data widths, situations with weird tab stop sizes will throw you off. The only way the tab stop mechanism has any chance is with fixed-width fonts and if your data is all exactly the same length, or if you can guarantee what e-mail client will be used on what operating system.

Your only real chance is to use a system that actually allows you to define columns, such as with the html suggested by the names in your code:

Function MakeHtmlEmailFromDataTable(dt As DataTable) As System.Text.StringBuilder
    Dim html As New System.Text.StringBuilder("<table><thead><tr>")

    For Each col As System.Data.DataColumn In dt.Columns
        html.AppendFormat("{0}{1}{2}", "<th>", col.Caption, "</th>")
    Next

    html.AppendLine("</tr></thead><tbody>")

    For Each dr As System.Data.DataRow In dt.Rows
        html.Append("<tr>")
        For i = 0 To dr.ItemArray.Length - 1
            html.AppendFormat("{0}{1}{2}", "<td>", dr.ItemArray(i).ToString(), "</td>")
        Next
        html.AppendLine("</tr>")
    Next
    html.AppendLine("</tbody></table>")

    Return html
End Function

If it is not too much data, you can loop twice. Once to get max col sizes (into an array) and the next to populate html. Then for the headers you basically do a mid (making the headers exactly the same size). Then both the Header and the columns each only have a single between them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM