谈谈asp.net项目中对Excel报表的使用心得

原创 2004年08月17日 14:31:00
最近处理完一个asp.net项目,其中有大量的报表需要操作。客户是一个开发区的财政局和企业。因此,这些报表都是财务报表。(做过报表的朋友们肯定知道报表中最复杂的就是财务报表,且不说是典型的中国式报表,更是分组报表、交叉报表、三维汇总报表等等。)如果采用常用的报表工具,比如:水晶报表、如意报表等等比较流行的WEB报表,几十份报表如果还搞不晕你的话,绝对会将宝贵的项目时间浪费在报表界面的绘制上面。

       我们的客户群体有个特点,计算机操作水平一般般,但是一般对Excel的操作比较熟练,对报表的输出形式或者表现形式要求不大,但是报表的格式一定要符合他们日常的工作方式。因为他们的工作如果说有一个工具软件必不可少的话,那就是MS Office(非国产的那些)。他们对Excel中的各种排版、样式几乎是了如指掌。如果你拿水晶报表或者如意报表之类的辛辛苦苦绘制的报表到他们跟前,他们肯定会拿你的辛苦杰作和他的电脑中的Excel文件甚至是Word文件进行对比,很有可能就会将你的报表指的头破血淋,因为他们的参考标准就是他们自己的Office文档。我相信,现在还没有一种报表工具做出来的报表可以和ExcelWord的灵活性进行比较(也许有些做报表的公司不服气了,别争了,呵呵!),因为Word或者Excel根本就不是报表工具而是办公软件!

       经过对以上情况的分析,我决定在项目中采取Excel报表(严格的说Excel并不是报表工具,正如上所述)。同时采用样表的方式。这也是我在本文中最想提到的一点。为什么要采用样表呢?我们对Excel的掌握程度没有我们的客户研究的那么仔细,他们是专家(奉承的话,别告密哦,^_^)。他们也许对报表的表现要求五彩斑斓,但是没有关系,交给我一份样表吧!(给我一份样表,我就可以撑起整个需求,仿自伽利略,^_^)告诉我那个单元格填写什么,记住别再变的太多(要不我也没有办法,如果内容也经常变化的,不使用这种方法阿,事前申明!),其他的格式,线条,字体,颜色,合并,你愿意怎么变就怎么变!表单的内容照常进行数据库操作,添加、修改和删除均填写正常的表单,当然表单的格式没有必要和Excel的表单完全一样(要是一样也够累的),存放到你制定的数据库表中(可以修改,如果没有这个必要可以跳过这里以及后面会涉及到的地方)。在需要生成报表的地方,从数据库中提取相应的内容,打开样表,一个萝卜一个坑,填空吧,哈哈!竟是如此地简单。居然可以做出要多么漂亮有多么漂亮的表格,呵呵!

       最后的报表要显示给用户看或者是要预览怎么办,直接让他去下载Excel文件吧,哈哈!(这样,用户看到的是他自己设计或者想要的Excel文件!八路的!好的!)

光说不做那行!以下是项目的实际例子!

1.既然是Excel报表,要引用Excel组件,位置如下:E:/Program Files/Microsoft Office/Office/EXCEL9.OLB

2.ReportExcelData.cs文件是专么用来处理Excel报表的自定义类,30多个方法,4000多行代码。

using System;

using System.Data;

using System.Data.SqlClient;

using System.IO;

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

namespace wjk.ZHKCGA

{

       /// <summary>

       /// 专门处理Excel报表文件的类

       /// by wjk

       /// </summary>

       public class ReportExcelData

       {

              private DBHelper myDBHelper=new DBHelper();

              private Function myFunc=new Function();

              private ApproveData myApprove=new ApproveData();

              DBHelper.strctSqlParam[] myParam1 = new DBHelper.strctSqlParam[1];

 

              string strSQL;

              int ret,iCount;

              Excel.ApplicationClass myApp;

              Excel.Workbook myBook;

