ASP.NET:将GridView导出到Excel的正确方法,包括动态添加的行

时间:2016-08-05 12:03:11

标签: c# asp.net excel gridview export

我一直在尝试实现一种将GridViews导出到Excel工作表的简单方法。但是,我现在已经坚持了很长一段时间了:

我的GridViewAutoGenerateColumns设置为true,因为数据源是动态的,并且不是真正可预测的(随着时间的推移更改列数)。它自动创建的HeaderRow不适合我,因此我还将ShowHeader设置为false并在OnRowCreated事件中创建了我自己的事件,如下所示:

if (e.Row.RowType == DataControlRowType.Header) {

        gv.Controls[0].Controls.AddAt(0, GetHeader());
        gv.Controls[0].Controls.AddAt(1, GetSubHeader());


}

其中GetHeader()GetSubHeader()都返回GridViewRow(标题中有两行使用不同的colspans,rowspans和stuff)。这一切在网站上运行得很好,但是,当我尝试使用OpenXML导出GridView时,这样:

    ExcelPackage excel = new ExcelPackage();
    var workSheet = excel.Workbook.Worksheets.Add("List 1");
    var totalCols = gv.Rows[0].Cells.Count;
    var totalRows = gv.Rows.Count;
    var headerRow = gv.HeaderRow;

    for (int i = 0; i < totalCols; i++) {

        workSheet.Cells[1,i+1].Value = headerRow.Cells[i].Text;

    }

    for (int i = 0; i < totalCols; i++) {

        for (int j = 0; j < totalRows; j++) {

            workSheet.Cells[j+2,i+1].Value = gv.Rows[j].Cells[i].Text;

        }

    }

    return excel;

我得到的是一张隐藏着原始HeaderRow的表 - 我认为我应该明显跳过第一个循环 - 然后是实际数据的行。没有跟踪我在OnRowCreated中添加的两行。

有人可以解释为什么会发生这种情况以及如何解决这个问题?理想情况下,该方法应始终导出整个GridView,因为它显示在网站上。

注意:使用HtmlTextWriter和GridView.RenderControl()的另一种方式可能不是一个选项,因为我甚至无法在下载后在Excel中打开文件(OpenOffice虽然做得很好)然后我在某处读到了这些表格实际上并不适用于数据处理,在这种情况下是至关重要的。

编辑:我在HeaderRow而不是OnRowDataBound中添加了两个OnRowCreated后,循环会占用它们,但是进入工作表的所有内容都是空白字段,它似乎也是它们不会被gv.Rows.Count考虑在内,因为循环永远不会到达我表格中的最后两行。

我尝试过调试,而且gv.Rows[j].Cells[i].Text;返回的所有内容都是"",即使单元格设置了Text属性,并且表格在网站上显示为OK。

我发现这种行为非常混乱,我想我错过了一些大事。有谁可以告诉我为什么会这样?

1 个答案:

答案 0 :(得分:1)

无论是自动生成还是其他方式都无关紧要。诀窍是将所有东西视为对象和对象的子对象。然后使用对象的属性(以及Excel),您可以在gridview中对数据进行操作。

参见下面的示例代码

protected void ExportToExcel(object sender, EventArgs e)

{

    Response.Clear();

    Response.Buffer = true;

    Response.AddHeader("content-disposition", "attachment;filename=GridViewExport.xls");

    Response.Charset = "";

    Response.ContentType = "application/vnd.ms-excel";

    using (StringWriter sw = new StringWriter())

    {

        HtmlTextWriter hw = new HtmlTextWriter(sw);



        //To Export all pages

        GridView1.AllowPaging = false;

        this.BindGrid();



        GridView1.HeaderRow.BackColor = Color.White;

        foreach (TableCell cell in GridView1.HeaderRow.Cells)

        {

            cell.BackColor = GridView1.HeaderStyle.BackColor;

        }

        foreach (GridViewRow row in GridView1.Rows)

        {

            row.BackColor = Color.White;

            foreach (TableCell cell in row.Cells)

            {

                if (row.RowIndex % 2 == 0)

                {

                    cell.BackColor = GridView1.AlternatingRowStyle.BackColor;

                }

                else

                {

                    cell.BackColor = GridView1.RowStyle.BackColor;

                }

                cell.CssClass = "textmode";

            }

        }



        GridView1.RenderControl(hw);



        //style to format numbers to string

        string style = @"<style> .textmode { } </style>";

        Response.Write(style);

        Response.Output.Write(sw.ToString());

        Response.Flush();

        Response.End();

    }

}

这只是其中一种方法。

还有许多其他样本。只需谷歌Gridview到Excel。

希望这有帮助。