急!报表列的选择打印($200)(200分)

  • 主题发起人 主题发起人 ankeylee
  • 开始时间 开始时间
A

ankeylee

Unregistered / Unconfirmed
GUEST, unregistred user!
请教各位同仁高手:
如何实现数据库报表列的选择打印!
比如,在打印之前,对一个 DBGrid 表列进行了筛选:显示一些选择的列,或是不显示
非选择的列,而后打印出来的数据库报表就如此 DBGrid 所视的行与列。
请教,如何做到此种“所见即所得”的打印报表!
希望您能提供 demo 代码,非常感谢!
(以上 DBGrid 可以不与报表有直接关系。
但是两者必须在形式上一致,即“所见即所得”!)



 
用第三方控件吧,QuickRep 是不行的。
 
很简单,看看我以前写的代码吧:
procedure PrintDbGrid(DataSet:TDataSet;DbGrid:TDbGrid;Title:String);
var
PointX,PointY:integer;
ScreenX:integer;
i,lx,ly:integer;
px1,py1,px2,py2:integer;
RowPerPage,RowPrinted:integer;
ScaleX:Real;
THeight:integer;
TitleWidth:integer;
SumWidth:integer;
PageCount:integer;
SpaceX,SpaceY:integer;
RowCount:integer;
begin
PointX:=Round(GetDeviceCaps(printer.Handle,LOGPIXELSX)/2.54);
PointY:=Round(GetDeviceCaps(printer.Handle,LOGPIXELSY)/2.54);
ScreenX:=Round(Screen.PixelsPerInch/2.54);
ScaleX:=PointX/ScreenX;
RowPrinted:=0;
SumWidth:=0;
printer.BeginDoc;
With Printer.Canvas do
begin
DataSet.DisableControls;
DataSet.First ;
THeight:=Round(TextHeight('我')*1.5);//设定每行高度为字符高的1.5倍
SpaceY:= Round(TextHeight('我')/4);
SpaceX:=Round(TextWidth('我')/4);
RowPerpage:=Round((printer.PageHeight-5*PointY)/THeight); //上下边缘各2厘米
ly:=2*PointY;
PageCount:=0;
while not DataSet.Eof do
begin
if (RowPrinted=RowPerPage) or (RowPrinted=0) then
begin
if RowPrinted<>0 then
Printer.NewPage;
RowPrinted:=0;
PageCount:=PageCount+1;
Font.Name:='宋体';
Font.size:=16;
Font.Style:=Font.Style+[fsBold];
lx:=Round((Printer.PageWidth-TextWidth(Title))/2);
ly:=2*PointY;
TextOut(lx,ly,Title);
Font.Size:=11;
Font.Style:=Font.Style-[fsBold];
lx:=Printer.PageWidth-5*PointX;
ly:=Round(2*PointY+0.2*PointY);
if RowPerPage*PageCount>DataSet.RecordCount then
RowCount:=DataSet.RecordCount
else
RowCount:=RowPerPage*PageCount;
TextOut(lx,ly,'第'+IntToStr(RowPerPage*(PageCount-1)+1)+'-'+IntToStr(RowCount)+'条,共'+IntToStr(DataSet.RecordCount)+'条');
lx:=2*PointX;
ly:=ly+THeight*2;
py1:=ly-SpaceY;
if RowCount=DataSet.RecordCount then
py2:=py1+THeight*(RowCount-RowPerPage*(PageCount-1)+1)
else
py2:=py1+THeight*(RowPerPage+1);
SumWidth:=lx;
for i:=0 to DBGrid.Columns.Count-1 do
begin
px1:=SumWidth-SpaceX;
px2:=SumWidth;
MoveTo(px1,py1);
LineTo(px2,py2);
TitleWidth:=TextWidth(DBGrid.Columns.Title.Caption);
lx:=Round(SumWidth+(DBGrid.Columns.width*scaleX-titleWidth)/2);
TextOut(lx,ly,DBGrid.Columns.Title.Caption);
SumWidth:=Round(SumWidth+DBGrid.Columns.width*scaleX)+SpaceX*2;
end;
px1:=SumWidth; //画最后一条竖线
px2:=SumWidth;
MoveTo(px1,py1);
LineTo(px2,py2);
px1:=2*PointX; //画第一条横线
px2:=SumWidth;
py1:=ly-SpaceY;
py2:=ly-SpaceY;
MoveTo(px1,py1);
LineTo(px2,py2);
py1:=py1+THeight;
py2:=py2+THeight;
MoveTo(px1,py1);
LineTo(px2,py2);
end;
lx:=2*PointX;
ly:=ly+THeight;
px1:=lx;
px2:=SumWidth;
py1:=ly-SpaceY+THeight;
py2:=ly-SpaceY+THeight;
MoveTo(px1,py1);
LineTo(px2,py2);
for i:=0 to DBGrid.Columns.Count-1 do
begin
TextOut(lx,ly,DataSet.FieldByname(DBGrid.Columns.Fieldname).AsString);
lx:=Round(lx+DBGrid.Columns.width*ScaleX+SpaceX*2);
end;
RowPrinted:=RowPrinted+1;
DataSet.next;
end;
DataSet.first;
DataSet.EnableControls;
end;
printer.EndDoc;
end;
 
