WEB开发网
开发学院软件开发Delphi 在Delphi中动态生成QuickReport报表 阅读

在Delphi中动态生成QuickReport报表

 2006-02-04 13:39:55 来源:WEB开发网   
核心提示:笔者在前一段使用Delphi开发数据库的工作中,用户提出了这样一个需求:要根据自己的的查询结果动态生成报表然后进行打印,在Delphi中动态生成QuickReport报表,几经摸索,笔者使用动态生成QuickReport控件的方法满足了用户的需求,是横打还是竖打 Columns:integer;//报表包含的列数 en

----笔者在前一段使用Delphi开发数据库的工作中,用户提出了这样一个需求:要根据自己的的查询结果动态生成报表然后进行打印。几经摸索,笔者使用动态生成QuickReport控件的方法满足了用户的需求。现将此方法说明如下,希望能为有类似工作要做的朋友们提供一点有益的提示。

 

一、基本思路

----先将查询的一些参数(如SQL命令,字段名称,字段宽度等)按照一定格式写入一个临时文件中。在生成报表时,根据临时文件中所记录的参数动态生成各种QuickReport控件即可。

 

二、程序实现

2.1临时文件格式

----临时文件的格式可以根据需要自定义,笔者采用了INI的文件格式。Delphi提供了一个TInifile类,使得在Delphi中操作INI格式文件,非常方便。关于INI文件的格式和具体操作相关的文章有不少,我这里不再赘述。临时文件格式如下:

Report.ini 

:报表细节

[rep_detail]

Title=XXXXX表

:打印纸设置,1为A4纸,2为B5纸,3为16K

Page=1

:打印方式,1为横打,0为竖打

Orientation=1

:报表包含的字段数目

columns=8

 

:TQurey组件信息

[QureyData]

:QuickReport组件中Tqurey组件的SQL命令的内容

Sql_command=select V_XM,V_JGZW,V_BMMC,V_DWMC,V_DWZW,V_ZY,V_ZC,V_BGDH from Hvzzjg where V_XM  LIKE '李%'

 

[col_0]

Caption=姓  名

DataFiled=V_XM

Width=60

……

……

 

2.2动态生成QuickReport报表

--- 报表的主要控件及其主要属性设置如下

控件名称

类名

属性

属性值

Form_rep

TForm

caption

动态报表

QuickRep

TQuickRep

DataSet

REP_QUERY

DetailBand1

TQRBand

BandType

rbDetail

ColumnHeaderBand1

TQRBand

BandType

rbColumnHeader

REP_DataSource

TDataSource

DataSet

Rep_Query

Rep_Query

TQuery

DatabaseName

REPDATABASE

Rep_Database

 

TDatabase

 

Connected

True

Params.Strings

'SERVER NAME=XXX

'USER MAME=XXX'

'PASSWord=XXX'

DatabaseName

REPDATABASE

上表所示控件是在程序中手工创建的。其他的控件则要在程序中动态创建。

2.2.2主要程序

unit f_rep;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, ExtCtrls, QuickRpt, QRCtrls, DB, DBTables,PRINTERS,QRPrntr,inifiles,

  TeeProcs, TeEngine, DbChart, QRTEE;

 

type

  TForm_rep = class(TForm)

   QuickRep: TQuickRep;

   DetailBand1: TQRBand;

   ColumnHeaderBand1: TQRBand;

   REP_DataSource: TDataSource;

   REP_QUERY: TQuery;

   rep_Database: TDatabase;

   procedure TForm_rep.QuickRepAfterPreview(Sender: TObject);//浏览完毕,释放所有创建的组件

  private

   { Private declarations }

  public

   { Public declarations }

  end;

 

var  Form_rep:TForm_Rep;

   type //报表的摘要信息

    C_rep_Summary=record

     Title:string;//报表的标题

     Page:TQRPaperSize;//报表的页面设置,采用何种型号的纸

     Orientation:TPrinterOrientation;//报表的页面设置,是横打还是竖打

     Columns:integer;//报表包含的列数

   end;

 

   type

     C_Rep_Col_Summary=record//报表列的摘要信息

      Caption:string;//报表的列名

      DataFiled:string;//报表的列所对应的数据库中的字段名

      Width:integer;//报表的列宽

   end;

 

   type

     C_Rep_Col_Sum_store=record //存储报表列的摘要信息

     Caption_array:array of string;

     DataFiled_array:array of string;

     Width_array:array of integer;

   end;

var 

   rep_Summary:C_rep_Summary;

   Rep_Col_Summary:C_Rep_Col_Summary;

   Rep_Col_Sum_store:C_Rep_Col_Sum_store;

   Colum_Name:array of tQRRichText;

   Colum_Data:array of TQRDBRichText;

   C_Query:TQuery;

  

 

