如何在excel中下载gridview in ASP.NET C#,即如何在datatable中使用group by
how to download gridview in excel in ASP.NET C #, ie How to use group by in datatable
如果我有一个具有以下布局的数据表:
第 1 列
第 2 列
第一个
1号
第一个
2号
第二
1号
第二
2号
第二
3号
我需要在 Excel 的 gridview 中下载数据table 以便像 table 这里:
列
第一个
1号
2号
第二
1号
2号
3号
我看到LINQ用了很多,但我是新手,所以我不太擅长LINQ。
你能帮忙吗?
代码:
private DataTable QR (int ID)
{
string conn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString.ToString();
SqlConnection sqlConnection = new SqlConnection(conn);
string queryQ = @"some query here to take data from database";
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(queryQ, sqlConnection);
cmd.Parameters.AddWithValue("@ID", ID);
SqlDataReader dr = cmd.ExecuteReader();
dataTableQ = new DataTable();
dataTableQ.Load(dr);
// after that I'm little confused
DataTable dtq = new DataTable();
var l = new List<string>();
var gg = dtq.Rows.Cast<DataRow>().GroupBy(r => (string)r["QT"]);
foreach (var g in gg)
{
l.Add(g.Key);
foreach (var r in g)
l.Add((string)r["SubQT"]);
}
HttpContext.Current.Session["_dataTableForExportInExcel1"] = dtq;
return dtq;
}
谢谢
呃,请做好准备,因为这种“按位置关联”的想法会把你的数据搞得一团糟
我也不会为此使用 LINQ
var l = new List<string>();
string prev = null;
foreach(DataRow r in dt.Rows){
var s = (string)r["Column1"];
var t = (string)r["Column2"];
if(s != prev){
l.Add(s);
prev = s;
}
l.Add(t);
}
渴望使用 LINQ 的东西?
var l = new List<string>();
var gg = dt.Rows.Cast<DataRow>().GroupBy(r => (string)r["Column1"]);
foreach(var g in gg){
l.Add(g.Key);
foreach(var r in g)
l.Add((string)r["Column2"]);
}
因此您希望将输出作为数据表 - 添加到数据表而不是列表:
var l = new DataTable();
l.Columns.Add("X");
string prev = null;
foreach(DataRow r in dt.Rows){
var s = (string)r["Column1"];
var t = (string)r["Column2"];
if(s != prev){
l.Rows.Add(s);
prev = s;
}
l.Rows.Add(t);
}
好吧,您可以将网格处理成 csv,或者实际上,我建议您在 table 驱动器上执行此操作,填充 gridview。
假设我们有这个:
<asp:GridView ID="GridView1" runat="server" CssClass="table table-hover">
</asp:GridView>
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="As Csv" Width="126px" />
<br />
<br />
好的,我们填充此网格视图的代码如下:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = LoadGrid();
GridView1.DataBind();
}
}
DataTable LoadGrid()
{
DataTable dt = new DataTable();
using (SqlCommand cmdSQL =
new SqlCommand("SELECT City, HotelName from tblHotels ORDER BY City, HotelName",
new SqlConnection(Properties.Settings.Default.TEST3)))
{
cmdSQL.Connection.Open();
dt.Load(cmdSQL.ExecuteReader());
}
return dt;
}
好的,此时输出是这样的:
因此,我们要将其展平为一列,按城市分组。
(真的和你的例子一样的问题)。
所以按钮代码是这样的:
protected void Button1_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt = LoadGrid();
DataTable OutTable = new DataTable();
OutTable.Columns.Add("C1", typeof(string));
string strGroup = "";
foreach (DataRow dRow in dt.Rows)
{
if (dRow[0].ToString() != strGroup)
{
strGroup = dRow[0].ToString();
OutTable.Rows.Add(strGroup);
}
OutTable.Rows.Add(dRow[1].ToString());
}
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment;filename=mydata.csv");
Response.Write(toCsvT(OutTable));
Response.End();
}
而 table 到 csv 例程是这样的:
public string toCsvT(DataTable dt)
{
string strCSV = "";
string q = "\"";
// csv heading
foreach (DataColumn hCol in dt.Columns)
{
if (strCSV != "")
strCSV += ",";
strCSV += q + hCol.ColumnName + q;
}
strCSV += System.Environment.NewLine;
// csv data
foreach (DataRow dRow in dt.Rows)
{
string strOneRow = "";
for (var i = 0; i <= dRow.Table.Columns.Count - 1; i++)
{
if (strOneRow != "")
strOneRow += ",";
strOneRow += q + dRow[i] + q;
}
strCSV += strOneRow + System.Environment.NewLine;
}
return strCSV;
}
因此,我们可能已经处理了 DataGrid 上的每一行,但最好花时间创建一个 table 到 csv 例程 - 我们可以在许多其他地方使用该例程。
因此,我强烈建议将 table(数据源)重新处理为所需的新格式。
但是,您可以使用非常接近我用于数据的相同代码table,并使用数据网格行作为数据源(您可以使用 .cells[0] 和 .cells1 来自 DataGridItem(每行)。但我认为上面更好。
这个,当我们点击按钮时,它下载,点击打开,我们得到这个:
如果我有一个具有以下布局的数据表:
第 1 列 | 第 2 列 |
---|---|
第一个 | 1号 |
第一个 | 2号 |
第二 | 1号 |
第二 | 2号 |
第二 | 3号 |
我需要在 Excel 的 gridview 中下载数据table 以便像 table 这里:
列 |
---|
第一个 |
1号 |
2号 |
第二 |
1号 |
2号 |
3号 |
我看到LINQ用了很多,但我是新手,所以我不太擅长LINQ。
你能帮忙吗?
代码:
private DataTable QR (int ID)
{
string conn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString.ToString();
SqlConnection sqlConnection = new SqlConnection(conn);
string queryQ = @"some query here to take data from database";
sqlConnection.Open();
SqlCommand cmd = new SqlCommand(queryQ, sqlConnection);
cmd.Parameters.AddWithValue("@ID", ID);
SqlDataReader dr = cmd.ExecuteReader();
dataTableQ = new DataTable();
dataTableQ.Load(dr);
// after that I'm little confused
DataTable dtq = new DataTable();
var l = new List<string>();
var gg = dtq.Rows.Cast<DataRow>().GroupBy(r => (string)r["QT"]);
foreach (var g in gg)
{
l.Add(g.Key);
foreach (var r in g)
l.Add((string)r["SubQT"]);
}
HttpContext.Current.Session["_dataTableForExportInExcel1"] = dtq;
return dtq;
}
谢谢
呃,请做好准备,因为这种“按位置关联”的想法会把你的数据搞得一团糟
我也不会为此使用 LINQ
var l = new List<string>();
string prev = null;
foreach(DataRow r in dt.Rows){
var s = (string)r["Column1"];
var t = (string)r["Column2"];
if(s != prev){
l.Add(s);
prev = s;
}
l.Add(t);
}
渴望使用 LINQ 的东西?
var l = new List<string>();
var gg = dt.Rows.Cast<DataRow>().GroupBy(r => (string)r["Column1"]);
foreach(var g in gg){
l.Add(g.Key);
foreach(var r in g)
l.Add((string)r["Column2"]);
}
因此您希望将输出作为数据表 - 添加到数据表而不是列表:
var l = new DataTable();
l.Columns.Add("X");
string prev = null;
foreach(DataRow r in dt.Rows){
var s = (string)r["Column1"];
var t = (string)r["Column2"];
if(s != prev){
l.Rows.Add(s);
prev = s;
}
l.Rows.Add(t);
}
好吧,您可以将网格处理成 csv,或者实际上,我建议您在 table 驱动器上执行此操作,填充 gridview。
假设我们有这个:
<asp:GridView ID="GridView1" runat="server" CssClass="table table-hover">
</asp:GridView>
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="As Csv" Width="126px" />
<br />
<br />
好的,我们填充此网格视图的代码如下:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GridView1.DataSource = LoadGrid();
GridView1.DataBind();
}
}
DataTable LoadGrid()
{
DataTable dt = new DataTable();
using (SqlCommand cmdSQL =
new SqlCommand("SELECT City, HotelName from tblHotels ORDER BY City, HotelName",
new SqlConnection(Properties.Settings.Default.TEST3)))
{
cmdSQL.Connection.Open();
dt.Load(cmdSQL.ExecuteReader());
}
return dt;
}
好的,此时输出是这样的:
因此,我们要将其展平为一列,按城市分组。 (真的和你的例子一样的问题)。
所以按钮代码是这样的:
protected void Button1_Click(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt = LoadGrid();
DataTable OutTable = new DataTable();
OutTable.Columns.Add("C1", typeof(string));
string strGroup = "";
foreach (DataRow dRow in dt.Rows)
{
if (dRow[0].ToString() != strGroup)
{
strGroup = dRow[0].ToString();
OutTable.Rows.Add(strGroup);
}
OutTable.Rows.Add(dRow[1].ToString());
}
Response.ClearContent();
Response.AddHeader("content-disposition", "attachment;filename=mydata.csv");
Response.Write(toCsvT(OutTable));
Response.End();
}
而 table 到 csv 例程是这样的:
public string toCsvT(DataTable dt)
{
string strCSV = "";
string q = "\"";
// csv heading
foreach (DataColumn hCol in dt.Columns)
{
if (strCSV != "")
strCSV += ",";
strCSV += q + hCol.ColumnName + q;
}
strCSV += System.Environment.NewLine;
// csv data
foreach (DataRow dRow in dt.Rows)
{
string strOneRow = "";
for (var i = 0; i <= dRow.Table.Columns.Count - 1; i++)
{
if (strOneRow != "")
strOneRow += ",";
strOneRow += q + dRow[i] + q;
}
strCSV += strOneRow + System.Environment.NewLine;
}
return strCSV;
}
因此,我们可能已经处理了 DataGrid 上的每一行,但最好花时间创建一个 table 到 csv 例程 - 我们可以在许多其他地方使用该例程。
因此,我强烈建议将 table(数据源)重新处理为所需的新格式。
但是,您可以使用非常接近我用于数据的相同代码table,并使用数据网格行作为数据源(您可以使用 .cells[0] 和 .cells1 来自 DataGridItem(每行)。但我认为上面更好。
这个,当我们点击按钮时,它下载,点击打开,我们得到这个: