.NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)

.NET导出报表一般是采用导出Excel报表的方式输出内容。而这又分为两种方式:使用Excel模板方式和使用网页输出Excel格式两种。
首先介绍简单的一种,网页输出Excel内容,这种不需要引用Excel的程序集。

    /// <summary>
    /// 报表导出辅助类
    /// </summary>
    public class ExportToExcel
    {
        字段信息        

        public ExportToExcel()
        {
        }

        /// <summary>
        /// 带参数的构造函数
        /// </summary>
        /// <param name="fileName">导出的Excel文件名</param>
        /// <param name="sourceTable">源数据DataTable</param>
        /// <param name="title">报表的抬头</param>
        public ExportToExcel(string fileName, DataTable sourceTable, string title)
        {
            this.fileName = fileName;
            this.sourceTable = sourceTable;
            this.title = title;
        }

        public void ExportReport()
        {
            if (SourceTable == null || SourceTable.Rows.Count == 0)
            {
                return;
            }

            DataGrid dataGrid = new DataGrid();
            dataGrid.DataSource = sourceTable;
            dataGrid.DataBind();

            HttpResponse Response = HttpContext.Current.Response;
            Response.Clear();
            Response.Buffer = true;
            Response.AddHeader(C_HTTP_HEADER_CONTENT, C_HTTP_ATTACHMENT + HttpUtility.UrlEncode(fileName + ".xls"));
            Response.ContentType = C_HTTP_CONTENT_TYPE_EXCEL;
            Response.ContentEncoding = Encoding.GetEncoding("gb2312");
            Response.Charset = charSet;

            StringWriter oStringWriter = new StringWriter();
            HtmlTextWriter oHtmlTextWriter = new HtmlTextWriter(oStringWriter);
            dataGrid.RenderControl(oHtmlTextWriter);

            string str = oStringWriter.ToString();
            int trPosition = str.IndexOf("<tr>", 0);
            string str1 = str.Substring(0, trPosition - 1);
            string str2 = str.Substring(trPosition, str.Length - trPosition);

            string str3 = "\r\n\t<tr>";
            str3 += "\r\n\t\t<td align=\"center\" colspan=\"" + sourceTable.Rows.Count +
                    "\" style=\"font-size:14pt;    font-weight:bolder;height:30px;\">" + title + "</td>";
            str3 += "\r\n\t</tr>";

            Response.Write(str1 + str3 + str2);
            Response.End();
        }
    }

使用时候代码如下:

        private void btnExport2_Click(object sender, EventArgs e)
        {
            DataTable table = SelectAll().Tables[0];
            ExportToExcel export = new ExportToExcel("TestExport", table, "TestExport");
            export.ExportReport();
        }

        public static DataSet SelectAll()
        {
            string sqlCommand = " Select ID, Name, Age, Man, CONVERT(CHAR(10), Birthday ,120) as Birthday from Test";

            DataSet ds = new DataSet();
            string connectionString = "Server=localhost;Database=Test;uid=sa;pwd=123456";

            SqlDataAdapter adapter = new SqlDataAdapter(sqlCommand, connectionString);
            adapter.Fill(ds);

            return ds;
        }

另外一种就是先定义好Excel模板,然后输出指定格式的内容,这些内容通过开始单元格名称定位,然后写入内容,但是这种功能比较强大,输出的Excel内容也比较整齐。
1. 首先在Web.Config中配置下
 <system.web>
   <identity impersonate="true"></identity>   
 </system.web>
2. 创建一个Excel模板文件,如下图所示,当然这个是简单的Excel模板,你可以定义很复杂
 