有一个控件叫PrintDBgridEh
就是所见即所得的grid打印控件!
可以 email windspray@263.net
 
有两个可以做到:
一个是Ehlib1.55和fastReprt2.4可以做到打印所见即所得。
http://www.net-wing.net/kangwei/
 
如果我没有理解错的话,您的意思是DBGRID的列和您想做的的
报表的列完全一致,并且此报表是做死的,如果这样的话,用
QIUCKREPORT可以实现,我先找找我以前作过的程序,我想应该有
稍等!
 
看看下面的例子吧!或许对你有所帮助!
procedure TS_Fee_Report.Button_previewClick(Sender: TObject);
var
tempstar1,tempend1,temptime:string;
begin
if S_Mgr_Rpt.RadioBtn_Day.checked then
temptime :='1';
if S_Mgr_Rpt.RadioBtn_Month.checked then
temptime :='30';
if S_Mgr_Rpt.RadioBtn_Select.checked then
temptime :=IntToStr( Trunc ( S_Mgr_Rpt.DateTimePicker_End.Date - S_Mgr_Rpt.DateTimePicker_Start.Date ));
tempstar1 := FormatDateTime('YYYY-MM-DD', S_Mgr_Rpt.DateTimePicker_Start.Date);
tempEnd1 := FormatDateTime('YYYY-MM-DD', S_Mgr_Rpt.DateTimePicker_End.Date);
QRLabel11.caption :=datetimetostr(S_Mgr_Rpt.DateTimePicker_Start.Datetime);
QRLabel12.caption :=datetimetostr(S_Mgr_Rpt.DateTimePicker_end.Datetime);

QuickRep1.ReportTitle :=s_mgr_rpt.Edit_Title.Text;

