Datatable to html Table
我有问题,也许有人在这里不会介意帮助我。 我已经说了3个数据表,他们每个人都有以下几列:
大小,数量,金额,持续时间
数据表和名称的名称
LivingRoom ================ 1 1 1 1 2 2 2 2 BathRoom ================ 3 3 3 3 4 4 4 4 BedRoom ================= 5 5 5 5 6 6 6 6
现在我正在试图build立一个HTML发票,我可以通过所有的数据表循环,并输出以下的HTML输出,非常基本的:
<table> <tr> <td>Area</td> </tr> <tr> <td>Living Room</td> </tr> <tr> <td>Size</td> <td>Quantity</td> <td>Amount</td> <td>Duration</td> </tr> <tr> <td>1</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr> <td>2</td> <td>2</td> <td>2</td> <td>2</td> </tr> <tr> <td>Area</td> </tr> <tr> <td>Bathroom</td> </tr> <tr> <td>Size</td> <td>Quantity</td> <td>Amount</td> <td>Duration</td> </tr> <tr> <td>3</td> <td>3</td> <td>3</td> <td>3</td> </tr> <tr> <td>4</td> <td>4</td> <td>4</td> <td>4</td> </tr> <tr> <td>Area</td> </tr> <tr> <td>Bedroom</td> </tr> <tr> <td>Size</td> <td>Quantity</td> <td>Amount</td> <td>Duration</td> </tr> <tr> <td>5</td> <td>5</td> <td>5</td> <td>5</td> </tr> <tr> <td>6</td> <td>6</td> <td>6</td> <td>6</td> </tr> </table>
所以几乎所有的区域都会有数据表的名称,然后在每个区域循环下指定具体的数据表,并以该格式输出数据。 我无法弄清楚循环逻辑或如何做到这一点,在过去的几天里,我一直在为此而头痛。 也许我只是在错误的方式思考,但我真的可以使用一些帮助。
使用这个function:
public static string ConvertDataTableToHTML(DataTable dt) { string html = "<table>"; //add header row html += "<tr>"; for(int i=0;i<dt.Columns.Count;i++) html+="<td>"+dt.Columns[i].ColumnName+"</td>"; html += "</tr>"; //add rows for (int i = 0; i < dt.Rows.Count; i++) { html += "<tr>"; for (int j = 0; j< dt.Columns.Count; j++) html += "<td>" + dt.Rows[i][j].ToString() + "</td>"; html += "</tr>"; } html += "</table>"; return html; }
public static string toHTML_Table(DataTable dt) { if (dt.Rows.Count == 0) return ""; // enter code here StringBuilder builder = new StringBuilder(); builder.Append("<html>"); builder.Append("<head>"); builder.Append("<title>"); builder.Append("Page-"); builder.Append(Guid.NewGuid()); 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(); }
正如奥默尔·埃尔丹(Omer Eldan)所说,我已经看到了一些值得注意的解决scheme 但在这里。 ASP C#
using System.Data; using System.Web.UI.HtmlControls; public static Table DataTableToHTMLTable(DataTable dt, bool includeHeaders) { Table tbl = new Table(); TableRow tr = null; TableCell cell = null; int rows = dt.Rows.Count; int cols = dt.Columns.Count; if (includeHeaders) { TableHeaderRow htr = new TableHeaderRow(); TableHeaderCell hcell = null; for (int i = 0; i < cols; i++) { hcell = new TableHeaderCell(); hcell.Text = dt.Columns[i].ColumnName.ToString(); htr.Cells.Add(hcell); } tbl.Rows.Add(htr); } for (int j = 0; j < rows; j++) { tr = new TableRow(); for (int k = 0; k < cols; k++) { cell = new TableCell(); cell.Text = dt.Rows[j][k].ToString(); tr.Cells.Add(cell); } tbl.Rows.Add(tr); } return tbl; }
为何这个解决scheme 因为你可以很容易地把这个添加到一个面板,即:
panel.Controls.Add(DataTableToHTMLTable(dtExample,true));
第二个问题,为什么你只有一列数据表而不是数组? 你确定这些数据表是统一的,因为如果数据是锯齿状的,那么这是没有用的。 如果你真的需要join这些数据表,那么有很多Linq操作的例子,或者只是使用(注意,尽pipe有相同的名字列,这将在两个linq操作中冲突,如果不处理,这个解决scheme也会冲突):
public DataTable joinUniformTable(DataTable dt1, DataTable dt2) { int dt2ColsCount = dt2.Columns.Count; int dt1lRowsCount = dt1.Rows.Count; DataColumn column; for (int i = 0; i < dt2ColsCount; i++) { column = new DataColumn(); string colName = dt2.Columns[i].ColumnName; System.Type colType = dt2.Columns[i].DataType; column.ColumnName = colName; column.DataType = colType; dt1.Columns.Add(column); for (int j = 0; j < dt1lRowsCount; j++) { dt1.Rows[j][colName] = dt2.Rows[j][colName]; } } return dt1; }
你的解决scheme看起来像这样:
panel.Controls.Add(DataTableToHTMLTable(joinUniformTable(joinUniformTable(LivDT,BathDT),BedDT),true));
解释其余的,玩得开心。
第一个答案是正确的,但是如果你有大量的数据(在我的项目中,我有8.000行* 8列)是悲剧缓慢….有一个string变得这么大的C#是为什么解决scheme是forbiden
而是使用一个大的string,我使用了一个string数组,我在最后join,以返回html表的string。 而且,我用了一个linqexpression式( 从row.ItemArray中selecto.ToString())。ToArray() )来连接表的每个DataRow,而不是再次循环,以节省更多的时间可能。
这是我的示例代码:
private string MakeHtmlTable(DataTable data) { string[] table = new string[data.Rows.Count] ; long counter = 1; foreach (DataRow row in data.Rows) { table[counter-1] = "<tr><td>" + String.Join("</td><td>", (from o in row.ItemArray select o.ToString()).ToArray()) + "</td></tr>"; counter+=1; } return "</br><table>" + String.Join("", table) + "</table>"; }
从这个链接
using System; using System.Collections.Generic; using System.Data; using System.Globalization; using System.Text; using System.Xml; namespace ClientUtil { public class DataTableUtil { public static string DataTableToXmlString(DataTable dtData) { if (dtData == null || dtData.Columns.Count == 0) return (string) null; DataColumn[] primaryKey = dtData.PrimaryKey; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(“<TABLE>”); stringBuilder.Append(“<TR>”); foreach (DataColumn dataColumn in (InternalDataCollectionBase) dtData.Columns) { if (DataTableUtil.IsPrimaryKey(dataColumn.ColumnName, primaryKey)) stringBuilder.Append(“<TH IsPK='true' ColType='”).Append(Convert.ToString(dataColumn.DataType == typeof (object) ? (object) typeof (string) : (object) dataColumn.DataType)).Append(“'>”).Append(dataColumn.ColumnName.Replace(“&”, “”)).Append(“</TH>”); else stringBuilder.Append(“<TH IsPK='false' ColType='”).Append(Convert.ToString(dataColumn.DataType == typeof (object) ? (object) typeof (string) : (object) dataColumn.DataType)).Append(“'>”).Append(dataColumn.ColumnName.Replace(“&”, “”)).Append(“</TH>”); } stringBuilder.Append(“</TR>”); int num1 = 0; foreach (DataRow dataRow in (InternalDataCollectionBase) dtData.Rows) { stringBuilder.Append(“<TR>”); int num2 = 0; foreach (DataColumn dataColumn in (InternalDataCollectionBase) dtData.Columns) { string str = Convert.IsDBNull(dataRow[dataColumn.ColumnName]) ? (string) null : Convert.ToString(dataRow[dataColumn.ColumnName]).Replace(“<“, “<”).Replace(“>”, “>”).Replace(“\””, “"”).Replace(“'”, “'”).Replace(“&”, “&”); if (!string.IsNullOrEmpty(str)) stringBuilder.Append(“<TD>”).Append(str).Append(“</TD>”); else stringBuilder.Append(“<TD>”).Append(“</TD>”); ++num2; } stringBuilder.Append(“</TR>”); ++num1; } stringBuilder.Append(“</TABLE>”); return ((object) stringBuilder).ToString(); } protected static bool IsPrimaryKey(string ColumnName, DataColumn[] PKs) { if (PKs == null || string.IsNullOrEmpty(ColumnName)) return false; foreach (DataColumn dataColumn in PKs) { if (dataColumn.ColumnName.ToLower().Trim() == ColumnName.ToLower().Trim()) return true; } return false; } public static DataTable XmlStringToDataTable(string XmlData) { DataTable dataTable = (DataTable) null; IList<DataColumn> list = (IList<DataColumn>) new List<DataColumn>(); if (string.IsNullOrEmpty(XmlData)) return (DataTable) null; XmlDocument xmlDocument1 = new XmlDocument(); xmlDocument1.PreserveWhitespace = true; XmlDocument xmlDocument2 = xmlDocument1; xmlDocument2.LoadXml(XmlData); XmlNode xmlNode1 = xmlDocument2.SelectSingleNode(“/TABLE”); if (xmlNode1 != null) { dataTable = new DataTable(); int num = 0; foreach (XmlNode xmlNode2 in xmlNode1.SelectNodes(“TR”)) { if (num == 0) { foreach (XmlNode xmlNode3 in xmlNode2.SelectNodes(“TH”)) { bool result = false; string str = xmlNode3.Attributes[“IsPK”].Value; if (!string.IsNullOrEmpty(str)) { if (!bool.TryParse(str, out result)) result = false; } else result = false; Type type = Type.GetType(xmlNode3.Attributes[“ColType”].Value); DataColumn column = new DataColumn(xmlNode3.InnerText, type); if (result) list.Add(column); if (!dataTable.Columns.Contains(column.ColumnName)) dataTable.Columns.Add(column); } if (list.Count > 0) { DataColumn[] dataColumnArray = new DataColumn[list.Count]; for (int index = 0; index < list.Count; ++index) dataColumnArray[index] = list[index]; dataTable.PrimaryKey = dataColumnArray; } } else { DataRow row = dataTable.NewRow(); int index = 0; foreach (XmlNode xmlNode3 in xmlNode2.SelectNodes(“TD”)) { Type dataType = dataTable.Columns[index].DataType; string s = xmlNode3.InnerText; if (!string.IsNullOrEmpty(s)) { try { s = s.Replace(“<”, “<“); s = s.Replace(“>”, “>”); s = s.Replace(“"”, “\””); s = s.Replace(“'”, “'”); s = s.Replace(“&”, “&”); row[index] = Convert.ChangeType((object) s, dataType); } catch { if (dataType == typeof (DateTime)) row[index] = (object) DateTime.ParseExact(s, “yyyyMMdd”, (IFormatProvider) CultureInfo.InvariantCulture); } } else row[index] = Convert.DBNull; ++index; } dataTable.Rows.Add(row); } ++num; } } return dataTable; } } }
如果你使用Web窗体,那么Grid View可以很好地工作
代码看起来有点像这样。
aspx页面。
<asp:GridView ID="GridView1" runat="server" DataKeyNames="Name,Size,Quantity,Amount,Duration"></asp:GridView>
您可以手动input数据,也可以使用代码端的源代码方法
public class Room { public string Name public double Size {get; set;} public int Quantity {get; set;} public double Amount {get; set;} public int Duration {get; set;} } protected void Page_Load(object sender, EventArgs e) { if(!IsPostBack)//this is so you can keep any data you want for the list { List<Room> rooms=new List<Room>(); //then use the rooms.Add() to add the rooms you need. GridView1.DataSource=rooms GridView1.Databind() } }
就我个人而言,我喜欢MVC4,客户端代码比Web Forms要轻得多。 它与上面使用类的例子类似,但是使用视图和Controller。
视图看起来像这样。
@model YourProject.Model.IEnumerable<Room> <table> <th> <td>@Html.LabelFor(model => model.Name)</td> <td>@Html.LabelFor(model => model.Size)</td> <td>@Html.LabelFor(model => model.Quantity)</td> <td>@Html.LabelFor(model => model.Amount)</td> <td>@Html.LabelFor(model => model.Duration)</td> </th> foreach(item in model) { <tr> <td>@model.Name</td> <td>@model.Size</td> <td>@model.Quantity</td> <td>@model.Amount</td> <td>@model.Duration</td> </tr> } </table>
控制器可能看起来像这样。
public ActionResult Index() { List<Room> rooms=new List<Room>(); //again add the items you need return View(rooms); }
希望这可以帮助 :)
根据我的理解,你需要在一个HTML表格中使用asp.net与c#显示3个表格数据。
我认为你最好只用3个DataTable对象创build一个数据集。
在页面加载时将数据集直接绑定到GriView。