none
将GridView中的数据直接添加到Excel中,转换为模板后出现的问题 RRS feed

  • 问题

  •     下列代码是将GridView中的数据直接添加到Excel中的代码,在一般情况下可以运行,但是我把GridView中的数据除了第一列PRID外的其他所有列都转换为模板,再点击“导入到Excel”键,Excel中就只有PRID的值了,如图1.

        我的模板用了Label和TextBox,不知道针对这种稍微复杂点的情况该如何修改下列代码呢?

    ----------------------------代码1(直接把GridView的数据写到Excel中)-----------

    protected void Button_SQLToExcel_Click(object sender, EventArgs e)
        {
            if (GridView_Search.Rows.Count == 0)
                return;
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Application.Workbooks.Add(true);
            excel.Visible = true;
            for (int i = 0; i < GridView_Search.Columns.Count; i++)
            {
                excel.Cells[1, i + 1] = GridView_Search.Columns[i].HeaderText;
            }
            for (int i = 0; i < GridView_Search.Rows.Count; i++)
            {
                for (int j = 0; j < GridView_Search.Columns.Count; j++)
                {
                    excel.Cells[i + 2, j + 1] = GridView_Search.Rows[i].Cells[j].Text;
                }
            }
        }

    ----------------------图1---------------------------------


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!

    2012年7月19日 4:01

