Создание HTML из DataTable с помощью C#
Мне нужно иметь возможность передавать HTML-данные в Outlook следующим образом:
MailMessage message = new MailMessage();
message.Body = myBody;
Первоначально я думал, что смогу передать ему простой текст и использовать PadLeft Вот так:
somestring.PadLeft(100);
Но он не выровнял все правильно, потому что, хотя
||||| и MMMMM имеют только 5 символов в длину, они физически на экране занимают больше места.Мое решение состоит в том, чтобы преобразовать данные, которые находятся в моей datatable в таблицу HTML, а затем передать их в Outlook.
- как мне преобразовать a datatable в таблицу html?
Есть ли лучшее решение моей проблемы?
Большое Спасибо за вашу помощь.
9 ответов:
Замкните цикл над вашей 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>");
Я просто хочу поделиться тем, что я сделал. Надеюсь, это поможет.
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()); }
Единственный способ-написать код, который проходит через каждую строку и строит HTML-строку так, как вам нужно.Как преобразовать datatable в таблицу html?
Есть ли лучшее решение моей проблемы?
Вы можете использовать моноширинный шрифт (например,
Courier), который позволит вам выровнять все правильно, просто выведя нужное количество пробелов, но вам все равно нужно будет отправить письмо в формате HTML, установив правильный шрифт на экране. документ.
Код может быть довольно длинным, чтобы написать здесь, я согласен с @mservidio. Перейдите по этой ссылке, чтобы увидеть пример того, что вам нужно сделать: Эта ссылка
Существует несколько способов вывода HTML.
Если это относительно простой формат (не много форматирования, стилей и т. д.) Я бы определенно согласился с предложением @mservidio.
Если выходные данные более сложны и у вас есть опыт работы с ASP.NET вы можете пойти по пути UserControl, который обеспечивает большую гибкость и управление выводом. Затем можно отобразить выходные данные элемента управления в HTML следующим образом:
StringBuilder sb = new StringBuilder(); StringWriter tw = new StringWriter(sb); HtmlTextWriter hw = new HtmlTextWriter(tw); ctrl.RenderControl(hw); return sb.ToString();
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>"; }
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(); }
Это моя версия, с добавленной возможностью "выделять" некоторые строки на основе общего правила (параметр 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(); }
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; }
Comments