2012-03-20 16 views
8

tengo que ser capaz de pasar datos HTML en Outlook como esto:Creación de HTML de una C utilizando DataTable #

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

inicialmente pensé que podía pasar a texto sin formato a la misma y utilizar PadLeft así:

somestring.PadLeft(100); 

pero no alineó todo correctamente porque a pesar de que ||||| y y MMMMM tienen solo 5 caracteres de longitud, físicamente en la pantalla ocupan más espacio.

mi solución es convertir datos que están en mi tabla de datos en una tabla HTML y luego pasarlos a Outlook.

  1. ¿cómo convierto una tabla de datos en una tabla html?
  2. ¿hay alguna solución mejor a mi problema?

muchas gracias por su ayuda.

+2

Itere las colecciones de Filas y Columnas del DataTable y construye una cadena html a partir de los valores de celda individuales. – mservidio

+1

Toman diferentes cantidades de espacio porque la fuente que estás utilizando no está monoespaciada. Tal vez una fuente monoespaciada sea una solución. –

+0

@DJQuimby muchas gracias !! ¿Qué es un ejemplo de una fuente monoespacial? –

Respuesta

16

Desplácese sobre su DataTable y construya la cadena 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>"); 
+0

muchas gracias! Lo siento, mi HTML no es genial. ¿Cómo voy a envolver las etiquetas allí? –

+0

He actualizado el fragmento de código para mostrar cómo envolverlo en las etiquetas. Consulte esta url sobre el uso de tablas html: http://www.w3schools.com/html/html_tables.asp – mservidio

+0

¡¡¡GRACIAS YO !!!!!!!! FUNCIONA INCREÍBLEMENTE BIEN –

3

El código puede ser bastante largo para escribir aquí, estoy de acuerdo con @mservidio. Siga este enlace para ver un ejemplo de lo que tiene que hacer: this link

+0

Nota al margen: verifique sus datos, si no son números, pueden contienen caracteres no válidos para HTML, por lo que un ToString sin formato() no funciona ("<", por ejemplo). –

2

¿Cómo se convierte una tabla de datos en una tabla HTML?

La única manera es escribir el código que recorre cada fila y crea la cadena HTML de la manera que lo necesita.

¿Existe alguna solución a mi problema?

Se puede usar un fuente de espacio sencillo (como Courier) wihch le permitirá alinear todo correctamente con sólo dar salida al número correcto de espacios pero aún había necesidad de enviar el correo electrónico en formato HTML establecer la fuente adecuada en el documento.

+0

¡gracias! ¿Puedes ayudar con este http://stackoverflow.com/questions/9793160/getting-the-innerhtml-of-an-htmltable-c-sharp –

1

Hay varias formas de generar el HTML.

Si se trata de un formato relativamente fácil (no hay mucho formato, estilos, etc.) Definitivamente iré con la sugerencia de @ mservidio.

Si la salida es más compleja y tiene experiencia con ASP.NET, puede seguir la ruta de un UserControl que permite más flexibilidad y administración de la salida. A continuación, puede procesar el resultado del control en HTML de esta manera:

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

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

gracias Shai! Es simple. ¿Puedes indicarme algún código que crees que podría funcionar? –

+0

shai, puedes ayudar aquí también http://stackoverflow.com/questions/9793160/getting-the-innerhtml-of-an-htmltable-c-sharp –

+0

Si es simple, yo iría con la respuesta presentada por @mservidio –

6

Solo quiero compartir lo que hice. Espero que esto ayude.

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()); 
} 
0
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(); 
     } 
0
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>"; 

    } 
-1
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; 
    } 
+0

No dijo JPG sino HTML. –

0

Ésta es mi versión de la misma, con el añadido la posibilidad de "resalte" algunas filas en base a una regla genérica (parámetro 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(); 
    } 
Cuestiones relacionadas