用服务器组件解决WEB交叉报表问题(1)

原创 2007年09月18日 17:32:00

web开发最麻烦的是做报表,特别是交叉报表。要将查询得到的看起来平淡无奇的数据展开成复杂的报表不知要费煞多少周张。下次维护时看到冗长的SQL语句或长达数页的程序代码,都有种快要晕厥的感觉。

最近,这种好事又让我碰上。公司因为费用统计的需要,要开发一份各分公司之间调货量的统计表,如下图所示。表中坚向为分公司帐套名称(调出方),横向为帐套中的客户名称(调入方),这是一份典型的交叉报表。
[调货表]

制作这份报表有两个难点:
一、每一个分公司帐套对应数据库服务器上一个数据库,并分别存放在两台以上的数据库服务器中,因此报表数据必须跨服务器查询得到。
二、将查询得到的数据展开。

如果直接用SQL语句来完成这查询和数据展开显得太复杂,而且效率会很低。如果只通过SQL语句来查询数据则会简单很多,撇开安全问题不考虑,完全可以用SQL Server提供的Open系列函数来完成。展开数据如果通过代码来完成,实在是一件很痛苦的事情,每当这时候我就会想起C/S开发中的报表控件,遗憾的是公司并没有购买任何的WEB报表控件,只好自己来打制一个了。{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-10
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}


说话间,我就拿出了我的看家宝贝:Delphi+Fast Report2.5(很久没用了一直没更新),东西虽旧但好用。首先,创建一个ActiveX Library和Active Server Object。

然后在TLB是添加ShowCrossReport方法,参数如下,其中:ConStr为数据库的连接字符串,Command为SQL查询语句,ReportFile是FastReport报表模板,通过它生成最终报表。

接着编写ShowCrossReport的代码。
{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-10
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com

  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}

function TkktWebCrossReport.ShowCrossReport(const ConStr, Command,
  ReportFile: WideString): Integer;
var
    ADOQ: TADOQuery;
    //frdb: TfrDBDataSet;
    rpt: TfrReport;
    st: TMemoryStream;
    ex: TfrHTML2Export;
    buf: String;
    e: TComponent;
begin
    e := TComponent.Create(nil);
    try
    ADOQ := TADOQuery.Create(e);
    try try
        //生成查询控件并查询数据
        ADOQ.Name := 'ADOQ';
        ADOQ.ConnectionString := ConStr;
        ADOQ.SQL.Add(Command);
        ADOQ.Open;
        {frdb := TfrDBDataSet.Create(nil); //Fast Report 2.5的交叉报表控件可以直接读取ADODataSet数据
        frdb.Name := 'frdb';
        frdb.DataSet := ADOQ;}
        st := TMemoryStream.Create;  //报表生成后会导出到内在流中
        //载入报表模板{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-10
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com
  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}


        rpt := TfrReport.Create(e);
        rpt.Name := 'frReport1';
        //rpt.Dataset := frdb;
        rpt.LoadFromFile(ReportFile);
        rpt.ShowProgress := false;
        rpt.PrepareReport;
        st.Position := 0;
        //创建导出控件,FastReport有TfrHTMExport和TfrHTML2Export两个导出到HTML格式的控件,TfrHTMExport以表格方式导出,默认没有表格线,且存在数据错位的问题,TfrHTML2Export以CSS格式导出,能完好的显示表格线,我采用后者。
        ex := TfrHTML2Export.Create(e);
        ex.Navigator.Align := haLeft;
        ex.ShowDialog := false;
        //这是重点,将结果导出到内存流并送到客户端
        //导出到内存流的好处是不用在服务器生成中间文件,不用考虑权限和安全问题
        //FastReport没有ExportToStream函数,是我加的,见后面说明
        rpt.ExportToStream(ex, st);
 
        st.Position := 0;
        SetLength(buf, st.Size);
        st.Read(buf[1], st.Size);
        Response.Write(buf);
        st.Clear;
    except on E: Exception do
        Response.Write('<font color=red><b><h2>'+E.Message+'</h2></b></font>');
    end;
    finally

        if ex <> nil then FreeAndNil(ex);
        if st <> nil then FreeAndNil(st);
        if rpt <> nil then FreeAndNil(rpt);
        //if frdb <> nil then frdb.Free;
        FreeAndNil(ADOQ);
    end;
    finally

        e.Free;
    end;
end;

最后,翻译项目得到Dll文件,拷贝到服务器上并注册。服务器组件就完成了。

接着,来段演示代码。
先创建一个报表模板,并保存到服务器上,命名为rpt1.frf
{========================================================================
  DESIGN BY :  彭国辉
  DATE:        2007-09-10
  SITE:       
http://kacarton.yeah.net/
  BLOG:        http://blog.csdn.net/nhconch
  EMAIL:       kacarton[A T]sohu.com  文章为作者原创,转载请注明文章出处、保留作者信息,谢谢支持!
=========================================================================}


然后是调用代码(ASP.NET):
'通过ParseSQL生成SQL查询语句


Private Sub ShowReport()
    Dim Cmd As String = ParseSQL()
    If Cmd <> "" Then
        Dim CrossReport = Server.CreateObject("CrossReport.kktWebCrossReport")
        CrossReport.ShowCrossReport(clsSQL.DefaultConStr, Cmd, Page.MapPath(".") + "/rpt1.frf")
        CrossReport = Nothing
    End If
End Sub

 下一篇:用服务器组件解决WEB交叉报表问题(2)——修改FastReport源码,支持内存流导出。

 

关于“Web 创作组件” 解决MS Office 2007找不到Office.zh-cn问题以及VS2008 SP1 安装失败需指定visualwebdeveloperww.msi所在路径

2010-08-01 01:00 by elivsit, 4071 visits, 网摘, 收藏, 编辑其实就是将visualstudio2008中文版.iso打开,然后把WCU/WebDesigne...

JFreeChart基于Java Web的报表组件的使用以及解决乱码

JFreeChart的简介在此就不赘述,主要讲解如何使用JFreeChart创建各种图表,这些图表包括:饼图、柱状图 ( 普通柱状图以及堆栈柱状图 )、线图、区域图、分布图、混合图、甘特图以及一些仪表...

一个Web报表项目的性能分析和优化实践(二):MySQL数据库连接不够用(TooManyConnections)问题的一次分析和解决案例

MySQL数据库连接不够用(TooManyConnections)问题的一次分析和解决案例

交叉报表列头排序时遇到的oracle问题—oracle ORA-12704:字符集不匹配、varchar2转化为nvarchar2字符缺失、case when else后的字符类型要一致

在做交叉报表列头的排序时,遇到这三个问题,下面具体来说一下。 设计的数据库的表结构如图1所示: 图1 要处出来student_name_,s.grade_,s.subject_name_,这...

web打印组件康虎云报表与odoo整合示例

康虎云报表是最好用的web打印组件之一,而Odoo(前身为OpenERP)则是最好的开源ERP,把康虎云报表与odoo整合,实现odoo报表精准输出,复杂报表快速开发,这个任务我筹划很久了,也已经拖了...
  • wdmsyf
  • wdmsyf
  • 2017年06月06日 00:26
  • 1119

WEB打印组件包解决web打印问题

  • 2009年02月01日 18:54
  • 73KB
  • 下载

推荐几款.NET下的报表组件(1) - FastReport .NET

www.commuch.cn FastReport可能对它最熟悉可能还是Delphi程序员了,几乎没有程序员不知道这款VCL组件的。前几年这个俄罗斯软件公司Fast Reports Inc.公司重写...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用服务器组件解决WEB交叉报表问题(1)
举报原因:
原因补充:

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