if S_Mgr_Rpt.ListBox_Order.Itemindex <> -1 then
case S_Mgr_Rpt.ListBox_Order.ItemIndex of
0 : begin
with query1 do begin
close;
sql.clear;
databasename := 'db';
sql.Add('SELECT GDR0502, GDD0202, SUM(GDR0503), (GDR0204*'''+temptime+'''/(GDR0203-GDR0202 + 1)) fee,SUM(GDR0503)/(GDR0204*30/(GDR0203-GDR0202 + 1))');
sql.Add('FROM ge_jc.GDR05 , ge_jc.GDR02 , ge_jc.GDD02 ');
sql.Add('where');
sql.Add(' GDR0201 = GDR0502');
sql.Add('and');
sql.Add(' GDD0201 = GDR0502');
sql.Add('and');
sql.Add('GDR0504 >= to_date(''' + tempstar1 + ''',''YYYY-MM-DD'')');
SQL.Add('and');
sql.Add('GDR0504 <= to_date(''' + tempend1 + ''',''YYYY-MM-DD'')');
sql.Add('group by');
sql.Add(' GDR0502,(GDR0203-GDR0202 + 1), GDR0204, GDD0202');
sql.add('order by');
sql.Add('sum(GDR0503)');
query1.open;
end;
if query1.RecordCount <1 then
begin
application.createform(ts_NULL,S_NULL);
S_NULL.SHOWMODAL;
end
else
QuickRep1.preview;
end;
1 : begin
with query1 do begin
close;
sql.clear;
databasename := 'db';
sql.Add('SELECT GDR0502, GDD0202, SUM(GDR0503), (GDR0204*'''+temptime+'''/(GDR0203-GDR0202 + 1)) ,SUM(GDR0503)/(GDR0204*30/(GDR0203-GDR0202 + 1))');
sql.Add('FROM GDR05 , GDR02 , GDD02 ');
sql.Add('where');
sql.Add(' GDR0201 = GDR0502');
sql.Add('and');
sql.Add(' GDD0201 = GDR0502');
sql.Add('and');
sql.Add('GDR0504 >= to_date(''' + tempstar1 + ''',''YYYY-MM-DD'')');
SQL.Add('and');
sql.Add('GDR0504 <= to_date(''' + tempend1 + ''',''YYYY-MM-DD'')');
sql.Add('group by');
sql.Add(' GDR0502,(GDR0203-GDR0202 + 1), GDR0204, GDD0202');
sql.add('order by');
sql.Add('(GDR0204*30/(GDR0203-GDR0202 + 1))');
query1.open;
end;
if query1.RecordCount <1 then
begin
application.createform(ts_NULL,S_NULL);
S_NULL.SHOWMODAL;
end
else
QuickRep1.preview;
end;
2 : begin
with query1 do begin
close;
sql.clear;
databasename := 'db';
sql.Add('SELECT GDR0502, GDD0202, SUM(GDR0503), (GDR0204*'''+temptime+'''/(GDR0203-GDR0202 + 1)) ,SUM(GDR0503)/(GDR0204*30/(GDR0203-GDR0202 + 1))');
sql.Add('FROM GDR05 , GDR02 , GDD02 ');
sql.Add('where');
sql.Add(' GDR0201 = GDR0502');
sql.Add('and');
sql.Add(' GDD0201 = GDR0502');
sql.Add('and');
sql.Add('GDR0504 >= to_date(''' + tempstar1 + ''',''YYYY-MM-DD'')');
SQL.Add('and');
sql.Add('GDR0504 <= to_date(''' + tempend1 + ''',''YYYY-MM-DD'')');
sql.Add('group by');
sql.Add(' GDR0502,(GDR0203-GDR0202 + 1), GDR0204, GDD0202');
sql.add('order by');
sql.Add('SUM(GDR0503)/(GDR0204*30/(GDR0203-GDR0202 + 1))');
query1.open;
end;
if query1.RecordCount <1 then
begin
application.createform(ts_NULL,S_NULL);
S_NULL.SHOWMODAL;
end
else
QuickRep1.preview;
end;
end//of case
else
begin
with query1 do begin
close;
sql.clear;
databasename := 'db';
sql.Add('SELECT GDR0502, GDD0202, SUM(GDR0503), (GDR0204*'''+temptime+'''/(GDR0203-GDR0202 + 1)) fee,SUM(GDR0503)/(GDR0204*30/(GDR0203-GDR0202 + 1))');
sql.Add('FROM ge_jc.GDR05 , ge_jc.GDR02 , ge_jc.GDD02 ');
sql.Add('where');
sql.Add(' GDR0201 = GDR0502');
sql.Add('and');
sql.Add(' GDD0201 = GDR0502');
sql.Add('and');
sql.Add('GDR0504 >= to_date(''' + tempstar1 + ''',''YYYY-MM-DD'')');
SQL.Add('and');
sql.Add('GDR0504 <= to_date(''' + tempend1 + ''',''YYYY-MM-DD'')');
sql.Add('group by');
sql.Add(' GDR0502,(GDR0203-GDR0202 + 1), GDR0204, GDD0202');
sql.add('order by');
sql.Add('sum(GDR0503)');
query1.open;
end;
if query1.RecordCount <1 then
begin
application.createform(ts_NULL,S_NULL);
S_NULL.SHOWMODAL;
end
else
QuickRep1.preview;
end;
end;
注:用数据库的QUERY控件把DBGRID的列用SQL语句选出来,然后设置他的一些相关属性就OK了
 
我以前是这样做的:
首先设计好所有的打印字段,在实际打印时再控制其打印与否,同时
要修正各字段的打印位置(left),只是有点繁。
procedure TxmyeForm.PrintBtnClick(Sender: TObject);
var i:integer;
w:real;
begin
dm.xmyeq.DisableControls;

bbrqLabel.Caption:='报表日期:'+trim(nianedit.Text)+'年'+trim(yueedit.text)+'月';
w:=1;
bmdmlabel.Visible:=false;
bmdmdbtext.Visible:=false;

bmmcline1.visible:=false;
bmmcline2.visible:=false;
bmmclabel.Visible:=false;
bmmcdbtext.visible:=false;

xmdmline1.visible:=false;
xmdmline2.visible:=false;
xmdmlabel.Visible:=false;
xmdmdbtext.Visible:=false;

xmmcline1.visible:=false;
xmmcline2.visible:=false;
xmmclabel.Visible:=false;
xmmcdbtext.visible:=false;

ncsline1.visible:=false;
ncsline2.visible:=false;
ncslabel.Visible:=false;
ncsdbtext.visible:=false;

qcsline1.visible:=false;
qcsline2.visible:=false;
qcslabel.Visible:=false;
qcsdbtext.visible:=false;

jjeline1.visible:=false;
jjeline2.visible:=false;
jjelabel.Visible:=false;
jjedbtext.visible:=false;

ljjline1.visible:=false;
ljjline2.visible:=false;
ljjlabel.Visible:=false;
ljjdbtext.visible:=false;

djeline1.visible:=false;
djeline2.visible:=false;
djelabel.Visible:=false;
djedbtext.visible:=false;

ljdline1.visible:=false;
ljdline2.visible:=false;
ljdlabel.Visible:=false;
ljddbtext.visible:=false;

yeline1.visible:=false;
yeline2.visible:=false;
yelabel.Visible:=false;
yedbtext.visible:=false;

leftline1.Visible:=False;
rightline1.Visible:=False;
bottomline1.Visible:=False;
hjlabel.Visible:=False;
ncsline3.Visible:=False;
ncsdbcalc.Visible:=False;
qcsline3.Visible:=False;
qcsdbcalc.Visible:=False;
jjeline3.Visible:=False;
jjedbcalc.Visible:=False;
ljjline3.Visible:=False;
ljjdbcalc.Visible:=False;
djeline3.Visible:=False;
djedbcalc.Visible:=False;
ljdline3.Visible:=False;
ljddbcalc.Visible:=False;
yeline3.Visible:=False;
yedbcalc.Visible:=False;

for i:=0 to dstlist.items.Count-1 do
begin
if dstlist.Items='部门代码' then
begin
bmdmlabel.Left:=w;
bmdmlabel.Visible:=true;
bmdmdbtext.Left:=w;
bmdmdbtext.Width:=bmdmlabel.Width;
bmdmdbtext.Visible:=true;
w:=bmdmlabel.Width+1;
end
else
if dstlist.Items='部门名称' then
begin
bmmcline1.Visible:=true;
bmmcline1.Left:=w;
bmmclabel.Left:=w+1;
bmmclabel.Visible:=true;
bmmcline2.Left:=w;
bmmcline2.Visible:=true;
bmmcDBText.Left:=w+1;
bmmcdbtext.Width:=bmmclabel.Width;
bmmcdbtext.Visible:=true;
w:=w+bmmclabel.width+1;
end
else
if dstlist.Items='项目代码' then
begin
xmdmline1.Visible:=true;
xmdmline1.Left:=w;
xmdmlabel.Left:=w+1;
xmdmlabel.Visible:=true;
xmdmline2.Left:=w;
xmdmline2.Visible:=true;
xmdmDBText.Left:=w+1;
xmdmdbtext.Width:=xmdmlabel.Width;
xmdmdbtext.Visible:=true;
w:=w+xmdmlabel.width+1;
end
else
if dstlist.Items='项目名称' then
begin
xmmcline1.Visible:=true;
xmmcline1.Left:=w;
xmmclabel.Left:=w+1;
xmmclabel.Visible:=true;
xmmcline2.Left:=w;
xmmcline2.Visible:=true;
xmmcDBText.Left:=w+1;
xmmcdbtext.Width:=xmmclabel.Width;
xmmcdbtext.Visible:=true;
w:=w+xmmclabel.width+1;
end
else
if dstlist.Items='上年结余' then
begin
ncsline1.Visible:=true;
ncsline1.Left:=w;
ncslabel.Left:=w+1;
ncslabel.Visible:=true;
ncsline2.Left:=w;
ncsline2.Visible:=true;
ncsDBText.Left:=w+1;
ncsdbtext.Width:=ncslabel.Width;
ncsdbtext.Visible:=true;
if hjchkb.Checked then
begin
ncsline3.Left:=w;
ncsline3.Visible:=true;
ncsDBcalc.Left:=w+1;
ncsdbcalc.Width:=ncslabel.Width;
ncsdbcalc.Visible:=true;
end;
w:=w+ncslabel.width+1;
end
else
if dstlist.Items='期初数' then
begin
qcsline1.Visible:=true;
qcsline1.Left:=w;
qcslabel.Left:=w+1;
qcslabel.Visible:=true;
qcsline2.Left:=w;
qcsline2.Visible:=true;
qcsDBText.Left:=w+1;
qcsdbtext.Width:=qcslabel.Width;
qcsdbtext.Visible:=true;
if hjchkb.Checked then
begin
qcsline3.Left:=w;
qcsline3.Visible:=true;
qcsDBcalc.Left:=w+1;
qcsdbcalc.Width:=ncslabel.Width;
qcsdbcalc.Visible:=true;
end;
w:=w+qcslabel.width+1;
end
else
if dstlist.Items='本期增' then
begin
jjeline1.Visible:=true;
jjeline1.Left:=w;
jjelabel.Left:=w+1;
jjelabel.Visible:=true;
jjeline2.Left:=w;
jjeline2.Visible:=true;
jjeDBText.Left:=w+1;
jjedbtext.Width:=jjelabel.Width;
jjedbtext.Visible:=true;
if hjchkb.Checked then
begin
jjeline3.Left:=w;
jjeline3.Visible:=true;
jjeDBcalc.Left:=w+1;
jjedbcalc.Width:=ncslabel.Width;
jjedbcalc.Visible:=true;
end;
w:=w+jjelabel.width+1;
end
else
if dstlist.Items='累计增' then
begin
ljjline1.Visible:=true;
ljjline1.Left:=w;
ljjlabel.Left:=w+1;
ljjlabel.Visible:=true;
ljjline2.Left:=w;
ljjline2.Visible:=true;
ljjDBText.Left:=w+1;
ljjdbtext.Width:=ljjlabel.Width;
ljjdbtext.Visible:=true;
if hjchkb.Checked then
begin
ljjline3.Left:=w;
ljjline3.Visible:=true;
ljjDBcalc.Left:=w+1;
ljjdbcalc.Width:=ncslabel.Width;
ljjdbcalc.Visible:=true;
end;
w:=w+ljjlabel.width+1;
end
else
if dstlist.Items='本期减' then
begin
djeline1.Visible:=true;
djeline1.Left:=w;
djelabel.Left:=w+1;
djelabel.Visible:=true;
djeline2.Left:=w;
djeline2.Visible:=true;
djeDBText.Left:=w+1;
djedbtext.Width:=djelabel.Width;
djedbtext.Visible:=true;
if hjchkb.Checked then
begin
djeline3.Left:=w;
djeline3.Visible:=true;
djeDBcalc.Left:=w+1;
djedbcalc.Width:=ncslabel.Width;
djedbcalc.Visible:=true;
end;
w:=w+djelabel.width+1;
end
else
if dstlist.Items='累计减' then
begin
ljdline1.Visible:=true;
ljdline1.Left:=w;
ljdlabel.Left:=w+1;
ljdlabel.Visible:=true;
ljdline2.Left:=w;
ljdline2.Visible:=true;
ljdDBText.Left:=w+1;
ljddbtext.Width:=ljdlabel.Width;
ljddbtext.Visible:=true;
if hjchkb.Checked then
begin
ljdline3.Left:=w;
ljdline3.Visible:=true;
ljdDBcalc.Left:=w+1;
ljddbcalc.Width:=ncslabel.Width;
ljddbcalc.Visible:=true;
end;
w:=w+ljdlabel.width+1;
end
else
if dstlist.Items='期末数(余额)' then
begin
yeline1.Visible:=true;
yeline1.Left:=w;
yelabel.Left:=w+1;
yelabel.Visible:=true;
yeline2.Left:=w;
yeline2.Visible:=true;
yeDBText.Left:=w+1;
yedbtext.Width:=yelabel.Width;
yedbtext.Visible:=true;
if hjchkb.Checked then
begin
yeline3.Left:=w;
yeline3.Visible:=true;
yeDBcalc.Left:=w+1;
yedbcalc.Width:=ncslabel.Width;
yedbcalc.Visible:=true;
end;
w:=w+yelabel.width+1;
end;
titleshape.Width:=w+0.25;
bottomline.Width:=w;
rightline.Left:=w;
bottomline1.Width:=w;
rightline1.Left:=w;
if hjchkb.Checked then
begin
hjlabel.Visible:=true;
leftline1.Visible:=True;
rightline1.Visible:=True;
bottomline1.Visible:=True;
end;
pagevar.Left:=w-pagevar.Width-5;
namelabel.Left:=w-namelabel.Width;
titlelabel.Left:=(w-titlelabel.Width)/2;
end;

ppReport1.print;
dm.xmyeq.EnableControls;
xmyepage.ActivePage:=jgtab;
end;
 
用QuickRep,根据DBGrid的显示动态生成报表控件(用QRLabel和QRShape就够了),
我做过一个StringGrid的所见即所得报表,因为涉及到单元格的合并,所以自定义了比较
复杂的数据结构来实现,另外报表本身还需要分组的功能,所以源码比较大,在里面
直接找到你想要的部分不太容易。我把大体思路说一下吧:

为简单起见,可以先在QuickRep上放好TitleBand,HeaderBand和DetailBand,然后每次
生成报表前先将三个Band里的所有控件Free掉。
根据选择的DBGrid列数Create出相应数量的Label(列标题文字)和Shape(格线),
QRShape的形状为qrsRectangle,宽度就是DBGrid相应的列宽,高度比DBGrid行高大1
(为了不使横线重叠),Label的大小最好是比Shape所确定矩形的尺寸小4(左右各留
2点空隙),AutoSize设为False。
同样,可以填出DetailBand的各个控件,然后关键是Detail的具体内容要在QuickRep的
OnNeedData事件里逐个填写Caption,为了DBGrid的每一列内容能和Detail中的相应列
对上,可以为Detail中的Label起名叫“QRLabelxx”其中xx就是对应的DBGrid列号。
注意根据DBGrid中需要显示的行数控制OnNeedData里的MoreData参数即可控制打印结束。
 
多人接受答案了。
 
后退
顶部