用服务器组件解决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交叉报表问题(2)

用服务器组件解决WEB交叉报表问题——修改FastReport源码,支持内存流导出  Fast Report是一个经典的报表控件,不过其导出功能只支持导出到磁盘文件,而此项目为了避开权限的限制和出于服...
  • nhconch
  • nhconch
  • 2007年09月18日 17:33
  • 1690

Visual Studio .NET 无法创建应用程序 。问题很可能是因为本地 Web 服务器上没有安装所需的组件

打开.net1.1项目时出现“Visual Studio .NET 无法创建应用程序 。问题很可能是因为本地 Web 服务器上没有安装所需的组件“这样的错误提示。           我的机器装...
  • jjhua
  • jjhua
  • 2008年06月07日 17:26
  • 1124

一个动态交叉分片报表的几种实现方法

http://blog.runqian.com.cn/?p=1382 动态列报表在报表应用中很常见,往往由于业务的不同复杂度也差异很大。复杂的动态列报表在实现上往往十分困难,常见于数据源准备...
  • raqreport
  • raqreport
  • 2016年04月11日 17:20
  • 555

如何制作交叉报表-多层交叉

本文介绍如何制作一张交叉报表   联系电话:15050176512  Q Q 号码:136846796  平台网址:www.sdpsoft.com   一、新建数据源 二、操作步...
  • szzzzn
  • szzzzn
  • 2016年04月20日 09:51
  • 739

ASP.NET服务器控件使用之Reportviewer 报表

1.       Reportviewer 报表 1.1. Reportviewer控件 注:本教程附2个事例: l  演练:在本地处理模式下将数据库数据源与 ReportViewer We...
  • oemoon
  • oemoon
  • 2012年03月10日 08:26
  • 15793

如何利用FastReport创建交叉报表?

转自:http://www.fastreportcn.com/Article/92.html 本文我们将创建一个交叉报表,用于显示员工四年中的工资。要创建交叉报表,我们需要使用到Fa...
  • cw370008359
  • cw370008359
  • 2014年12月11日 13:24
  • 1119

用iReport制作一个简单的交叉报表

1、  打开iReport软件,【文件】——>【New】,选择一个报表模版,(以选择第一个模版为例),然后选择“Open this Template”, 如图1.1所示。进入下一个页面,填写文件...
  • liuxiyangyang
  • liuxiyangyang
  • 2012年12月24日 16:10
  • 8320

【PB】提取动态交叉报表动态标题名和动态列值

//提取动态交叉报表动态标题名和动态列值: String ls_Str, ls_Str1, ls_Name, ls_Name_Text, ls_Text Long ll_Cnt, ...
  • lijianhe043
  • lijianhe043
  • 2016年09月12日 17:52
  • 1472

Ireport交叉报表

1、构造数据源: package test; import java.util.ArrayList; public class CrossReportFactory { pu...
  • cbjcry
  • cbjcry
  • 2017年04月13日 10:27
  • 368

用Birt 制作交叉报表

1>我们先建立一个简单的数据库模型,虽然说简单,但是为了后期扩展,尽量将表设计更加细些. 但是,在本例中,我们只用到我们所关心的表.截图如下(图一目了然我就不多说了): 我们将数据库模型导出脚...
  • xiaocha2008
  • xiaocha2008
  • 2011年09月13日 16:45
  • 3534
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用服务器组件解决WEB交叉报表问题(1)
举报原因:
原因补充:

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