1、将datagrid数据作为HTML输出为流保存为excel文件
具体见http://dotnet.aspx.cc/ShowDetail.aspx?id=8A4CBF47-B888-4832-3389-ED3A3A3C8AAB
这里贴出主要代码
private void Button1_Click(object sender, System.EventArgs e)
{
Response.Clear(); 
Response.Buffer= true; 
Response.Charset="GB2312";    
Response.AppendHeader("Content-Disposition","attachment;filename=FileName.xls"); 
Response.ContentEncoding=System.Text.Encoding.UTF8;设置输出流为简体中文
Response.ContentType = "application/ms-excel";//设置输出文件类型为excel文件。 
this.EnableViewState = false;    
System.Globalization.CultureInfo myCItrad = new System.Globalization.CultureInfo("ZH-CN",true);
System.IO.StringWriter oStringWriter = new System.IO.StringWriter(myCItrad); 
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
this.ClearControls(DataGrid1);
this.DataGrid1.RenderControl(oHtmlTextWriter); 
Response.Write(oStringWriter.ToString());
Response.End();
}
private void ClearControls(Control control)
        {
            for (int i=control.Controls.Count -1; i>=0; i--)
            {
                ClearControls(control.Controls[i]);
            }
            if (!(control is TableCell))
            {
                if (control.GetType().GetProperty("SelectedItem") != null)
                {
                    LiteralControl literal = new LiteralControl();
                    control.Parent.Controls.Add(literal);
                    try
                    {
                        literal.Text = (string)control.GetType().GetProperty("SelectedItem").GetValue(control,null);
                    }
                    catch
{
}
                    control.Parent.Controls.Remove(control);
                }
else
                    if (control.GetType().GetProperty("Text") != null)
                {
                    LiteralControl literal = new LiteralControl();
                    control.Parent.Controls.Add(literal);
                    literal.Text = (string)control.GetType().GetProperty("Text").GetValue(control,null);
                    control.Parent.Controls.Remove(control);
                }
            }
            return;
        }
该方法的优点是简单快捷,显示的datagrid什么样子,excel中就是什么样子,不会出现身份证号码等数字字符串被excel处理成数字的情况。但是缺点是不能导出过于复杂的datagrid,比如有分页,datagrid分栏中有HyperLink等等。如果datagrid中有分页的需要。那么解决的办法就是:在导出前datagrid.AllowPaging=false; 导出后。重新datagrid.AllowPaging=true;datagrid.banddata();一次。 
2、这种方法也比较快捷简单。执行后直接生成excel文档供用户下载。此方法也是利用流来输出文件,不过可以由datatable中导出数据。但是缺点是,excel无法将数字字符串处理成字符串而是直接处理成数字格式(也就是说处理前面带零之类的数字字符串,excel会默认为其为数字而把前面的零给去除掉)。在excel中如果数字前加上半角的单引号“ ' ”会将其作为字符串来处理。但是我在处理的过程中,发现这种导出的excel中没有办法实现。因为这种方法导出的是excel数据并未导出其格式,如果用文本阅读器查看就可以看出。一种处理办法就是在用EXCEL打开该文件的时候他会询问你哪些列作为字符串处理,你自己指定就是了,当然这种情况下可以不要加单引号。呵呵,这样的办法似乎不是什么办法。^_^!
using System.IO;
            StringWriter sw=new StringWriter(); 
            sw.WriteLine("所属库房\t类别名称\t号码段\t开始序号\t结尾序号\t库存状态");  //excel中以tab作为栏目分隔符号
            dt=(System.Data.DataTable)Session["SmnoStock"];
            DataRow dr;
            string housename,sortname,smno,fromno,tono,stock;
            for(int i=0;i<dt.Rows.Count;i++)
            { 
                dr=dt.Rows[i];
                housename=dr["housename"].ToString();
                sortname=dr["sortname"].ToString();
                smno=dr["smno"].ToString();
                fromno=dr["fromno"].ToString();
                tono=dr["tono"].ToString();
                stock=dr["stock"].ToString();
                sw.WriteLine(housename+"\t"+sortname+"\t"+smno+"\t"+fromno+"\t"+tono+"\t"+stock); 
            } 
            sw.Close();
            Response.AddHeader("Content-Disposition", "attachment; filename=sm"+DateTime.Now.ToShortDateString()+".xls"); 
            Response.ContentType = "application/ms-excel"; 
            Response.ContentEncoding=System.Text.Encoding.GetEncoding("GB2312"); 
            Response.Write(sw); 
            Response.End();
