Reputation: 60741
I need to be able to pass HTML data into Outlook like this:
MailMessage message = new MailMessage();
message.Body = myBody;
Initially, I thought I could pass plain text to it and use PadLeft
like this:
somestring.PadLeft(100);
but it did not align everything properly because even though |||||
and MMMMM
are both only 5 characters in length, they physically on the screen take up more space.
My solution is to convert data that is in my datatable into an HTML table and then pass it into Outlook.
Upvotes: 8
Views: 43694
Reputation: 67090
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
Upvotes: 3
Reputation: 407
This is my version of it, with added the possibility to "highlight" some rows based on a generic rule (rowHighlightRule parameter).
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();
}
Upvotes: 0
Reputation: 305
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;
}
Upvotes: -1
Reputation: 305
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>";
}
Upvotes: 3
Reputation: 1961
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();
}
Upvotes: 0
Reputation: 171
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());
}
Upvotes: 6
Reputation: 13057
Loop over your DataTable, and build up the html string. 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>");
Upvotes: 17
Reputation: 6249
There are a number of ways to output the HTML.
If this is a relatively easy format (not much formatting, styles etc.) I would definitely go with @mservidio's suggestion.
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:
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
HtmlTextWriter hw = new HtmlTextWriter(tw);
ctrl.RenderControl(hw);
return sb.ToString();
Upvotes: 1
Reputation: 63966
how do i convert a datatable into an html table?
The only way is to write code that goes through every row and builds the HTML string the way you need it.
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.
Upvotes: 3