使用 C# 从数据表创建 HTML

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9792882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 08:53:47  来源:igfitidea点击:

Creating HTML from a DataTable using C#

c#.netdatatableoutlook

提问by l--''''''---------''''''''''''

I need to be able to pass HTML data into Outlook like this:

我需要能够像这样将 HTML 数据传递到 Outlook 中:

MailMessage message = new MailMessage();
message.Body = myBody;

Initially, I thought I could pass plain text to it and use PadLeftlike this:

最初,我以为我可以将纯文本传递给它并PadLeft像这样使用:

somestring.PadLeft(100);

but it did not align everything properly because even though |||||and MMMMMare both only 5 characters in length, they physically on the screen take up more space.

但它没有对齐一切正常,因为即使|||||MMMMM的长度都只有5个字符,它们在物理屏幕上占用更多的空间。

My solution is to convert data that is in my datatable into an HTML table and then pass it into Outlook.

我的解决方案是将数据表中的数据转换为 HTML 表,然后将其传递到 Outlook。

  1. how do I convert a datatable into an html table?
  2. is there a better solution to my issue?
  1. 如何将数据表转换为 html 表?
  2. 我的问题有更好的解决方案吗?

采纳答案by mservidio

Loop over your DataTable, and build up the html string. IE:

循环遍历您的 DataTable,并构建 html 字符串。IE:

DataTable dt = new DataTable();

dt.Columns.Add("col1");
dt.Columns.Add("col2");
dt.Columns.Add("col3");
dt.Rows.Add(new object[] { "a", "b", "c" });
dt.Rows.Add(new object[] { "d", "e", "f" });

string tab = "\t";

StringBuilder sb = new StringBuilder();

sb.AppendLine("<html>");
sb.AppendLine(tab + "<body>");
sb.AppendLine(tab + tab + "<table>");

// headers.
sb.Append(tab + tab + tab + "<tr>");

foreach (DataColumn dc in dt.Columns)
{        
    sb.AppendFormat("<td>{0}</td>", dc.ColumnName);        
}

sb.AppendLine("</tr>");

// data rows
foreach (DataRow dr in dt.Rows)
{
    sb.Append(tab + tab + tab + "<tr>");

    foreach (DataColumn dc in dt.Columns)
    {
        string cellValue = dr[dc] != null ? dr[dc].ToString() : "";
        sb.AppendFormat("<td>{0}</td>", cellValue);
    }

    sb.AppendLine("</tr>");
}

sb.AppendLine(tab + tab + "</table>");
sb.AppendLine(tab + "</body>");
sb.AppendLine("</html>");

回答by Adriano Repetti

Code could be pretty long to write here, I agree with @mservidio. Follow this link to see an example of what you have to do: this link

在这里写代码可能很长,我同意@mservidio。按照此链接查看您必须执行的操作的示例:此链接

回答by Icarus

how do i convert a datatable into an html table?

如何将数据表转换为 html 表?

The only way is to write code that goes through every row and builds the HTML string the way you need it.

唯一的方法是编写遍历每一行的代码并按照您需要的方式构建 HTML 字符串。

is there a better solution to my issue?

我的问题有更好的解决方案吗?

You could use a monospace font (such as Courier) wihch will allow you to align everything properly by simply outputting the right number of spaces but you'd still need to send the email in HTML format setting the proper font on the document.

您可以使用等宽字体(例如Courier),这样您就可以通过简单地输出正确数量的空格来正确对齐所有内容,但您仍然需要以 HTML 格式发送电子邮件,并在文档上设置正确的字体。

回答by Shai Cohen

There are a number of ways to output the HTML.

有多种方法可以输出 HTML。

If this is a relatively easy format (not much formatting, styles etc.) I would definitely go with @mservidio's suggestion.

如果这是一种相对简单的格式(没有太多格式、样式等),我肯定会同意@mservidio 的建议。

If the output is more complex and you have experience with ASP.NET you can go the route of a UserControl which allows more flexibility and management of the output. You can then render the output of the control to HTML like this:

如果输出更复杂并且您有使用 ASP.NET 的经验,则可以采用 UserControl 的路线,这样可以更灵活地管理输出。然后,您可以像这样将控件的输出呈现为 HTML:

StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);

ctrl.RenderControl(hw);
return sb.ToString();

回答by Andamon A. Abilar

I just want to share what I did. I hope this would help.

我只想分享我所做的。我希望这会有所帮助。

using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.IO;

