如何在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(每行)。但我认为上面更好。

这个,当我们点击按钮时,它下载,点击打开,我们得到这个: