本人大学新手一枚,在大学工作室学习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,望大家批评指正。不管怎么样,希望自己能坚持走下去!