procedure  Form_rep_init();

procedure DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);//动态创建TQRDBText控件

procedure  DynCreat_TQRRichtext(Colum_Num:integer);//动态创建TQRRichtext控件

procedure  DynCreat_TQuery(Inifile_Name:Tinifile);//动态创建TQuery控件的SQL语句

procedure  Get_PageCount();//取得打印总页数

function  Open_IniFile():Tinifile;//打开临时文件

procedure  Read_Col_Summary(Inifile_Name:Tinifile);//读取报表列的摘要信息

procedure  Read_Rep_Summary(Inifile_Name:Tinifile);//读取报表的摘要信息

function  rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//将打印方式设置进行转换

function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;//将打印页尺寸设置进行转换

 

implementation

 

{$R *.dfm}

 

function rep_chanslatepage(var Rep_Page:integer):TQRPaperSize;//将打印页类型设置进行转换

begin

   case  Rep_Page of

1:begin

      result:=A4;

      Form_rep.QuickRep.PrinterSettings.PaperSize:=A4;

     end;

    2:begin

      result:=B5;

      Form_rep.QuickRep.PrinterSettings.PaperSize:=B5

     end;

    3:begin

      result:=Executive;

      Form_rep.QuickRep.PrinterSettings.PaperSize:=Executive;

     end;

   end;

end;

 

function rep_chanslateOrientation(var Rep_Orientation:integer):TPrinterOrientation;//将打印方式设置进行转换

begin

   case  Rep_Orientation of

    0:begin

      result:=poPortrait;//0为竖直

      Form_rep.QuickRep.PrinterSettings.Orientation:=poPortrait;

      end;

    1:begin

      result:=poLandscape;//1为水平

      Form_rep.QuickRep.PrinterSettings.Orientation:=poLandscape;

     end;

   end;

end;

 

function  Open_IniFile():Tinifile;//打开临时文件

var Filename:string;

   Ini_Filename:string;

begin

   Filename:=’Report.ini’;

   Ini_Filename:=File_Path+Filename;

   Result:=Tinifile.Create(Ini_Filename);

end;

 

procedure Read_Rep_Summary(Inifile_Name:Tinifile);//读取报表的摘要信息

var  Rep_Page,Rep_Orientation:integer;

begin

   rep_Page:=Inifile_Name.Readinteger('rep_detail','Page',1);

   Rep_Orientation:=Inifile_Name.Readinteger('rep_detail','Orientation',0);

   with  rep_Summary do

   begin

    Columns:=Inifile_Name.Readinteger('rep_detail','columns',0);

    Title:=Inifile_Name.Readstring('rep_detail','Title','未命名报表');

    page:=rep_chanslatepage(Rep_Page);//将打印页尺寸进行转换

    Orientation:=rep_chanslateOrientation(Rep_Orientation);//将打印方式设置进行转换

   end;

end;

 

procedure  Read_Col_Summary(Inifile_Name:Tinifile);//读取报表列的摘要信息

var i_count:integer;

begin

   //将列信息保存在数组中

   with Rep_Col_Sum_store do

   begin

    SetLength(Caption_array,rep_Summary.Columns);

    SetLength(DataFiled_array,rep_Summary.Columns);

    SetLength(Width_array,rep_Summary.Columns);

   end;

   for i_count:=0 to rep_Summary.Columns-1 do

   begin

    with Rep_Col_Summary do

     begin

      Caption:=Inifile_Name.Readstring('col_'+inttostr(i_count),'Caption','未命名');

      DataFiled:=Inifile_Name.Readstring('col_'+inttostr(i_count),'DataFiled','');

      Width:=Inifile_Name.Readinteger('col_'+inttostr(i_count),'Width',0);

     end;

    with Rep_Col_Sum_store  do

     begin

      Caption_array[i_count]:=Rep_Col_Summary.Caption;

      DataFiled_array[i_count]:=Rep_Col_Summary.DataFiled;

      Width_array[i_count]:=Rep_Col_Summary.Width;

     end;

   end;

end;

 

procedure DynCreat_TQRRichtext(Colum_Num:integer);//动态创建TQRRichtext控件,此控件用来显示报表每列的中文名称

var Colum_Name_list:TStrings;