              Excel.Worksheet mySheet;

 

              public ReportExcelData()

              {

                     //

                     // TODO: 在此处添加构造函数逻辑

                     //

              }

              /// <summary>

              /// 财政基建资金拨款申请表

              /// </summary>

              /// <param name="id">材料编号</param>

              /// <param name="strPath">临时文件路径</param>

              /// <param name="strUser">创建临时文件的用户</param>

              /// <returns>-1样表不存在;1成功;0失败</returns>

              public int WriteExcel_JJ_BoKuan(int id,string strPath,string strUniteCode,string strReportName,out string strErr)

              {

                     strErr="";

 

                     #region 样表文件

                     string strSampleName="[样表]基建资金拨款申请表";

                     string strSampleFile=strPath+"File//样表//"+strSampleName+".xls";                

                     string strReportFile=strPath+"File//报表//"+strUniteCode+"//"+strReportName+".xls";                   

                     string strReportFileDB="//File//报表//"+strUniteCode+"//"+strReportName+".xls";

 

                     if(!File.Exists(strSampleFile))

                     {

                            strErr="样表不存在";

                            return -1;

                     }

                     Directory.CreateDirectory(strPath+"File//报表//"+strUniteCode);      

                     if(File.Exists(strReportFile))

                            File.Delete(strReportFile);

                     File.Copy(strSampleFile,strReportFile);

                     #endregion

 

                     #region 写文件

                     myApp=null;

                     myBook=null;

                     mySheet=null;

 

                     object oMissiong=System.Reflection.Missing.Value;

                     myApp=new Excel.ApplicationClass();

                     myApp.Visible=false;

                    

                     myApp.Workbooks.Open(strReportFile,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong,oMissiong);

                     myBook=myApp.Workbooks[1];

                     mySheet=(Excel.Worksheet)myBook.ActiveSheet;

 

                     #region 一个萝卜一个坑

                     DataSet mySet;

                     strSQL="select 项目名称,项目计划总投资,年度计划投资,合同造价,财政已拨资金,项目单位财务支出,"+

                            "项目单位资金结余,计划投资财政未拨数,项目单位本次申请拨款,财政部门拟定拨款,财政部门核定拨款,"+

                            "备注,请款单位说明,请款单位签名,请款单位日期,请款单位负责人,财务负责人,项目负责人,联系电话 "+

                            "from 基建_基建资金拨款申请表 where 材料编号="+id+" order by 序号";

                     ret=myDBHelper.RunSQLReturnDataSet(strSQL,out mySet,out iCount,out strErr);

                     if(ret==0) return 0;

                     //if(iCount<1) return -1;

                     int iRow=7;               //初始行号

                     for(int i=0;i<iCount;i++)

                     {

                            #region 写单元格

                            mySheet.Cells[iRow+i,1]=mySet.Tables[0].Rows[i][0].ToString();

                            mySheet.Cells[iRow+i,2]=mySet.Tables[0].Rows[i][1].ToString();

                            mySheet.Cells[iRow+i,3]=mySet.Tables[0].Rows[i][2].ToString();

                            mySheet.Cells[iRow+i,4]=mySet.Tables[0].Rows[i][3].ToString();

                            mySheet.Cells[iRow+i,5]=mySet.Tables[0].Rows[i][4].ToString();

                            mySheet.Cells[iRow+i,6]=mySet.Tables[0].Rows[i][5].ToString();

                            mySheet.Cells[iRow+i,7]=mySet.Tables[0].Rows[i][6].ToString();

                            mySheet.Cells[iRow+i,8]=mySet.Tables[0].Rows[i][7].ToString();

                            mySheet.Cells[iRow+i,9]=mySet.Tables[0].Rows[i][8].ToString();

                            mySheet.Cells[iRow+i,10]=mySet.Tables[0].Rows[i][9].ToString();

                            mySheet.Cells[iRow+i,11]=mySet.Tables[0].Rows[i][10].ToString();

                            mySheet.Cells[iRow+i,12]=mySet.Tables[0].Rows[i][11].ToString();

                            #endregion

                     }

                     if(iCount>0)

                     {

                            mySheet.Cells[16,9]=mySet.Tables[0].Rows[0][12].ToString();

                            mySheet.Cells[17,10]=mySet.Tables[0].Rows[0][13].ToString();

                            mySheet.Cells[17,12]=mySet.Tables[0].Rows[0][14].ToString();

                            mySheet.Cells[19,2]=mySet.Tables[0].Rows[0][15].ToString();

                            mySheet.Cells[19,5]=mySet.Tables[0].Rows[0][16].ToString();

                            mySheet.Cells[19,8]=mySet.Tables[0].Rows[0][17].ToString();

                            mySheet.Cells[19,11]=mySet.Tables[0].Rows[0][18].ToString();

                     }

 

                     mySet.Dispose();

                    

                     #region 合计内容

                     strSQL="select sum(项目计划总投资),sum(年度计划投资),sum(合同造价),"+

                            "sum(财政已拨资金),sum(项目单位财务支出),sum(项目单位资金结余),"+

                            "sum(计划投资财政未拨数),sum(项目单位本次申请拨款),sum(财政部门拟定拨款),"+

                            "sum(财政部门核定拨款) "+

                            " from 基建_基建资金拨款申请表 where 材料编号="+id;

                     ret=myDBHelper.RunSQLReturnDataSet(strSQL,out mySet,out iCount,out strErr);

                     if(ret==0) return 0;

                    

                     iRow=13;      //初始行号

                     for(int i=0;i<iCount;i++)

                     {

                            #region 具体参数

                            mySheet.Cells[iRow+i,2]=mySet.Tables[0].Rows[i][0].ToString();

                            mySheet.Cells[iRow+i,3]=mySet.Tables[0].Rows[i][1].ToString();

                            mySheet.Cells[iRow+i,4]=mySet.Tables[0].Rows[i][2].ToString();

                            mySheet.Cells[iRow+i,5]=mySet.Tables[0].Rows[i][3].ToString();

                            mySheet.Cells[iRow+i,6]=mySet.Tables[0].Rows[i][4].ToString();

                            mySheet.Cells[iRow+i,7]=mySet.Tables[0].Rows[i][5].ToString();

                            mySheet.Cells[iRow+i,8]=mySet.Tables[0].Rows[i][6].ToString();

                            mySheet.Cells[iRow+i,9]=mySet.Tables[0].Rows[i][7].ToString();

                            mySheet.Cells[iRow+i,10]=mySet.Tables[0].Rows[i][8].ToString();

                            mySheet.Cells[iRow+i,11]=mySet.Tables[0].Rows[i][9].ToString();

                            #endregion

                     }

                     #endregion                   

                     #endregion

 

                     myBook.Save();;

                     myBook.Close( true,strReportFile,true);

                     //myApp.Quit();

                     System.Runtime.InteropServices.Marshal.ReleaseComObject(mySheet);

                     System.Runtime.InteropServices.Marshal.ReleaseComObject(myBook);

                     System.Runtime.InteropServices.Marshal.ReleaseComObject(myApp);

                     GC.Collect();

                     #endregion

                     #region 写数据库

                     string strDate=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                     strSQL="update 附件表 set 路径='"+strReportFileDB+"',类型='.xls',日期='"+strDate+"',操作者='"+strUniteCode+"' where 序号="+id;

                     return myDBHelper.RunSQL(strSQL,out strErr);

                     #endregion

              }

/*以下省去30个类似的操作例子*/

}

3.Excel2000Excel2002Excel的引用对象是不一样的,一个是EXCEL9.OLB;另一个是EXCEL10.OLB;分别到相应的目录下去引用即可!同时,Excel2000Excel2002下面的参数是不一样的。Excel2000下面的参数少一个,将oMissiong干掉一个就OK(这么简单阿!)。

4.操作Excel的时候,可能会发生Excel进程被锁定,无法退出,解决方法是在保存完并关闭myBook(工作簿)后,别关闭Excel进程(//myApp.Quit();)。这样的结果是服务器上始终有一个Excel的进程。但也无所谓,比起开始nExcel进程好多了!(试过好多网友提供的方法,几乎没有好用的,呵呵)

5.可能会出现asp_net用户操作Excel的权限不够,配置Dcom。运行Dcomcnfg.exe,找到Excel应用程序,配置其属性,身份验证级别选“无”,身份标识选“交互式用户”,安全性页面,启动和访问均给everyone。注意:查看当前进程中是否有Winword进程存在,如果有且不能被结束,那么重启动计算机。再次运行你的代码即OK。这样以后就不会出现权限不够的情况了。

asp.net 使用NPOI实现导出Excel功能

asp.net 使用NPOI实现导出Excel功能
  • LanMangFeiGe
  • LanMangFeiGe
  • 2017年04月27日 13:53
  • 2401

谈谈这一年来做项目的经历(2)

谈谈这一年做项目的经历
  • a2399717
  • a2399717
  • 2016年08月12日 10:29
  • 217

项目开发经验分享—分页查询

从今天开始,我将和大家分享一下最近经手项目的开发经验。今天我们分享的内容是:分页查询! 引言:     大家在浏览网页的时候,肯定遇到过这样的效果,一个滚动条套另一个滚动条,上下拉动,看着非常不方便,...
  • small_baby01
  • small_baby01
  • 2015年01月31日 16:33
  • 1757

如何在ASP.NET项目里面正确使用Linq to Sql

老久不上来写技术类的东西了,偶尔回归一下吧。(其实,这篇文章8个月前写了个大半,后来一直没有时间去完善,再后来就因为各种原因给放下来了。) 非常抱歉,由于需要发表其他文章的缘故,我只能忍着不修正文中...
  • yl_99
  • yl_99
  • 2015年01月04日 16:27
  • 633

excel C# 报表制作汇总

1. 单击“添加引用”对话框的“COM”选项卡,找到“Microsoft Excel 11 Object Library”,按“确定”。 注意:Microsoft Excel 11 Object L...
  • zzy7075
  • zzy7075
  • 2016年08月03日 10:23
  • 1090

javaweb 利用POI生成excel报表 相关代码

采用Spring mvc架构:  Controller层代码如下 @Controller public class StudentExportController{ ...
  • sdzhangshulong
  • sdzhangshulong
  • 2016年06月16日 10:16
  • 1332

BIRT报表工具安装和集成到现有项目中详解

1.首先从官网下载BIRT http://www.eclipse.org/birt/   (不要忘记下载运行时包:Latest BIRT Runtime Release Build) 2.ecli...
  • u013010822
  • u013010822
  • 2015年04月28日 15:44
  • 1512

为什么我的项目中要使用Redis

转自:http://www.cnblogs.com/runningsmallguo/p/5871412.html 我知道有些地方没说到位,希望大神们提出来,我会吸取教训,大家共同进步! ...
  • sinat_30474567
  • sinat_30474567
  • 2017年06月08日 14:56
  • 3044

SpringAOP在项目中的简单应用

 SpringAOP在项目中的简单应用 一、前言 项目背景 由于公司的机房到期,需要做应用迁移(包括数据库),割接到云平台。但是又不能进行一次性割接,需要分三个阶段:第一阶段割...
  • keyingbo2008
  • keyingbo2008
  • 2014年04月03日 21:47
  • 3890

在项目中使用springmvc

什么是springmvcspringmvc是spring框架的一个模块,springmvc和spring无需通过中间整个层进行整合,它是一个基于mvc的web框架。springmvc与struts2的...
  • jinzili777
  • jinzili777
  • 2016年04月09日 08:36
  • 1296
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:谈谈asp.net项目中对Excel报表的使用心得
举报原因:
原因补充:

(最多只允许输入30个字)