我一直在尝试实现一种将GridViews导出到Excel工作表的简单方法。但是,我现在已经坚持了很长一段时间了:
我的GridView
将AutoGenerateColumns
设置为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。
我发现这种行为非常混乱,我想我错过了一些大事。有谁可以告诉我为什么会这样?
答案 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。
希望这有帮助。