public void Build(DataSet ds) 
{
    StringWriter sw = new StringWriter();
    HtmlTextWriter w = new HtmlTextWriter(sw);

    foreach (DataTable dt in ds.Tables) 
    {
        //Create a table
        Table tbl = new Table();

        //Create column header row
        TableHeaderRow thr = new TableHeaderRow();
        foreach (DataColumn col in dt.Columns) {
            TableHeaderCell th = new TableHeaderCell();
            th.Text = col.Caption;
            thr.Controls.Add(th);
        }
        tbl.Controls.Add(thr);

        //Create table rows
        foreach (DataRow row in dt.Rows)
        {
            TableRow tr = new TableRow();
            foreach (var value in row.ItemArray)
            {
                TableCell td= new TableCell();
                td.Text = value.ToString();
                tr.Controls.Add(td);
            }
            tbl.Controls.Add(tr);
        }

        tbl.RenderControl(w);

    }

    Response.Write(sw.ToString());
}

回答by Sumon Banerjee

public string toHTML_Table(DataTable dt)
        {
            if (dt.Rows.Count == 0)
                return "";

            StringBuilder builder = new StringBuilder();
            builder.Append("<html>");
            builder.Append("<head>");
            builder.Append("<title>");
            builder.Append("Page-");
            builder.Append(Guid.NewGuid().ToString());
            builder.Append("</title>");
            builder.Append("</head>");
            builder.Append("<body>");
            builder.Append("<table border='1px' cellpadding='5' cellspacing='0' ");
            builder.Append("style='border: solid 1px Silver; font-size: x-small;'>");
            builder.Append("<tr align='left' valign='top'>");
            foreach (DataColumn c in dt.Columns)
            {
                builder.Append("<td align='left' valign='top'><b>");
                builder.Append(c.ColumnName);
                builder.Append("</b></td>");
            }
            builder.Append("</tr>");
            foreach (DataRow r in dt.Rows)
            {
                builder.Append("<tr align='left' valign='top'>");
                foreach (DataColumn c in dt.Columns)
                {
                    builder.Append("<td align='left' valign='top'>");
                    builder.Append(r[c.ColumnName]);
                    builder.Append("</td>");
                }
                builder.Append("</tr>");
            }
            builder.Append("</table>");
            builder.Append("</body>");
            builder.Append("</html>");

            return builder.ToString();
        }

回答by Dr.sai

public string ConvertDataTableToHTMLTableInOneLine(DataTable dt)
    {
        //Convert DataTable To HTML Table in one line
        return "<table>\n<tr>" + string.Join("", dt.Columns.Cast<DataColumn>().Select(dc => "<td>" + dc.ColumnName + "</td>")) + "</tr>\n" +
        "<tr>" + string.Join("</tr>\n<tr>", dt.AsEnumerable().Select(row => "<td>" + string.Join("</td><td>", row.ItemArray) + "</td>").ToArray()) + "</tr>\n<\table>";

    }