3. 在网站的根目录中创建一个Temp目录,给EveryOne读写权限,当然你也可以给AuthenticatedUsers
4. 辅助类代码

    /// <summary>
    /// 报表导出基类
    /// </summary>
    public abstract class BaseReport
    {
        变量及属性

        public BaseReport()
        {
            excelHelper = new ExcelHelper(false);
        }

        /// <summary>
        /// 打开Excel文件和关闭Excel
        /// </summary>        
        /// <returns>返回OK表示成功</returns>
        protected virtual bool OpenFile()
        {
            return excelHelper.OpenFile(fileName);
        }

        /// <summary>
        /// 关闭工作薄和excel文件
        /// </summary>
        protected virtual void CloseFile()
        {
            excelHelper.stopExcel();
        }

        /// <summary>
        /// 导出EXCEL文件
        /// </summary>
        protected virtual void ExportFile()
        {
            string tempFileName = HttpContext.Current.Request.PhysicalApplicationPath + @"Temp\" + sheetName.Replace(".xls", "");
            string SaveFileName = tempFileName + DateTime.Now.ToLongDateString() +
                                  DateTime.Now.ToLongTimeString().Replace(":", "-") + ".xls";
            excelHelper.SaveAsFile(SaveFileName);
            CloseFile();

            HttpResponse Response = HttpContext.Current.Response;
            Response.Clear();
            Response.Buffer = true;
            Response.AddHeader(C_HTTP_HEADER_CONTENT,
                               C_HTTP_ATTACHMENT + HttpUtility.UrlEncode(DateTime.Now.ToLongDateString() + sheetName));
            Response.ContentType = C_HTTP_CONTENT_TYPE_EXCEL;
            Response.ContentEncoding = Encoding.GetEncoding("gb2312");
            Response.Charset = CharSet;
            Response.WriteFile(SaveFileName);
            Response.Flush();
            Response.Clear();

            File.Delete(SaveFileName);
        }

        /// <summary>
        /// 填充表单数据到excel中
        /// </summary>
        /// <param name="GotoCell">定义的首个Cell名称</param>
        /// <param name="dt">数据表Datatable</param>
        protected virtual void FillCell(string GotoCell, DataTable dt)
        {
            int BeginRow = 2;
            int RowCount = dt.Rows.Count;
            Range rgFill = excelHelper.GotoCell(GotoCell);
            if (RowCount > BeginRow)
            {
                excelHelper.InsertRows(rgFill.Row + 1, RowCount - BeginRow); //从定位处的下一行的上面插入新行
            }
            //Fill
            if (RowCount > 0)
            {
                excelHelper.DataTableToExcelofObj(dt, excelHelper.IntToLetter(rgFill.Column) + rgFill.Row.ToString(), false);
            }
        }

        private void AppendTitle(string titleAppendix)
        {
            if (titleAppendix != null && titleAppendix != string.Empty)
            {
                try
                {
                    excelHelper.AppendToExcel(titleAppendix, "Title");
                }
                catch (Exception ex)
                {
                    throw new Exception("您没有指定一个Title的单元格", ex);
                }
            }
        }

        /// <summary>
        /// 写入内容
        /// </summary>
        public virtual void ExportExcelFile()
        {
            ExportExcelFile(string.Empty);
        }

        /// <summary>
        /// 写入内容并追加标题内容
        /// </summary>
        /// <param name="titleAppendix">追加在Title后面的内容(一般如年月份)</param>
        public virtual void ExportExcelFile(string titleAppendix)
        {
            try
            {
                OpenFile();
                AppendTitle(titleAppendix);
                FillFile();
                ExportFile();
            }
            catch //(Exception ex)
            {
                CloseFile();
                throw;
            }
        }


        protected virtual void FillFile()
        {
        }
    }

    /// <summary>
    ///通用的报表导出类
    /// </summary>
    /// <example>
    /// <code>
    /// DataTable dt = InitTableData(); //InitTableData为自定义获取数据表的函数
    ///    CommonExport report = new CommonExport(dt, "架空线.xls", "Start"); //Start是Excel一个单元格名称
    /// report.ExportExcelFile();
    /// </code>
    /// </example>
    public class CommonExport : BaseReport
    {
        private DataTable sourceTable;
        private string startCellName;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sourceTable">要导出的DataTable对象</param>
        /// <param name="excelFileName">相对于根目录的文件路径,如Model/Test.xls</param>
        /// <param name="startCellName">开始的单元格名称</param>
        public CommonExport(DataTable sourceTable, string excelFileName, string startCellName)
        {
            fileName = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, excelFileName);
            sheetName = Path.GetFileName(fileName);

            this.sourceTable = sourceTable;
            this.startCellName = startCellName;
        }

        /// <summary>
        /// 填写文件
        /// </summary>
        protected override void FillFile()
        {
            FillCell(startCellName, sourceTable);
        }

    /// <summary>
    /// Excel帮助类
    /// </summary>
    internal class ExcelHelper : IDisposable
    {
        一般的属性变量

        打开工作薄变量

        关闭工作薄变量

        /// <summary>
        /// 当前工作薄
        /// </summary>
        public Workbook CurrentExcelWorkBook
        {
            get { return excelWorkbook; }
            set { excelWorkbook = value; }
        }

        /// <summary>
        /// 释放对象内存,推出进程
        /// </summary>
        /// <param name="obj"></param>
        private void NAR(object obj)
        {
            try
            {
                Marshal.ReleaseComObject(obj);
            }
            catch
            {
            }
            finally
            {
                obj = null;
            }
        }


        public ExcelHelper()
        {
            StartExcel();
        }

        /// <summary>
        /// 确定Excel打开是否可见
        /// </summary>
        /// <param name="visible">true为可见</param>
        public ExcelHelper(bool visible)
        {
            m_app_visible = visible;
            StartExcel();
        }

        /// <summary>
        /// 开始Excel应用程序
        /// </summary>
        private void StartExcel()
        {
            if (excelApp == null)
            {
                excelApp = new ApplicationClass();
            }

            // Excel是否可见
            excelApp.Visible = m_app_visible;
        }

        public void Dispose()
        {
            stopExcel();
            GC.SuppressFinalize(this);
        }

        
        打开、保存、关闭Excel文件        

        windows窗口,workbook工作薄,worksheet工作区操作

        行列操作        
    }

本文转自博客园伍华聪的博客,原文链接:.NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版),如需转载请自行联系原博主。

时间: 2024-10-27 21:03:34

.NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)的相关文章

