常见的C#实现导出到Excel 功能

报表在生产中的应用非常广泛,项目中也会经常需要实现将自动生成报表,并导出到Excel 中的功能。以下是对该功能实现的一点总结。

 

 

1.利用GridView自带的导出功能

图1.1 页面呈现效果

   

1.2 导出到 Excel里的效果

前台直接拖放一个GridView控件。

后台代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Web.UI.HtmlControls;//加上这个命名空间才能使用HtmlForm类


namespace WebToExcel03
{
/// <summary>
/// GridView自带的属性
/// </summary>
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Gv_Bind();
}
}

public void Gv_Bind()
{
string connStr = "Data Source=20110814-1820;Initial Catalog=NewHeleScann;Integrated Security=True";
string sql = "select * from Scan_JiDiTable ";
SqlConnection conn = new SqlConnection(connStr);
SqlDataAdapter sdp = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
sdp.Fill(ds);
GridView1.DataSource = ds;
GridView1.DataBind();
}


//在页面重写Web基类 否则报错:控件必须放在具有 runat=server 的窗体标记内"错误
public override void VerifyRenderingInServerForm(Control control)
{
// Confirms that an HtmlForm control is rendered for
}

private void ExportExcelFromDataGrid(string filename, GridView ToExcelGrid)
{
/* 传说此方法更好,可以让我们不用重写VerifyRenderingInServerForm方法
* 但是这里未调试成功
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
HtmlTextWriter htw = new HtmlTextWriter(sw);

Page page = new Page();
HtmlForm form = new HtmlForm();

ToExcelGrid.EnableViewState = false;

// Deshabilitar la validación de eventos, sólo asp.net 2
page.EnableEventValidation = false;

// Realiza las inicializaciones de la instancia de la clase Page que requieran los diseñadores RAD.
page.DesignerInitialize();

page.Controls.Add(form);
form.Controls.Add(ToExcelGrid);

page.RenderControl(htw);
*/
Response.ClearHeaders();
Response.Clear();
Response.Expires = 0;
Response.Buffer = true;
Response.HeaderEncoding = System.Text.Encoding.UTF8;
// Response.Charset = "utf-8";
Response.AppendHeader("Content-Disposition", "attachment;filename=" + Server.UrlEncode(filename));
Response.ContentEncoding = System.Text.Encoding.Default;//设置输出流为简体中文
// Response.ContentType = "application/ms-excel";//设置输出文件类型为excel文件。
Response.ContentType = "Application/octet-stream";
this.EnableViewState = false;
System.Globalization.CultureInfo myCItrad = new System.Globalization.CultureInfo("zh-CHS", true);
System.IO.StringWriter oStringWriter = new System.IO.StringWriter(myCItrad);
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
ToExcelGrid.RenderControl(oHtmlTextWriter);
Response.Write(oStringWriter.ToString());
Response.End();
}

protected void ToExcel_Click(object sender, EventArgs e)
{
string filename = "ToExcel" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls" ;
ExportExcelFromDataGrid(filename, GridView1);
}
}
}

2 采用COM.Excel组件实现导出到Excel

COM.Excel是一个外部组件,所以首先要在当前项目中,添加对它的引用。

单击项目,右键选择“添加引用”,找到该组件,添加完成后效果如下:

为了方便查看数据,这里也在前台放了一个GridView控件(实际上与导出没有关系)。

导出效果如下:

 

后台源码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;
using System.Collections;

namespace ToExcelCom
{
/// <summary>
/// 采用COM.Excel组件实现导出到Excel
/// </summary>
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
//获取ds
DataSet ds = GetDs();
//绑定到GridView
GridView1.DataSource = ds;
GridView1.DataBind();
}
}

public DataSet GetDs()
{
string connStr = "Data Source=20110814-1820;Initial Catalog=NewHeleScann;Integrated Security=True";
string sql = "select * from Scan_JiDiTable ";
SqlConnection conn = new SqlConnection(connStr);
SqlDataAdapter sdp = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
sdp.Fill(ds);
return ds;
}