回答by Dr.sai

 public string MakeJPGFromDataTable(DataTable dt)
    {
        Font fnt = new System.Drawing.Font("verdana", 10,FontStyle.Bold);
        string strPath = Path.GetTempPath();
        string strJPG = "";
        strPath += "Publisher";
        Directory.CreateDirectory(strPath);
        Graphics grfx = CreateGraphics();
        float nWdBMP = 0;
        float nHtBMP = 0;

        var TalleststringLength = dt.AsEnumerable().Max(row => row.ItemArray.Max(x => grfx.MeasureString(x.ToString(), fnt).Height));
        var longeststringLength = dt.AsEnumerable().Max(row => row.ItemArray.Max(x => grfx.MeasureString(x.ToString(), fnt).Width));
        //string ss =  dt.Columns[1].ToString();
        //int[] nColHeaderLengths = (from z in new int[7] { 0, 1, 2, 3, 4, 5, 6 } select dt.Columns.Cast<DataColumn>().Max(dc => (int)grfx.MeasureString(dt.Columns[z].ToString(), fnt).Width)).ToArray();
        //int[] nColWidths = (from z in new int[7] { 0, 1, 2, 3, 4, 5, 6 } select dt.AsEnumerable().Max(row => (int)grfx.MeasureString(row.ItemArray[z].ToString(), fnt).Width)).ToArray();
        var xx = (from x in dt.Columns.Cast<DataColumn>() select x.Ordinal).ToArray();
        var nColWidths = (from z in (xx)
                           select dt.AsEnumerable().Max(row =>
                               (grfx.MeasureString(row.ItemArray[z].ToString(), fnt).Width >
                               grfx.MeasureString(dt.Columns[z].ToString(), fnt).Width)
                               ? grfx.MeasureString(row.ItemArray[z].ToString(), fnt).Width
                               : grfx.MeasureString(dt.Columns[z].ToString(), fnt).Width)
            ).ToArray();

        nWdBMP = nColWidths.Sum();
        nHtBMP = TalleststringLength * (dt.Rows.Count + 1);
        int xPos = 0;
        int yPos = 0;
        int nMargin = 10;

        Bitmap mapMem = new Bitmap((int)nWdBMP + (nMargin * (dt.Columns.Count + 1)), (int)nHtBMP);
        Graphics grfxMem = Graphics.FromImage(mapMem);
        grfxMem.SmoothingMode = SmoothingMode.HighQuality;
        grfxMem.InterpolationMode = InterpolationMode.HighQualityBicubic;
        grfxMem.PixelOffsetMode = PixelOffsetMode.HighQuality;
        grfxMem.CompositingQuality = CompositingQuality.GammaCorrected;

        grfxMem.FillRectangle(lgBackgroundBrush,0,0,mapMem.Width,mapMem.Height);

        for (int j = 0; j < dt.Columns.Count; j++)
        {
            grfxMem.DrawString(dt.Columns[j].ToString(), fnt, lgFontBrush, xPos, yPos);
            //xPos += (int)grfx.MeasureString(dt.Columns[j].ToString(), fnt).Width;
            xPos += (int)nColWidths[j] + nMargin;
        }
        xPos = 0;
        yPos += (int)TalleststringLength;
        grfxMem.DrawLine(pen, new Point(0, yPos), new Point((int)mapMem.Width, yPos));
        //foreach (DataRow dr in dt.Rows)
        //{
        //    for (int j = 0; j < dt.Columns.Count; j++)
        //    {
        //        grfxMem.DrawString(dr[j].ToString(), fnt, Brushes.Blue, xPos, yPos);
        //        xPos += (int)nColWidths[j] + nMargin;
        //    }
        //    xPos = 0;
        //    yPos += (int)TalleststringLength;
        //}
        int s = 0;
        Func<object, bool> too_much_where = delegate(object itemCurrent)
        {
            grfxMem.DrawString(itemCurrent.ToString(), fnt, lgFontBrush, xPos, yPos);
            xPos += (int)nColWidths[s++] + nMargin;
            if (s >= dt.Columns.Count)
            {
                //Know what this determines the end of every row
                s = 0;
                xPos = 0;
                yPos += (int)TalleststringLength;
                grfxMem.DrawLine(pen, new Point(0, yPos), new Point((int)mapMem.Width, yPos));
            }
            return false;
        };
        //var sizzeler = (from dr in dt.AsEnumerable()
        //                let drItems = (from itemCurrent in dr.ItemArray select itemCurrent)
        //                               from item in drItems
        //                                where too_much_where(item)
        //                    select new
        //                    {
        //                        z = true,
        //                    }
        //                ).ToArray();
        var sizzeler = (from dr in dt.AsEnumerable()
                        where (dr.ItemArray.Where(itemCurrent => too_much_where(itemCurrent)).Count() == 0)
                        select new
                        {
                            z = true,
                        }
                        ).ToArray();
        s = 0;
        for (int j = 0; j < nColWidths.Length; j ++)
        {
            grfxMem.DrawLine(pen, new Point(s, 0), new Point(s, (int)mapMem.Height));
            s += (int)(nColWidths[j] + nMargin );
        }
        s = mapMem.Width-1;
        grfxMem.DrawRectangle(pen, new Rectangle(0, 0, mapMem.Width - 1, mapMem.Height - 1));
        s = 0;
        grfx.DrawImage(mapMem, (float)10.0, (float)10.0);
        grfx.Dispose();
        return strJPG;
    }

回答by Michele Ferracin

This is my version of it, with added the possibility to "highlight" some rows based on a generic rule (rowHighlightRule parameter).

这是我的版本,添加了基于通用规则(rowHighlightRule 参数)“突出显示”某些行的可能性。

  public static string ToHTML(this DataTable dt, Func<DataRow, bool> rowHiglithRule)
    {

        if (dt == null) throw new ArgumentNullException("dt");

        string tab = "\t";

        StringBuilder sb = new StringBuilder();
        sb.AppendLine(tab + tab + "<table>");

        // headers.
        sb.Append(tab + tab + tab + "<thead><tr>");

        foreach (DataColumn dc in dt.Columns)
        {
            sb.AppendFormat("<td>{0}</td>", dc.ColumnName);
        }

        sb.AppendLine("</thead></tr>");

        // data rows
        foreach (DataRow dr in dt.Rows)
        {
            if (rowHiglithRule != null)
            {

                if (rowHiglithRule(dr))
                {
                    sb.Append(tab + tab + tab + "<tr class=\"highlightedRow\">");
                }
                else
                {
                    sb.Append(tab + tab + tab + "<tr>");
                }
            }
            else
            {
                //Non ho alcuna regola, quindi caso normale.
                sb.Append(tab + tab + tab + "<tr>");
            }

            foreach (DataColumn dc in dt.Columns)
            {
                string cellValue = dr[dc] != null ? dr[dc].ToString() : "";
                sb.AppendFormat("<td>{0}</td>", cellValue);
            }

            sb.AppendLine("</tr>");
        }

        sb.AppendLine(tab + tab + "</table>");


        return sb.ToString();
    }