begin

   Colum_Name[Colum_Num]:=tQRRichtext.Create(application); //创建TQRRichtext控件

   Colum_Name[Colum_Num].Parent:=Form_rep.ColumnHeaderBand1;

   Colum_Name[Colum_Num].Frame.DrawTop:=true;

   Colum_Name[Colum_Num].Frame.DrawBottom:=true;

   Form_rep.ColumnHeaderBand1.Height:=40;

   Colum_Name[Colum_Num].Height:=40;

   Colum_Name[Colum_Num].Font.Height:=-14;

   Colum_Name[Colum_Num].Font.Name:='黑体';

   Colum_Name[Colum_Num].Top:=0;

   Colum_Name[Colum_Num].Alignment:=taCenter;

   Colum_Name[Colum_Num].AutoStretch:=false;

    //画表格线

   Colum_Name[Colum_Num].Frame.Style:=psSolid;

   Colum_Name[Colum_Num].Frame.Width:=1;

   Colum_Name[Colum_Num].Frame.DrawRight:=true;

   Colum_Name[Colum_Num].Frame.DrawBottom:=true;

   if Colum_Num=0 then

     begin

      Colum_Name[Colum_Num].Frame.DrawLeft:=true;

     end;

   //将记录RRep_Col_Sum_store中的信息赋给Colum_Name

   Colum_Name_list:=TStringList.Create;

   Colum_Name_list.Add(Rep_Col_Sum_store.Caption_array[Colum_Num]);

   Colum_Name[Colum_Num].Lines:=Colum_Name_list;

   Colum_Name[Colum_Num].Width:=Rep_Col_Sum_store.Width_array[Colum_Num];

   Colum_Name[Colum_Num].Visible:=true;

   //计算左边界

   if Colum_Num>0 then

     Colum_Name[Colum_Num].Left:=Colum_Name[Colum_Num-1].Left+Colum_Name[Colum_Num-1].Width

   else

     Colum_Name[Colum_Num].Left:=0;

end;

说明:此处采用TQRRichtext控件是因为当名称过长时,TQRRichtext控件可以自动换行。

  

procedure DynCreat_TQRDBText(Colum_Num:integer;Colum_Height:integer;DataSet_Name:TQuery);//动态创建TQRDBText控件,此控件用来显示每列的值

begin

Colum_Data[Colum_Num]:=tQRDBText.Create(application);

   Colum_Data[Colum_Num].Parent:=Form_rep.DetailBand1;

   //设置数据集

   Colum_Data[Colum_Num].DataSet:=DataSet_Name;

   //将数组Colum_Data.DateField属性设置为C_Rep_Col_Sum_store中的字段名

   Colum_Data[Colum_Num].DataField:=Rep_Col_Sum_store.DataFiled_array[Colum_Num];

   Colum_Data[Colum_Num].Width:=Rep_Col_Sum_store.Width_array[Colum_Num];

   Colum_Data[Colum_Num].Height:=Colum_Height;

   Form_rep.DetailBand1.Height:=Colum_Height;

   Colum_Data[Colum_Num].Top:=0;

   Colum_Data[Colum_Num].AutoSize:=false;

   Colum_Data[Colum_Num].AutoStretch:=false;

   Colum_Data[Colum_Num].WordWrap:=false;

   Colum_Data[Colum_Num].Visible:=true;

   //画表格线

   Colum_Data[Colum_Num].Frame.Style:=psSolid;

   Colum_Data[Colum_Num].Frame.DrawRight:=true;

   Colum_Data[Colum_Num].Frame.DrawBottom:=true;

   if Colum_Num=0 then

    Colum_Data[Colum_Num].Frame.DrawLeft:=true;

   //计算左边界

   if Colum_Num>0 then

    Colum_Data[Colum_Num].Left:=Colum_Data[Colum_Num-1].Left+Colum_Data[Colum_Num-1].Width

   else

     Colum_Data[Colum_Num].Left:=0;

end;

 

procedure DynCreat_TQuery(Inifile_Name:Tinifile);//动态设置TQuery控件的SQL语句

var

   Sql_command:string;

begin

   Flag_CreatQuery:=false;

   Sql_command:=Inifile_Name.Readstring('QureyData','Sql_Command','');

   Form_rep.REP_QUERY.Close;

   Form_rep.REP_QUERY.SQL.Clear;

   Form_rep.REP_QUERY.SQL.Append(Sql_command);

   if not Form_rep.REP_QUERY.Prepared then

    Form_rep.REP_QUERY.Prepare;

   try

    Form_rep.REP_QUERY.ExecSQL;

    Form_rep.REP_QUERY.Active:=true;

    Form_rep.REP_QUERY.AutoCalcFields:=true;

    Flag_CreatQuery:=true;

   except

    Application.MessageBox('SQL语句错误!','系统提示',MB_ICONWARNING);

    Flag_CreatQuery:=false;

   end;

end;

 

procedure Form_rep_init();

var  i_count:integer;

   Rep_IniFile:Tinifile;//

Tags:Delphi 动态 生成

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接

热点阅读
焦点图片
最新推荐
精彩阅读