本人大學新手一枚,在大學工作室學習asp.net,從中積累的一些小的知識和大家一起分享與討論。
今天的主題是導出數據。現在從服務器端到客戶端數據的幾種主要方式有:web頁面呈現(各種view..),導出到excel,導出到word,導出到報表等。我今天講下我實際開發項目中用到的導出到excel和導出到word。
一、導出到excel
主要有以下兩種方法:
(1)用數據展示控件如GridView或者ListView等,先把需要導出的數據展示在web頁面上,然后再利用Response的另存為功能,將html頁存為Xls格式的Excel文件。
下面是代碼:
protected void btnExport_Click(object sender, EventArgs e) { this.dp.pageSize = 9999;//為了導出全部數據,ListView 使用pageSize,但是GridView 可用AllowPaging this.lvExt.HiddenFields ="c0,c1";//根據id隱藏列 this.lv.DataBind(); Export("application/ms-excel", "場地信息.xls", lv, "場地信息"); this.dp.pageSize = 10; this.lv.DataBind(); } protected void btnExport_Load(object sender, EventArgs e) { //將控件注冊為回發的觸發器。 //該方法用於配置 UpdatePanel 控件內以其他方式執行異步回發的回發控件。 ScriptManager sm = ScriptManager.GetCurrent(this.Page); if (sm != null) { sm.RegisterPostBackControl((Control)sender); } } /// <summary> /// 導出方法 2014-5-30 bob /// </summary> /// <param name="FileType">文件類型</param> /// <param name="FileName">文件名稱</param> /// <param name="c">裝載數據的控件如:ListView,GridView</param> /// <param name="Title">導出文件的標題</param> public void Export(string FileType, string FileName, System.Web.UI.Control c, string Title) { Response.Clear(); Response.Buffer = true; Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312"); Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(FileName, Encoding.UTF8).ToString()); Response.ContentType = FileType; // 設置輸出文件類型為excel文件"application/ms-excel"。 System.IO.StringWriter oStringWriter = new System.IO.StringWriter(); System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter); c.RenderControl(oHtmlTextWriter); string writeString = oStringWriter.ToString(); writeString = "<tr> <td> " + Title + " </td> <tr> " + writeString; Response.Output.Write(writeString); Response.Flush(); Response.End(); }
(2)引用Microsoft.Office.Interop.Excel.dll,這種方法我也是借鑒別人的。我給出詳細地址:http://blog.csdn.net/yysyangyangyangshan/article/details/7067370
二、導出至Word
這里講一下導出到word用到的是word中的文字編輯域工具,就是事先在word中需要導出數據的地方先用文字編輯語站好位置,之后用反射機制根據文字編輯域中的默認文字找到數據庫中同樣的字段,然后導出至Word,下面是代碼:
protected void btnPrint_Click(object sender, EventArgs e) { //2014-6-8 bob 打印證書 從數據庫中把數據導出到word lvExt.VerifySelectRowCount(Common.UserControl.ListViewExtender.SelectCountMode.OnlyOne); //獲得學員基本信息數據集 eTangent.PSMS.PSMSDataContext dc = new eTangent.PSMS.PSMSDataContext(); eTangent.PSMS.vw_PMInfor pmInfors = dc.vw_PMInfors.FirstOrDefault(p => Convert.ToInt32(p.ID).Equals(this.lvExt.SelectedValues.FirstOrDefault())); //生成證書 Application app = null; Document docTemp = null; Document doc = null; try { string docPath = string.Format("~/Contacts/CertificateDoc/{0}", pmInfors.Card); if (!System.IO.Directory.Exists(Server.MapPath(docPath))) { System.IO.Directory.CreateDirectory(Server.MapPath(docPath));//創建文件夾 } object templateName = Server.MapPath(string.Format("~/Contacts/CertificateDoc/Template.doc")); app = new Application(); //啟用進程 object nullobj = System.Reflection.Missing.Value; docTemp = app.Documents.Open(templateName); object CertificateName = Server.MapPath( string.Format("{0}/Certificate.doc", VirtualPathUtility.RemoveTrailingSlash(docPath))); docTemp.SaveAs(ref CertificateName); //把臨時doc另存為當前人的證書doc docTemp.Close(); //ref nullobj,ref nullobj,ref nullobj // GC.Collect(); //垃圾回收 docTemp = null; string docCertificateName = Server.MapPath( string.Format("{0}/Certificate.doc", VirtualPathUtility.RemoveTrailingSlash(docPath))); doc = app.Documents.Open(docCertificateName); //基本信息 foreach (FormField f in doc.FormFields.Cast<FormField>()) { if (f.Result.Equals("PrintTime")) { f.Range.Text = DateTime.Now.Date.ToShortDateString(); } else { //反射 (根據外部的doc文檔中的文字域的名字來找到數據集pmInfors中對應的屬性) // 其中數據集也可以用dataset來實現 System.Reflection.PropertyInfo propInfo = pmInfors.GetType().GetProperty(f.Result); if (propInfo != null) { object pValue = propInfo.GetValue(pmInfors, null); if (pValue != null) { f.Range.Text = pValue.ToString(); } else { f.Range.Text = string.Empty; } } else { f.Range.Text = string.Empty; } } } doc.Save(); if (docTemp != null) { docTemp.Close(); // GC.Collect(); } docTemp = null; if (doc != null) doc.Close(); doc = null; if (app != null) app.Quit(); app = null; // 下載證書 string docPrintPath = string.Format("~/Contacts/CertificateDoc/{0}//Certificate.doc", pmInfors.Card); if (File.Exists(Server.MapPath(docPrintPath))) { //btSave.PostBackUrl = docPath; Response.Redirect(docPrintPath); //注意一定要把執行該動作的按鈕設置為異步回發(如果按鈕在UpdatePanel中) } } catch (Exception ex) { System.Diagnostics.EventLog.WriteEntry("黨校系統錯誤", string.Format("打印證書發生錯誤: {0}", ex.Message)); object saveOption = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges; if (app != null) app.Quit(ref saveOption); docTemp = null; doc = null; app = null; throw new Exception(ex.Message); } } protected void btnPrint_PreRender(object sender, EventArgs e) { //將控件注冊為回發的觸發器。 //該方法用於配置 UpdatePanel 控件內以其他方式執行異步回發的回發控件。 ScriptManager sm = ScriptManager.GetCurrent(this.Page); if (sm != null) { sm.RegisterPostBackControl((Control)sender); } }
有人肯定好奇為什么我的兩個導出按鈕都要注冊為異步回發,因為我這是個項目,用到了母版頁,母版頁中的內容頁套了一個UpdatePanel,所以才這么做的。
好了,終於寫完了。肯定有很多理解不到位的地方,畢竟才剛接觸.net,望大家批評指正。不管怎么樣,希望自己能堅持走下去!