全部回复

  •   private void DisableControls(Control gv)
            {
                LinkButton lb = new LinkButton();
                Literal l = new Literal();
                string name = String.Empty;
                for (int i = 0; i < gv.Controls.Count; i++)
                {
                    if (gv.Controls[i].GetType() == typeof(LinkButton))
                    {
                        l.Text = (gv.Controls[i] as LinkButton).Text;
                        gv.Controls.Remove(gv.Controls[i]);
                        gv.Controls.AddAt(i, l);
                    }
                    else if (gv.Controls[i].GetType() == typeof(DropDownList))
                    {
                        l.Text = (gv.Controls[i] as DropDownList).SelectedItem.Text;
                        gv.Controls.Remove(gv.Controls[i]);
                        gv.Controls.AddAt(i, l);
                    }
                    else if (gv.Controls[i].GetType() == typeof(TextBox))
                    {
                        l.Text = (gv.Controls[i] as TextBox).Text;
                        gv.Controls.Remove(gv.Controls[i]);
                        gv.Controls.AddAt(i, l);
                    }
                    else if (gv.Controls[i].GetType() == typeof(CheckBox))
                    {
                        if ((gv.Controls[i] as CheckBox).Checked) l.Text = "√"; else l.Text = "×";
                        gv.Controls.Remove(gv.Controls[i]);
                        gv.Controls.AddAt(i, l);
                    }
                    if (gv.Controls[i].HasControls())
                    {
                        DisableControls(gv.Controls[i]);
                    }
                }
            }
    可以像我上面那样写的替换那些控件!
    2012年7月19日 10:31
    版主
  • 谢谢您的解答!

        这个函数是根据各个单元格不同的控件,最后通通用 gv.Controls.AddAt(i, l); 统一格式,是吧?

    问题1:最后一个判断怎么是if而不是else或者else if呢?

    问题2:这个函数我就如下面使用 不行啊!还是只有第一列的数据,我用错了么?

    //应该是这样用的吧?怎么还是和以前一样,Excel只有第一列的值呢?
    
     protected void Button_SQLToExcel_Click(object sender, EventArgs e)
        {
            DisableControls(GridView_Search);
            if (GridView_Search.Rows.Count == 0)
                return;
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Application.Workbooks.Add(true);
            excel.Visible = true;
            for (int i = 0; i < GridView_Search.Columns.Count; i++)
            {
               excel.Cells[1, i + 1] = GridView_Search.Columns[i].HeaderText;
            }
            for (int i = 0; i < GridView_Search.Rows.Count; i++)
            {
                
                for (int j = 0; j < GridView_Search.Columns.Count; j++)
                {
                    excel.Cells[i + 2, j + 1] = GridView_Search.Rows[i].Cells[j].Text;
                }
            }
        }
        private void DisableControls(Control gv)
        {
            LinkButton lb = new LinkButton();
            Literal l = new Literal();
            string name = String.Empty;
            for (int i = 0; i < gv.Controls.Count; i++)
            {
                if (gv.Controls[i].GetType() == typeof(LinkButton))
                {
                    l.Text = (gv.Controls[i] as LinkButton).Text;
                    gv.Controls.Remove(gv.Controls[i]);
                    gv.Controls.AddAt(i, l);
                }
                else if (gv.Controls[i].GetType() == typeof(DropDownList))
                {
                    l.Text = (gv.Controls[i] as DropDownList).SelectedItem.Text;
                    gv.Controls.Remove(gv.Controls[i]);
                    gv.Controls.AddAt(i, l);
                }
                else if (gv.Controls[i].GetType() == typeof(TextBox))
                {
                    l.Text = (gv.Controls[i] as TextBox).Text;
                    gv.Controls.Remove(gv.Controls[i]);
                    gv.Controls.AddAt(i, l);
                }
                else if (gv.Controls[i].GetType() == typeof(CheckBox))
                {
                    if ((gv.Controls[i] as CheckBox).Checked) l.Text = "√"; else l.Text = "×";
                    gv.Controls.Remove(gv.Controls[i]);
                    gv.Controls.AddAt(i, l);
                }
                if (gv.Controls[i].HasControls())
                {
                    DisableControls(gv.Controls[i]);
                }
            }


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!




    2012年7月19日 13:59
  • 答问题1: 这个函数是递归调用的 所以是if  是判断这个单元格的控件下面还有没有包含其他控件 如果有 在递归

    答 问题2:这个函数是把控件替换成值然后输出的,一般来说是可以的 你可以单步调试跟踪一下!

    2012年7月21日 7:11
    版主
  •     我尝试了您的代码!还是只能输出第一列的数据!我在其他电脑上联网打开该网页,点击“导出到Excel表”的Button键!发现其他电脑上GridView会变成普通的样子(也就是不显示TextBox等等控件的样子),但导出来的Excel表还是只有第一列。因此,我猜测是我的导出代码没有解读您给出的那个函数,还是直接取的GridView的数据吧?

    ---------------------我的代码------------------------

    protected void Button_SQLToExcel_Click(object sender, EventArgs e)
        {
            DisableControls(GridView_Search);
            if (GridView_Search.Rows.Count == 0)
                return;
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Application.Workbooks.Add(true);
            excel.Visible = true;
            for (int i = 0; i < GridView_Search.Columns.Count; i++)
            {
               excel.Cells[1, i + 1] = GridView_Search.Columns[i].HeaderText;
            }
            for (int i = 0; i < GridView_Search.Rows.Count; i++)
            {
                
                for (int j = 0; j < GridView_Search.Columns.Count; j++)
                {
                    excel.Cells[i + 2, j + 1] = GridView_Search.Rows[i].Cells[j].Text;
                }
            }
        }



    2012年7月25日 5:27
  • 导出的代码 你可以改写成下面的形式  你按我这样试试

       
    for (int j = 0; j < GridView_Search.Columns.Count; j++)
                {
    
    if (GridView_Search.Controls[j].GetType() == typeof(TextBox))
                {
     var  str = (GridView_Search.Controls[j] as TextBox).Text;
    
                    excel.Cells[i + 2, j + 1] = str  ;
    
    }
    
    else
    
    {
    
         excel.Cells[i + 2, j + 1]=GridView_Search.Rows[i].Cells[j].Text;
    
    }
                }
    
    
    2012年7月25日 9:47
    版主
  • 根据您的提示,我修改了代码。为了测试方便,我把所有的模板都改成了TextBox,但出现了如图所示的错误!我怎么看都没有错误啊 !

    ---------------------------导出到Excel的代码--------------------------

    protected void Button_SQLToExcel_Click(object sender, EventArgs e)
        {
            //DisableControls(GridView_Search);
            if (GridView_Search.Rows.Count == 0)
                return;
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Application.Workbooks.Add(true);
            excel.Visible = true;
            for (int i = 0; i < GridView_Search.Columns.Count; i++)
            {
                excel.Cells[1, i + 1] = GridView_Search.Columns[i].HeaderText;
            }
            
            for (int i = 0; i < GridView_Search.Rows.Count; i++)
            {
                for (int j = 0; j < GridView_Search.Columns.Count; j++)
                {
    
                    if (GridView_Search.Controls[j].GetType() == typeof(TextBox))
                    {
                        var str = (GridView_Search.Controls[j] as TextBox).Text;
                        excel.Cells[i + 2, j + 1] = str;
                    }
    
                    else
                    {
                        excel.Cells[i + 2, j + 1] = GridView_Search.Rows[i].Cells[j].Text;
                    }
                }
            }
    
        }

    ---------------------------图----------------------------

    ------------------------很简单的前台代码----------------------

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <style type="text/css">
            .style1
            {
                width: 100%;
            }
        </style>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        
            <table cellpadding="0" cellspacing="0" class="style1">
                <tr>
                    <td>
                        <asp:Button ID="Button_SQLToExcel" runat="server" 
                            onclick="Button_SQLToExcel_Click" Text="导入到Excel表" /></td>
                </tr>
                <tr>
                    <td>
                        <asp:GridView ID="GridView_Search" runat="server" AutoGenerateColumns="False" 
                            CellPadding="0" DataSourceID="SqlDataSource1">
                            <Columns>
                                
                                <asp:TemplateField HeaderText="SupplierID" SortExpression="SupplierID">
                                    <ItemTemplate>
                                        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("SupplierID") %>'></asp:TextBox>
                                    </ItemTemplate>
                                </asp:TemplateField>
                                <asp:TemplateField HeaderText="CategoryID" SortExpression="CategoryID">
                                    <ItemTemplate>
                                        <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("CategoryID") %>'></asp:TextBox>
                                    </ItemTemplate>
                                </asp:TemplateField>
                                <asp:TemplateField HeaderText="QuantityPerUnit" 
                                    SortExpression="QuantityPerUnit">
                                    <ItemTemplate>
                                        <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("QuantityPerUnit") %>'></asp:TextBox>
                                    </ItemTemplate>
                                </asp:TemplateField>
                            </Columns>
                        </asp:GridView>
                        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
                            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
                            SelectCommand="SELECT [SupplierID], [CategoryID], [QuantityPerUnit] FROM [Alphabetical list of products]">
                        </asp:SqlDataSource>
                    </td>
                </tr>
                </table>
        
        </div>
        </form>
    </body>
    </html>
    


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!


    2012年7月30日 8:55
  • 怎么会出现这个错误提示呢???

    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!


    2012年8月2日 7:34
  • 自己顶!

    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!

    2012年8月7日 9:11
  • 错误是因为j的大小超过gridview 控件的数量的大小了。。。。

    认真的活,认真的爱!

    2012年8月10日 10:39
    版主
  • 谢谢您的解答!我做了测试,只有j=0的时候才能运行,j=1就开始出错了,难道GridView只有1个控件?我错在哪里了啊?,

    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!

    2012年8月11日 7:07
  •         GridView ss = new GridView();
                ss.Rows[0].FindControl("id");

    一般都是直接去你的控件所在的那行找的!

    认真的活,认真的爱!

    2012年8月11日 9:54
    版主
  • 您提供的代码是教我怎么找GridView的控件么?

    if (GridView_Search.Controls[j].GetType() == typeof(TextBox))

    只有j=0的时候才能运行,j=1就不对了。Controls[]肯定不止1个控件啊!


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!

    2012年8月12日 7:23
  • 那是因为你那么写是找不到的 gridview 只能找他下一个级别的控件 也就是说你放在Row里面的控件是找不到的...

    认真的活,认真的爱!

    2012年8月12日 10:27
    版主
  •     根据您的提示,直接GridView.Controls[i]是找不到控件的,因为所有的控件都在Rows里,于是我修改了代码: if (GridView_Search.Controls[j].GetType() == typeof(TextBox))

    改成

         if (GridView_Search.Rows[i].Cells [j].Controls[0].GetType() == typeof(TextBox)),

    下面的string Str=...也做了相应修改,怎么打开的Excel表还是只有表头,没有内容呢?

    ------------------------------完整代码-----------------------------

    protected void Button_SQLToExcel_Click(object sender, EventArgs e)
        {
            if (GridView_Search.Rows.Count == 0)
                return;
            Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
            excel.Application.Workbooks.Add(true);
            excel.Visible = true;
            DisableControls(GridView_Search );
            for (int i = 0; i < GridView_Search.Columns.Count; i++)
            {
                excel.Cells[1, i + 1] = GridView_Search.Columns[i].HeaderText;//excel.Cells[1,i+1]  行->列,excel是从“1”开始
            }
    
            for (int i = 0; i < GridView_Search.Rows.Count; i++)
            {
                for (int j = 0; j < GridView_Search.Columns.Count; j++)
                {
                    
                    if (GridView_Search.Rows[i].Cells [j].Controls[0].GetType() == typeof(TextBox))//修改
                    
                    {
                        string str = (GridView_Search.Rows [i].Cells [j].Controls [0] as TextBox).Text;//修改
                        excel.Cells[i + 2, j + 1] = str;
                    }
    
                    else
                    {
                        excel.Cells[i + 2, j + 1] = GridView_Search.Rows[i].Cells[j].Text;
                    }
    
                }
            }
        }


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!


    2012年8月14日 4:04
  • 没内容是因为没成功的把TextBox转换成内容 

        excel.Cells[i + 2, j + 1] = str;
    你上面的那句话还是直接用单元格里面的值。。而不是单元格里面控件的值

    其实完全可以换一种方法写的..既然你是想一格一格的填充 你就直接画 。。如果你有aspx页面的代码 可以贴出来 我帮你写一点 示例!


    认真的活,认真的爱!

    2012年8月14日 11:57
    版主
  • 我也是觉得TextBox中的代码还未被读取到,就是不知道该怎么改了!

    下面是我用的前台代码,就3列,每一列都是TextBox,该怎么改进呢?

    ------------------------------前台代码-------------------------

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="Default3" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <style type="text/css">
            .style1
            {
                width: 100%;
            }
        </style>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
        
            <table cellpadding="0" cellspacing="0" class="style1">
                <tr>
                    <td>
                        <asp:Button ID="Button_SQLToExcel" runat="server" 
                            onclick="Button_SQLToExcel_Click" Text="导入到Excel表" /></td>
                </tr>
                <tr>
                    <td>
                        <asp:GridView ID="GridView_Search" runat="server" AutoGenerateColumns="False" 
                            CellPadding="0" DataSourceID="SqlDataSource1">
                            <Columns>
                                
                                <asp:TemplateField HeaderText="SupplierID" SortExpression="SupplierID">
                                    <ItemTemplate>
                                        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("SupplierID") %>'></asp:TextBox>
                                    </ItemTemplate>
                                </asp:TemplateField>
                                <asp:TemplateField HeaderText="CategoryID" SortExpression="CategoryID">
                                    <ItemTemplate>
                                        <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("CategoryID") %>'></asp:TextBox>
                                    </ItemTemplate>
                                </asp:TemplateField>
                                <asp:TemplateField HeaderText="QuantityPerUnit" 
                                    SortExpression="QuantityPerUnit">
                                    <ItemTemplate>
                                        <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("QuantityPerUnit") %>'></asp:TextBox>
                                    </ItemTemplate>
                                </asp:TemplateField>
                            </Columns>
                        </asp:GridView>
                        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
                            ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
                            SelectCommand="SELECT [SupplierID], [CategoryID], [QuantityPerUnit] FROM [Alphabetical list of products]">
                        </asp:SqlDataSource>
                    </td>
                </tr>
                </table>
        
        </div>
        </form>
    </body>
    </html>


    C# 菜鸟中的雏鸟!提的问题也许很幼稚,但我是认真的。希望看在党国的面子上拉兄弟一把!

    2012年8月14日 12:27
  •       for (int i = 0; i < GridView_Search.Rows.Count; i++)
                {
                  string c1 = ((TextBox)GridView_Search.Rows[i].FindControl("textbox1")).Text;
                  string c2= ((TextBox)GridView_Search.Rows[i].FindControl("textbox2")).Text;
                  string c3= ((TextBox)GridView_Search.Rows[i].FindControl("textbox3")).Text;
    ///填充数据 
                }

    上面的代码是一行一行获取数据的 你可以在///填充数据那边   按你想要的格式填充任何导出

    认真的活,认真的爱!

    2012年8月15日 15:35
    版主