本次應用datatable導出,若用gridview(假設gridview設為了分頁顯示)會出現只導出當前頁的情況。
protected void btnPrn_Click(object sender, EventArgs e) { DataSet ds = new DataSet("gv");//new一個標視為 gv的庫 DataTable dt = new DataTable("logoo"); string sCmd = "select * from mytable "; MySqlDataReader reader; mySqlMod newMySqlMod = new mySqlMod(); newMySqlMod.RunSQL(sCmd, out reader); dt.Load(reader); string FileName ="test.xls";//前為固定名稱,后為隨機名稱 Guid.NewGuid().ToString() + ".xls";
//增加服務發布地址 string sNewFullFile = Server.MapPath(FileName); try { //此種方法必須在發布地址預先放置一個format.xls模板 File.Copy(Server.MapPath("format.xls"), sNewFullFile); if (File.Exists(sNewFullFile)) File.Delete(sNewFullFile); } catch (Exception er) { Response.Write(er.Message); return; } String strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source="+ sNewFullFile + ";" + "Extended Properties=Excel 8.0;"; System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(strConn); OleDbCommand cmd = null; bool bRet = false; try { conn.Open(); cmd = new OleDbCommand("create table [sheet1]([ID] int,[字段一] Text,[字段二] Text,[字段三] Text)", conn); cmd.ExecuteNonQuery(); string strSQL = "INSERT INTO [Sheet1$] ([ID], [字段一],[字段二],[字段三]) VALUES (?, ?, ?, ?)"; cmd = new OleDbCommand(strSQL, conn); for (int i = 0; i < 4; i++) { cmd.Parameters.Add(i.ToString(), OleDbType.VarChar); } DataView dv = dt.DefaultView; foreach (DataRowView row in dv) { cmd.Parameters[0].Value = (int)row["id"]; cmd.Parameters[1].Value = row["col1"].ToString(); cmd.Parameters[2].Value = row["col2"].ToString(); cmd.Parameters[3].Value = row["col3"].ToString(); cmd.ExecuteNonQuery(); } bRet = true; } catch (Exception er) { Response.Write(er.Message); } finally { if (cmd != null) { cmd.Dispose(); } conn.Dispose(); } if (bRet) Response.Redirect(FileName); }
參考文章:一、C#操作Excel(創建、打開、讀寫、保存)幾種方法的總結
下面開始就各種方法逐步說明其具體的Excel操作過程:
1.通過ADO.NET數據庫連接方式 Microsoft Jet 提供程序用於連接到 Excel 工作簿。在以下連接字符串中,Extended Properties 關鍵字設置 Excel 特定的屬性。“HDR=Yes;”指示第一行中包含列名,而不是數據,“IMEX=1;”通知驅動程序始終將“互混”數據列作為文本讀取。Excel 8.0 針對Excel2000及以上版本,Excel5.0 針對Excel97。
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""
注意,Extended Properties 所需的雙引號必須還要加雙引號。
使用ADO.NET打開、讀取並關閉代碼示例如下:
using System.Data.OleDb; using System.Data;
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:/test.xls;" + "Extended Properties=Excel 8.0;"; OleDbConnection objConn = new OleDbConnection(sConnectionString); objConn.Open(); OleDbCommand objCmdSelect =new OleDbCommand("SELECT * FROM [sheet1]", objConn); OleDbDataAdapter objAdapter1 = new OleDbDataAdapter(); objAdapter1.SelectCommand = objCmdSelect; DataSet objDataset1 = new DataSet(); //將Excel中數據填充到數據集 objAdapter1.Fill(objDataset1, "XLData"); objConn.Close();
從上面可以看出,使用ADO.NET可將Excel當作普通數據庫,使用SQL語句來操作。
通過ADO.NET獲取Excel文件的各Sheet名稱,可使用元數據方式:
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:/test.xls;" + "Extended Properties=Excel 8.0;"; OleDbConnection cn = new OleDbConnection(sConnectionString); cn.Open(); DataTable tb = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null); foreach (DataRow row in tb.Rows) { //遍歷彈出各Sheet的名稱 MessageBox.Show(row["TABLE_NAME"]); }
關於使用ADO.NET創建並寫入Excel文件與普通數據庫操作極為類似,參見以下代碼:
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=c:/test.xls;" + "Extended Properties=Excel 8.0;"; OleDbConnection cn = new OleDbConnection(sConnectionString); string sqlCreate = "CREATE TABLE TestSheet ([ID] INTEGER,[Username] VarChar,[UserPwd] VarChar)"; OleDbCommand cmd = new OleDbCommand(sqlCreate, cn); //創建Excel文件:C:/test.xls cn.Open(); //創建TestSheet工作表 cmd.ExecuteNonQuery(); //添加數據 cmd.CommandText = "INSERT INTO TestSheet VALUES(1,'elmer','password')"; cmd.ExecuteNonQuery(); //關閉連接 cn.Close();
關於SQL語句中用到的數據類型,請查看System.Data.OleDb.OleDbType 枚舉。
至此,使用ADO.NET打開、創建、讀取、寫入、保存並退出已全部實現,總結起來,與數據庫操作基本無異,很簡單。這種方式的好處就是通用性強,將Excel中內容看作數據表,讀取操作簡單可靠,適合內容規范的Excel表格的數據讀取。缺點是當Excel結構復雜,如含合並單元等時,無法正確讀取,甚至出現不可預知的異常。
二、asp.net導出數據到Excel的三種方法
第一種是比較常用的方法。是利用控件的RenderControl功能,得到該控件生成的HTML,然后以Excel文件的類型輸出到客戶端。這種方法生成的其實是個HTML文件,只不過Excel支持HTML格式,所以使用起來似乎和真正的Excel文件沒什么兩樣,但它終究不是Excel格式,它不能當作數據源供其他程序調用。
這種實現起來比較簡單,就不多述,請看代碼。
public void ExportExcel( System.Web.UI.WebControls.WebControl objControl, string strFileName) { strFileName = System.Web.HttpUtility.UrlEncode(strFileName, System.Text.Encoding.UTF8); System.Web.HttpContext.Current.Response.Clear(); System.Web.HttpContext.Current.Response.Buffer = true; System.Web.HttpContext.Current.Response.Charset = "gb2312"; System.Web.HttpContext.Current.Response.AppendHeader("Content-Disposition", "online; filename=" + strFileName + ".xls"); System.Web.HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312"); System.Web.HttpContext.Current.Response.ContentType = "application/ms-excel"; 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); objControl.RenderControl(oHtmlTextWriter); objControl = null; System.Web.HttpContext.Current.Response.Write(oStringWriter.ToString().Replace("<td", "<td STYLE='MSO-NUMBER-FORMAT:\@'")); System.Web.HttpContext.Current.Response.Buffer = false; System.Web.HttpContext.Current.Response.End(); }
可能出現的錯誤:
1、只能在執行 Render() 的過程中調用 RegisterForEventValidation;
解決辦法:修改頁面選項<%@ Page EnableEventValidation = "false"
還有一種辦法是修改web.config的,但影響全局,這里就不推薦了。
2...必須放在具有 runat=server 的窗體標記內。
解決辦法:
在頁面中重寫VerifyRenderingInServerForm方法,不對控件要求form容器進行驗證
public override void VerifyRenderingInServerForm(Control control) { //這里沒有內容。 }
第二種方法是利用Excel的Com接口庫來完成,這種方法的優點是功能強大,可像使用Excel程序一樣來操作Excel文件,缺點是需要服務器安裝Excel程序,且需要一定的安全配置。
一、准備工作:
1)安裝Microsoft Excel
2)Com的安全設置。
在命令行輸入DCOMCNFG ,進入組件服務設置界面,如圖:
打到Micorosoft Excel應用程序,如圖:
右鍵點擊屬性,然后點擊“安全”,將“啟動和激活權限”、“訪問權限”、“配置權限”都選擇自定義,然后添加運行ASP.NET的用戶(IIS6以上是NETWORK SERVICE以下是ASPNET),給予全部權限,如圖所示:
3)配置文件目錄權限,因為可能要保存文件到某目錄中,所以要將該目錄對ASP.NET用戶予以寫入權限。
二、使用
在VS.NET的工程中添加引用,如圖:
如果添加引用后Excel組件不能正常使用(excel組件的左邊顯示一個黃色的感嘆號),可以使用.Net工具進行組件轉換。
轉換方法,運行vs.net的命令行工具,進入Office目錄,輸入TlbImp Excel.exe即可,然后刪除有問題的引用重新添加引用,這次使用瀏覽,然后引用Excel.DLL。
根據我的經驗,vs2003可以直接引用Microsoft Excel x.0 ObjectLibary,而vs2005就需要使用工具轉換成DLL才可使用。
然后即可以使用Excel.Application對象來操作它了。
以下就一段簡單的將GirdView的數據導出到Excel的代碼,功能較簡單,權當拋磚引玉了。
this.GridView1.DataBind(); Excel.ApplicationClass oExcel = new Excel.ApplicationClass(); object oMissing = System.Reflection.Missing.Value; oExcel.Workbooks.Add(oMissing); Excel.Workbook oBook = oExcel.Workbooks[1]; Excel.Worksheet oSheet = (Excel.Worksheet)oBook.Sheets[1]; oSheet.Name = this.Title; Excel.Range rg; for (int j = 0; j < this.GridView1.HeaderRow.Cells.Count; j++) { rg = ((Excel.Range)oSheet.Cells[ 1, j + 1]); rg.FormulaR1C1 = this.GridView1.HeaderRow.Cells[j].Text; } for(int i = 0;i<this.GridView1.Rows.Count;i++) { for (int j = 0; j < this.GridView1.Rows[0].Cells.Count; j++) { rg = ((Excel.Range)oSheet.Cells[i + 2, j+1]); rg.FormulaR1C1 = this.GridView1.Rows[i].Cells[j].Text; } } rg = null; string VirFileName = Guid.NewGuid().ToString() + ".xls"; oBook.SaveAs(Server.MapPath(VirFileName), Excel.XlFileFormat.xlExcel9795, oMissing, oMissing, oMissing, oMissing, Excel.XlSaveAsAccessMode.xlExclusive, oMissing, oMissing, oMissing, oMissing, oMissing); oExcel.Workbooks.Close(); oExcel.Quit(); oSheet = null; oBook = null; oExcel = null; GC.Collect(); Response.Redirect(VirFileName);
說明一下:為了Excel進程在使用完成后能徹底退出,需要將所有對象在使用完成后清空,像代碼中的rg,oSheet,oBook,oExcel等。
第三種方法是利用OELDB數據訪問對象操作Excel文件,達到將數據導出到Excel的目的,這種方法可能用的人不太多,缺點是必須有一個存在的Excel文件。優點是服務器不需要安裝Excel,且生成的Excel是標准的Excel格式可以當作數據源使用。
准備工作:
1)先用准備一個Excel文件,這個Excel文件可以是空的,或是有一定格式的當做數據模板使用。
2)將操作的目錄給ASP.NET用戶(ASPNET 或NETWORK SERVICE)寫入權限。
以下是示例:
說明一下:如果這個模板文件是個空文件,則需要使用Create Table創建一個工作表,否則只需使用已有的表進操作就可以了。
DataTable dt = new DataTable(); dt.Columns.Add("name"); dt.Columns.Add("age", typeof(int)); dt.Columns.Add("phone"); dt.Rows.Add("老張", 40,"99213812"); dt.Rows.Add("小李", 28,"a21313"); dt.Rows.Add("小王", 22,"2131434"); string FileName = Guid.NewGuid().ToString()+".xls"; string sNewFullFile = Server.MapPath(FileName); try { File.Copy(Server.MapPath("format.xls"), sNewFullFile); } catch (Exception er) { Response.Write(er.Message); return; } string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=True;Data Source=" + sNewFullFile + ";Extended Properties=Excel 8.0;"; System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(strConn); OleDbCommand cmd = null; bool bRet = false; try { conn.Open(); cmd = new OleDbCommand("create table [sheet4]([姓名] Text,[年齡] int,[電話] Text)",conn); cmd.ExecuteNonQuery(); string strSQL = "INSERT INTO [Sheet4$] ([姓名], [年齡],[電話]) VALUES (?, ?, ?)"; cmd = new OleDbCommand(strSQL, conn); for (int i = 0; i < 3; i++) { cmd.Parameters.Add(i.ToString(), OleDbType.VarChar); } DataView dv = dt.DefaultView; foreach (DataRowView row in dv) { cmd.Parameters[0].Value = row["name"].ToString(); cmd.Parameters[1].Value =(int) row["age"]; cmd.Parameters[2].Value = row["phone"].ToString(); cmd.ExecuteNonQuery(); } bRet = true; } catch (Exception er) { Response.Write(er.Message); } finally { if (cmd != null) { cmd.Dispose(); } conn.Dispose(); } if(bRet) Response.Redirect(FileName);