protected void ToExcel_Click(object sender, EventArgs e)
{
string path = System.Web.HttpContext.Current.Server.MapPath("~/SaveExcelFiles/");//保存路径
//string filename = comm.OutputExcel(ds.Tables[0], DDLName.SelectedItem.Text.ToString(), path);//保存文件
Hashtable hs = new Hashtable();//表列名
DataSet ds = GetDs();
//循环添加表列名
foreach (DataColumn dc in ds.Tables[0].Columns)
{
hs.Add(dc.ColumnName, dc.ColumnName);
}
//DataTable dts = ds.Tables[0];
DataTable[] dts = { ds.Tables[0]};//数据集的集合
string strTitle = "";
string filename = DataExcels(dts ,strTitle, path, hs);
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + filename);
System.Web.HttpContext.Current.Response.ContentType = "application/ms-excel";
System.Web.HttpContext.Current.Response.TransmitFile(path + filename);//打开文件
//System.Web.HttpContext.Current.Response.TransmitFile(filename);//打开文件
System.Web.HttpContext.Current.Response.End();
}
/// <summary>
///
/// </summary>
/// <param name="dts"></param>
/// <param name="strTitle"></param>
/// <param name="FilePath"></param>
/// <param name="nameList"></param>
/// <param name="titles"></param>
/// <returns></returns>
public string DataExcels(System.Data.DataTable[] dts, string strTitle, string FilePath, Hashtable nameList)
{
COM.Excel.cExcelFile excel = new COM.Excel.cExcelFile();
//当文件大于10的时候 清空所有文件!!!
ClearFile(FilePath);
//文件名
string filename = strTitle+ DateTime.Now.ToString("yyyyMMddHHmmssff") + ".xls";
//生成相应的文件
excel.CreateFile(FilePath + filename);
//设置margin
COM.Excel.cExcelFile.MarginTypes mt1 = COM.Excel.cExcelFile.MarginTypes.xlsTopMargin;
COM.Excel.cExcelFile.MarginTypes mt2 = COM.Excel.cExcelFile.MarginTypes.xlsLeftMargin;
COM.Excel.cExcelFile.MarginTypes mt3 = COM.Excel.cExcelFile.MarginTypes.xlsRightMargin;
COM.Excel.cExcelFile.MarginTypes mt4 = COM.Excel.cExcelFile.MarginTypes.xlsBottomMargin;
double height = 2.2;
excel.SetMargin(ref mt1, ref height);
excel.SetMargin(ref mt2, ref height);
excel.SetMargin(ref mt3, ref height);
excel.SetMargin(ref mt4, ref height);
//设置字体!!
COM.Excel.cExcelFile.FontFormatting ff = COM.Excel.cExcelFile.FontFormatting.xlsNoFormat;
string font = "宋体";
short fontsize = 14;
excel.SetFont(ref font, ref fontsize, ref ff);
byte b1 = 1, b2 = 12;
short s3 = 12;
excel.SetColumnWidth(ref b1, ref b2, ref s3);

string header = "页眉";
string footer = "页脚";
excel.SetHeader(ref header);
excel.SetFooter(ref footer);

COM.Excel.cExcelFile.ValueTypes vt = COM.Excel.cExcelFile.ValueTypes.xlsText;
COM.Excel.cExcelFile.CellFont cf = COM.Excel.cExcelFile.CellFont.xlsFont0;
COM.Excel.cExcelFile.CellAlignment ca = COM.Excel.cExcelFile.CellAlignment.xlsCentreAlign;
COM.Excel.cExcelFile.CellHiddenLocked chl = COM.Excel.cExcelFile.CellHiddenLocked.xlsNormal;
// 报表标题
int cellformat = 1;
int rowIndex = 1;//起始行
int colIndex = 0;
foreach (System.Data.DataTable dt in dts)
{
colIndex = 0;
//取得列标题
foreach (DataColumn colhead in dt.Columns)
{
colIndex++;
string name = colhead.ColumnName.Trim();
object namestr = (object)name;
excel.WriteValue(ref vt, ref cf, ref ca, ref chl, ref rowIndex, ref colIndex, ref namestr, ref cellformat);
}
//取得表格中的数据
foreach (DataRow row in dt.Rows)
{
rowIndex++;
colIndex = 0;
foreach (DataColumn col in dt.Columns)
{
colIndex++;
if (col.DataType == System.Type.GetType("System.DateTime"))
{
object str = (object)(Convert.ToDateTime(row[col.ColumnName].ToString())).ToString("yyyy-MM-dd"); ;
excel.WriteValue(ref vt, ref cf, ref ca, ref chl, ref rowIndex, ref colIndex, ref str, ref cellformat);
}
else
{
object str = (object)row[col.ColumnName].ToString();
excel.WriteValue(ref vt, ref cf, ref ca, ref chl, ref rowIndex, ref colIndex, ref str, ref cellformat);
}
}
}
rowIndex += 3 ;
}
int ret = excel.CloseFile();
//return FilePath+filename;
return filename;
}

#region 清理过时的Excel文件

private void ClearFile(string FilePath)
{
String[] Files = System.IO.Directory.GetFiles(FilePath);
if (Files.Length > 10)
{
for (int i = 0; i < 10; i++)
{
try
{
System.IO.File.Delete(Files[i]);
}
catch
{
}

}
}
}
#endregion
}
}

对比两种导出的效果,显然第二种更加人性化一些。当然这两种方法,基本都被普遍使用。

3.使用asposecell组件,详细参考http://www.cnblogs.com/whitewolf/archive/2011/03/21/Aspose_Cells_Template1.html#commentform

该组件确实强大,比较好用,Excel模板可以事先做好,很直观,对于格式比较复杂的报表,优势明显。

效果如下:

这种方案,在http://www.cnblogs.com/whitewolf/archive/2011/03/21/Aspose_Cells_Template1.html#commentform有很详细的演示,这里不再獒述。

但是也有人从性能方面提出了更好的方案,如通过SSIS 包的实现,据说这种方案主要是针对于较大数据量的报表性能卓越,我认为值得尝试。

posted @ 2011-12-04 15:12  楠木大叔  阅读(1203)  评论(0编辑  收藏  举报