3、这种方法是通过调用COM中的EXCEL来解决问题。这种方法比较灵活,当然也麻烦。以下的一段程序是网络中比较盛行的一种处理该问题的方法。但是还有一些BUG,比如导出excel后无法杀死进程中的excel,导致excel无法使用。我对其进行了修改,基本上可以解决问题。但是该方法还有个不足就是如果datatable中如果有不需要显示的col也是会被导出的。呵呵,这个问题呢,应该不与程序没有太大关系了。看各位如何处理了!
首先要引用COM中的EXCEL
using EXCEL;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Threading;
public void OutputExcel(DataTable dt,string filename)
{
   //
   // TODO: 在此处添加构造函数逻辑
   //
                           //dt为要输出到Excel的数据,filename为文件名,最好为英文
   GC.Collect(); //强制垃圾回收
   Application excel;// = new Application();
   int rowIndex=4; //初始划起始行
   int colIndex=1;
   _Workbook xBk; //工作薄
   _Worksheet xSt; //工作表
   excel= new ApplicationClass(); //excel实例
  
   xBk = excel.Workbooks.Add(true); //为excel添加工作薄xBk
   
   xSt = (_Worksheet)xBk.ActiveSheet; //获得活动的工作表
   //
   //取得标题
   //
   foreach(DataColumn col in dt.Columns)
   {
    colIndex++;
    excel.Cells[4,colIndex] = col.Caption; //遍历第4行的第2列起,为其添加标题,如果dt中的column没有设置相应的caption则默认为其columnname
    xSt.get_Range(excel.Cells[4,colIndex],excel.Cells[4,colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;//设置标题格式为居中对齐
   }
   //
   //取得表格中的数据 
   //遍历dt中的每行每列添加其到相应的cell中
   foreach(DataRow row in dt.Rows)
   {
    rowIndex ++;
    colIndex = 1;
    foreach(DataColumn col in dt.Columns)
    {
     colIndex ++;
     if(col.DataType == System.Type.GetType("System.DateTime"))
     {
      excel.Cells[rowIndex,colIndex] = (Convert.ToDateTime(row[col.ColumnName].ToString())).ToString("yyyy-MM-dd");
      xSt.get_Range(excel.Cells[rowIndex,colIndex],excel.Cells[rowIndex,colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;//设置日期型的字段格式为居中对齐
     }
     else
      if(col.DataType == System.Type.GetType("System.String"))
     {
      excel.Cells[rowIndex,colIndex] = "'"+row[col.ColumnName].ToString();
      xSt.get_Range(excel.Cells[rowIndex,colIndex],excel.Cells[rowIndex,colIndex]).HorizontalAlignment = XlVAlign.xlVAlignJustify;//设置字符型的字段格式为左对齐
     }
     else
     {
      excel.Cells[rowIndex,colIndex] = row[col.ColumnName].ToString();
     }
    }
   }
   //
   //加载一个合计行
   //
   int rowSum = rowIndex + 1;
   int colSum = 2;
   excel.Cells[rowSum,2] = "合计";
   xSt.get_Range(excel.Cells[rowSum,2],excel.Cells[rowSum,2]).HorizontalAlignment = XlHAlign.xlHAlignCenter;
   //
   //设置选中的部分的颜色
   //
   xSt.get_Range(excel.Cells[rowSum,colSum],excel.Cells[rowSum,colIndex]).Select();
   xSt.get_Range(excel.Cells[rowSum,colSum],excel.Cells[rowSum,colIndex]).Interior.ColorIndex = 19;//设置为浅黄色,共计有56种
   //
   //取得整个报表的标题
   //
   excel.Cells[2,2] = str;
   //
   //设置整个报表的标题格式
   //
   xSt.get_Range(excel.Cells[2,2],excel.Cells[2,2]).Font.Bold = true;
   xSt.get_Range(excel.Cells[2,2],excel.Cells[2,2]).Font.Size = 22;
   //
   //设置报表表格为最适应宽度
   //
   xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Select();
   xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Columns.AutoFit();
   //
   //设置整个报表的标题为跨列居中
   //
   xSt.get_Range(excel.Cells[2,2],excel.Cells[2,colIndex]).Select();
   xSt.get_Range(excel.Cells[2,2],excel.Cells[2,colIndex]).HorizontalAlignment = XlHAlign.xlHAlignCenterAcrossSelection;
   //
   //绘制边框
   //
   xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,colIndex]).Borders.LineStyle = 1;
   xSt.get_Range(excel.Cells[4,2],excel.Cells[rowSum,2]).Borders[XlBordersIndex.xlEdgeLeft].Weight = XlBorderWeight.xlThick;//设置左边线加粗
   xSt.get_Range(excel.Cells[4,2],excel.Cells[4,colIndex]).Borders[XlBordersIndex.xlEdgeTop].Weight = XlBorderWeight.xlThick;//设置上边线加粗
   xSt.get_Range(excel.Cells[4,colIndex],excel.Cells[rowSum,colIndex]).Borders[XlBordersIndex.xlEdgeRight].Weight = XlBorderWeight.xlThick;//设置右边线加粗
   xSt.get_Range(excel.Cells[rowSum,2],excel.Cells[rowSum,colIndex]).Borders[XlBordersIndex.xlEdgeBottom].Weight = XlBorderWeight.xlThick;//设置下边线加粗
   //
   //显示效果
   //
   excel.Visible=true;
   xBk.SaveCopyAs(Server.MapPath(".")+"\\"+filename+".xls");
   ds = null;
            xBk.Close(false, null,null);
   
            excel.Quit();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(xSt); //注意释放的先后顺序
            System.Runtime.InteropServices.Marshal.ReleaseComObject(xBk);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
     xSt = null;
            xBk = null;
            excel = null;
}
   public void output(string filename)
    {
      string path = HttpContext.Current.Server.MapPath(filename+".xls");
      System.IO.FileInfo file = new System.IO.FileInfo(path);
      HttpContext.Current.Response.Clear();
      HttpContext.Current.Response.Charset="GB2312";
      HttpContext.Current.Response.ContentEncoding=System.Text.Encoding.UTF8;
      // 添加头信息,为"文件下载/另存为"对话框指定默认文件名
      HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpContext.Current.Server.UrlEncode(file.Name));
      // 添加头信息,指定文件大小,让浏览器能够显示下载进度
      HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString());
                 
      // 指定返回的是一个不能被客户端读取的流,必须被下载
      HttpContext.Current.Response.ContentType = "application/ms-excel";
                 
      // 把文件流发送到客户端
      HttpContext.Current.Response.WriteFile(file.FullName);
      // 停止页面的执行
           
      HttpContext.Current.Response.End();
    }
//可供调用的部分
    public void ExportExcel(System.Data.DataTable dt,string filename)
    {
        OutputExcel(dt,filename);
        GC.Collect(); //再次垃圾回收。在原程序中该三个步骤都在同一个函数中处理完毕,系统对excel回收不完全。
        output(filename);
    }
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号