.NET开发不可不知、不可不用的辅助类(二)

序列化及反序列化的辅助类SerializeUtil     /// <summary>    /// 序列化及反序列化的辅助类    /// </summary>    public sealed class SerializeUtil    {        private SerializeUtil()        {        }        序列化操作函数        反序列化操作函数        /// <summary>        /// 获

.NET开发不可不知、不可不用的辅助类(一)

1. 用于获取或设置Web.config/*.exe.config中节点数据的辅助类     /// <summary>    /// 用于获取或设置Web.config/*.exe.config中节点数据的辅助类    /// </summary>    public sealed class AppConfig    {        private string filePath;        /// <summary>        /// 从当前目录中按顺序

IOS开发:Unity3D游戏引擎之构建框架与导出项目

  首先先去Unity3D官网 http://unity3d.com/,我们可以看到很多关于Unity3D的消息.点击DownLoad开始下载Unity,下载的时候建议不要使用Safari自带的下载工具,因为不支持断点续传,国外网站不稳定.建议使用迅雷去下载.目前最新的版本是Unity 3.4.1 ,完美支持Xcode 4 . 开发:Unity3D游戏引擎之构建框架与导出项目-"> 下载完成后,进入Unity.首次须要走注册流程,这里说一下Unity 3D的购买许可为1500美刀,如果要部

循序渐进开发WinForm项目(5)--Excel数据的导入导出操作

随笔背景:在很多时候,很多入门不久的朋友都会问我:我是从其他语言转到C#开发的,有没有一些基础性的资料给我们学习学习呢,你的框架感觉一下太大了,希望有个循序渐进的教程或者视频来学习就好了. 其实也许我们每天面对的太多东西了,觉得很多都稀松平常了,即使很细微的地方,可能我们都已经形成习惯了.反过来,如果我们切换到其他领域,如IOS.android,那么开始我们可能对里面很多设计的规则不甚了解,开始可能也是一头雾水. 本篇继续上一篇<循序渐进开发WinForm项目(4)--Winform界面模块的集

web开发设计人员不可不用的在线web工具和应用

大家可能还记得在过去的文章我们我们曾经介绍我们收集的前端开发人员必备的工具,脚本和资源,在今天的这篇文章中,我们将继续推荐给大家一组我们精挑细选的web开发设计必备的在线工具应用.相信会在web开发和设计的过程中给你带来方便和快捷! 前端开发相关 jsfiddle jsfiddle是老牌的在线调试和分享代码的网站,它可以帮助你在线调试javascript/css/html代码, 并且方便的发布到社区,论坛或者社交媒体上与朋友们分享或者提问.整合了很多的不同的类库供大家选择. 类似的工具还有jsb

大家作开发的时候用不用myeclipse 中的UML?

问题描述 今天早上一直在看UML,但是感觉这个插件似乎和myeclipse结合的不是很好.生成某些方法不如在代码里直接操作方便,代码反向生成UML效果似乎也不尽人意,好多依赖关系都显示把出来...似乎仅仅做个架构图看看还成,靠它写程序似乎太累了.... 解决方案 解决方案二:用过,但没像你这么试过.开发的时候肯定是不会用这个的了.解决方案三:几乎就是没用过.解决方案四:UML是鸡肋啊基本都是用来写文档的

Ruby on rails开发从头来(windows)(三十二)- Rails的配置文件

Rails的运行时配置是由config目录下的文件来控制的. 1.运行时环境(Runtime environment) 当开发者编写代码时,需求是多中多样的.在开发中你可能会需要很多的登录,加载变化过的代码.在测试时,你需要各个系统之间是隔离开的.在发布之前,你可能需要进行性能优化,并且时用户远离bug. 为了支持这一切,Rials有运行时配置的概念.每一个环境都拥有自己的一组配置,可以在不同的环境中运行同一个应用程序. 切换运行环境可以使我们不用修改代码就可以从开发切换到测试再切换到发布.怎样

Ruby on rails开发从头来(windows)(三十)- NetBeans IDE

到现在,应该告一段落了,总共有二十九篇随笔,干脆凑个整数,再写写IDE环境吧.前面所有的代码都是我用ruby自带的编辑器SciTE编写的,很不方便,随着Rails的发展,目前也有很多IDE推出来,刚刚看到NetBeans推出的6.0rc版,提供了单独的Rails开发环境,这次来简单尝试下. 1.第一步当然是下载NetBeans的6.0rc版,在http://sunmicro.vo.llnwd.net/c1/netbeans/6.0/final/下载. 2.下载后一路默认安装,完成后启动NetBe

Ruby on rails开发从头来(windows)(三)-实现页面间的跳转

在上篇随笔Ruby on rails开发从头来(windows)(二)-创建项目和第一个Hello world 中,我们介绍了如何使用InstantRails创建一个项目和编写一个简单的Helloworld页面,今天在上次的基础上,写一个简单的页面跳转. 1.将appcontrollers目录下的say_controller.rb文件的内容改成下面这样: class SayController < ApplicationController def Hello @time = Time.now