在最后一页上补充足够的空行?(200分)

  • 主题发起人 主题发起人 louchanghong
  • 开始时间 开始时间
L

louchanghong

Unregistered / Unconfirmed
GUEST, unregistred user!
我要每页打印10行,当数据一共有88行时,前8页上每 页有10行,最后一页上有8行,我想
再补充上2行空行,如何做呢?
 
看看FAST REPORT的DEMO或用REPORT MACHINE
 
在哪一个DEMO里啊?
 
选中FastReport或ReportMachine中的两遍报表。

 
两遍报表 我已选中,可以有总页数,但补充空行不行啊。
如果DEMO里有谁能告诉我在哪个DEMO里啊??
 
看这
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1749405
 
用FAST REPORT的怎么办啊?
 
print empty line有这个demo的呀!
 
to louchanghong
报表专家ReportExpert2。0控件下载地址:
http://www.smartparter.com/download/ReportExpert20.zip
这个很好的
 
打印中一些问题的解决方法 (taogou)
以下quickrpt版本都为3.6

关于自动折行
需求:将超过长度的文本自动折行
解决方法:根据DELPHI的判断函数来控制超过长度文本的取舍,其实它本身有判断并截取中文字符的功能,
但是只取了第一行,所以就没有折行的效果。
源码:文件 QRCtrls;函数 FormatLines;子函数AddWord
procedure AddWord(aWord : string);
{$ifdef ver100}
var
S: string;
{$endif}
begin
while aLineWidth(NewLine + aWord) > Widthdo
//字符长度超过指定长度
begin
if NewLine = '' then
begin
{$ifdef ver100} //版本控制 似乎只分了{$ifdef VER36} 和这个。
if SysLocale.FarEast then
begin
while truedo
begin
if (aWord[1] in LeadBytes) and (Length(aWord) > 1) then

S := copy(aWord, 1, 2)
else
S := copy(aWord, 1, 1);
if aLineWidth(NewLine + S) < Width then
begin
NewLine := NewLine + S;
Delete(aWord, 1, Length(S));
end
else
Break;
end;
end
else
while aLineWidth(NewLine + copy(aWord, 1, 1)) < Widthdo
begin
NewLine := NewLine + copy(aWord, 1, 1);
Delete(aWord, 1, 1);
end;
{$else
}
while aLineWidth(NewLine + copy(aWord, 1, 1)) <= Widthdo
begin
if ByteType(aWord, Length(aWord)) = mbTrailByte then
//如果是是双字节字符,则截两位
//如果截的是双字节字符而长度恰好又超过了指定长度,
//系统默认将指定长度扩展一位。如果不愿意,当然这里也可以自己再加入控制
begin

NewLine:=NewLine +copy(aWord,1,2);

Delete(aWord, 1, 2);
end else
begin
NewLine := NewLine + copy(aWord, 1, 1);
Delete(aWord, 1, 1);
end;
end;
{$endif}
//taogou aWord := '';
//该句的赋值就将导致不能换行
end;
FlushLine;
//将截取的指定长度的字符加入到字符串列表中
{ if aLineWidth(aWord) > Width then

begin
if NewLine = '' then
begin
if Width = 0 then
aWord := ''
else
while aLineWidth(aWord) > Widthdo
{$ifdef ver100}
{ if ByteType(aWord, Length(aWord)) = mbTrailByte then
Delete(aWord, Length(aWord)-1, 2)
else
}
//{$endif}
{ begin
Delete(aWord, Length(aWord), 1);
end;
end;
NewLine := aWord;
FlushLine;
aWord := '';
end;
}
if not WordWrap then
begin
aWord := '';
LineFinished := true;
end;
end;
NewLine := NewLine + aWord;
end;

关于自动折行所引起的页行数可变控制
需求:文本折行后,是已设格式的行高自动变化,行数不容易控制,预览效果不堪入目。
解决方法:不允许已设行高自动变化,根据detail行高取舍文本的行数。例:不折行的情况下打印5行的固定
格式,会因为折行而打不了5行,程序自动将行高增大,在套打的情况下,情况非常糟糕。所以强制固定行高,
如果折行超过了固定高度,则超出部分不打印。
源码:文件 QRCtrls;主函数 PrintToCanvas;子函数CanPrint
找到下面着一行
TQRCustomBand(Parent).ExpandBand(LineHeight, AFExpanded, HasExpanded);

该行是根据你的CAPTION的行数来增加行数的,所以屏蔽掉
在主函数中找到下面这一行
ControlBottom := aTop + aHeight +1;
修改为
ControlBottom := aTop + TQRCustomBand(Parent).size.Length +1;
TQRCustomBand(Parent).size.Length 是当前DETAIL的行高
然后找到下面这个循环
while (FCurrentLine <= FFormattedLines.Count - 1) and CanPrintdo

if (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint then
begin
PrintLine(FCurrentLine);
inc(FCurrentLine);
end;
修改为
while (FCurrentLine <= FFormattedLines.Count - 1) and CanPrintdo
//taogou
if (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint then
begin
if Y + LineHeight < ControlBottom then
//taogou Y为当前开始打印的位置,lineHeight为字符行高
PrintLine(FCurrentLine);
//controlbottom为detail的下限位置,仅当位置小于允许的位置才打印
inc(FCurrentLine);
end;
FCurrentLine:=FFormattedLines.Count;
//不管打了几行,都将当前行表示为该caption已经打印完毕

需求:控制多余行数,例:页打印行数为5行,当前打印记录数为12,带格式不套打,
则在最后页只有2行数据,从第3行到页脚为一片空白。这里需要将最后一页上3行打印上无数据的空格式.
解决方法:循环N次detail行的打印方法,并屏蔽掉记录
源码:文件 QuickRpt;主函数 TQRController.Execute

HasPrintedLines:=0;
//新增本函数局部变量 记录已经打印的行数
while MoreDatado
begin
inc(HasPrintedLines);
//增1
Application.ProcessMessages;
if ParentReport.QRPrinter.Cancelled then
Exit;
if ParentReport.PreparingDesignTime and (ParentReport.FPageCount > 1) then
Exit;
inc(FDetailNumber);
PrintGroupHeaders;
PrintBeforeControllers;
ParentReport.PrintBand(FDetail);
PrintAfterControllers;
if DSOK then
begin
DataSet.Next;
MoreData := not FDataSet.Eof;
if (FDataSet.Eof) then
//Add begin
begin
if FDetail<>nil then
//将detail中的TQRDBText and TQRLabel 全部不打
for j:=0 to FDetail.ControlCount-1do
begin
if FDetail.Controls[j] is TQRDBText then
TQRDBText(FDetail.Controls[j]).Enabled:=False;
if FDetail.Controls[j] is TQRLabel then
TQRLabel(FDetail.Controls[j]).Caption:='';
end;
for j:=1 to FPageMaxLines*ParentReport.PageNumber-HasPrintedLines do

// FPageMaxLines 页最大打印行数,外部传进来的变量
//ParentReport.PageNumber 总共打印的页数,因为只对最后一页进行控制,
//所以当前的打印页数已经确定,可以直接取
begin

Application.ProcessMessages;
//begin
1
if ParentReport.QRPrinter.Cancelled then
Exit;
PrintGroupHeaders;
PrintBeforeControllers;
if assigned(FDetail) then
FDetail.MakeSpace;
NotifyClients(qrMasterDataAdvance);
ParentReport.PrintBand(FDetail);

PrintAfterControllers;
//end 1
//从begin
1到这里的函数是直接COPY自2.0版本上的打印(此处应该有更加好的解决方法,
//偶只是懒了一下,:) ) 其实这段用在2.0中也是没有问题DI
end;
//Add end
end
end else
begin
MoreData := false;
if assigned(FOnNeedDataEvent) and not (csDesigning in ComponentState) then
OnNeedData(SelfCheck, MoreData);
end;
if CheckGroups then
begin
if DSOK then
DataSet.Prior;
PrintGroupFooters;
if DSOK then
DataSet.Next;
end;
if ParentReport is TQuickRep and
DSOK and (TQuickRep(ParentReport).DataSet = DataSet) and (RecCount <> 0) then
ParentReport.QRPrinter.Progress := (Longint(DetailNumber) * 100) div RecCount;
end;

注:第一次写这样的东东和大家共享,感觉有点力不从心。原因?太明显了,1、不知道格式该怎么定义
2、不知道怎么写注解 3、我的文笔又很懒 4、不知道MM是否在想我呢???:)
OK,本次东东就东到这里,同志们,好东西拿出来共享吧
 
自动增加空行都不行的吗?
 
这是个很普遍的问题,我也搞了好久了,到现在也没搞出来,上面的程序是从CSDN上拷贝过来的,可仍然无法运行,这网上已经有很多人提出这个问题了,可到现在也没有谁给出个满意的答复!我也在急切关注中!
 
unit Uorderdetail_orderprint;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, QuickRpt, QRCtrls, ExtCtrls, DB, ADODB,printers;
const max=8;leng=25;
type
Torderdetail_orderprint = class(TForm)
ADOQuery1: TADOQuery;
ADOQuery2: TADOQuery;
QuickRep1: TQuickRep;
DetailBand1: TQRBand;
QRLabel1: TQRLabel;
QRLabel2: TQRLabel;
QRLabel3: TQRLabel;
QRLabel4: TQRLabel;
xh1: TQRLabel;
xh2: TQRLabel;
xh3: TQRLabel;
xh4: TQRLabel;
xh5: TQRLabel;
xh6: TQRLabel;
xh7: TQRLabel;
xh8: TQRLabel;
proname1: TQRLabel;
proname2: TQRLabel;
proname3: TQRLabel;
proname4: TQRLabel;
proname5: TQRLabel;
proname6: TQRLabel;
proname7: TQRLabel;
proname8: TQRLabel;
spec5: TQRLabel;
spec6: TQRLabel;
spec7: TQRLabel;
spec4: TQRLabel;
spec1: TQRLabel;
spec2: TQRLabel;
spec3: TQRLabel;
spec8: TQRLabel;
type1: TQRLabel;
type2: TQRLabel;
type3: TQRLabel;
type4: TQRLabel;
type5: TQRLabel;
type6: TQRLabel;
type7: TQRLabel;
type8: TQRLabel;
num1: TQRLabel;
num2: TQRLabel;
num3: TQRLabel;
num4: TQRLabel;
num5: TQRLabel;
num6: TQRLabel;
num7: TQRLabel;
num8: TQRLabel;
unit1: TQRLabel;
unit2: TQRLabel;
unit3: TQRLabel;
unit4: TQRLabel;
unit5: TQRLabel;
unit6: TQRLabel;
unit7: TQRLabel;
unit8: TQRLabel;
price1: TQRLabel;
price2: TQRLabel;
price3: TQRLabel;
price4: TQRLabel;
price5: TQRLabel;
price6: TQRLabel;
price7: TQRLabel;
price8: TQRLabel;
money1: TQRLabel;
money2: TQRLabel;
money3: TQRLabel;
money4: TQRLabel;
money5: TQRLabel;
money6: TQRLabel;
money7: TQRLabel;
money8: TQRLabel;
QRLabel5: TQRLabel;
QRLabel6: TQRLabel;
QRLabel7: TQRLabel;
QRLabel8: TQRLabel;
count1: TQRLabel;
count2: TQRLabel;
count3: TQRLabel;
count4: TQRLabel;
count5: TQRLabel;
PageHeaderBand1: TQRBand;
procedure QuickRep1BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
procedure QuickRep1NeedData(Sender: TObject;
var MoreData: Boolean);
private
{ Private declarations }
procedure Notvisible();
procedure Getdata();

public
{ Public declarations }
flag:integer;
end;

var
orderdetail_orderprint: Torderdetail_orderprint;
ids,i,j,k,l,h,h1,pagenum:integer;
s,childstring:string;
ifnew,Ifhaschild:boolean;
implementation
uses ubasedm, publicfunction, uprinter;
{$R *.dfm}
procedure Torderdetail_orderprint.Notvisible();
var i:integer;
begin
for i :=1 to maxdo
begin
If self.FindComponent('xh'+inttostr(i)) is Tqrlabel then
TQRlabel(self.FindComponent('xh'+inttostr(i))).caption:='';
If self.FindComponent('proname'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('proname'+inttostr(i))).Caption :='';
If self.FindComponent('spec'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('spec'+inttostr(i))).Caption :='';
If self.FindComponent('type'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('type'+inttostr(i))).Caption :='';
If self.FindComponent('num'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('num'+inttostr(i))).Caption :='';
If self.FindComponent('unit'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('unit'+inttostr(i))).Caption :='';
If self.FindComponent('price'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('price'+inttostr(i))).Caption :='';
If self.FindComponent('money'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('money'+inttostr(i))).Caption :='';
If self.FindComponent('count'+inttostr(i)) is Tqrlabel then
Tqrlabel(self.FindComponent('count'+inttostr(i))).Caption :='';
end;

end;

procedure Torderdetail_orderprint.Getdata();
var i:integer;
s:string;
begin
i:=1;
While I<=maxdo
begin
If adoquery2.Eof then
begin
ifhaschild:=False;
exit;
end;
If ifhaschild and (i=1) then
begin
While trim(Childstring)<>''do
begin
Tqrlabel(self.FindComponent('spec'+inttostr(i))).Caption :=copy(childstring,1,leng);
I:=I+1;
childstring:=copy(childstring,leng+1,length(childstring));
end;

adoquery2.Next;
ifhaschild:=false;
ids:=ids+1;
continue;

end;

Tqrlabel(self.FindComponent('xh'+inttostr(i))).Caption :=inttostr(ids);
Tqrlabel(self.FindComponent('proname'+inttostr(i))).Caption :=adoquery2.fieldbyname('proname').AsString;
Tqrlabel(self.FindComponent('type'+inttostr(i))).Caption :=trim(adoquery2.fieldbyname('type').AsString);
Tqrlabel(self.FindComponent('num'+inttostr(i))).Caption :=Getpointnum(trim(adoquery2.fieldbyname('num').AsString));
Tqrlabel(self.FindComponent('unit'+inttostr(i))).Caption :=trim(adoquery2.fieldbyname('unit').AsString);
Tqrlabel(self.FindComponent('price'+inttostr(i))).Caption :=Getpointnum(trim(adoquery2.fieldbyname('price').AsString));
Tqrlabel(self.FindComponent('money'+inttostr(i))).Caption :=Getpointnumlen(trim(adoquery2.fieldbyname('money').AsString),0);
s :=trim(adoquery2.fieldbyname('spec').AsString);
j:=length(s);
k:=(j div leng)+1;
l:=j mod leng;
If l=0 then
k:=k+1;
for l:=1 to kdo
begin
Tqrlabel(self.FindComponent('spec'+inttostr(i))).Caption :=copy(s,(l-1) *leng+1,leng);
i:=i+1;
If (i>max) then
begin
childstring:=copy(s,l*leng+1,j);
If trim(childstring)<>'' then
begin
Ifhaschild:=True;
exit;
end;
end;
end;
ids:=ids+1;
adoquery2.Next;
ifhaschild:=false;
end;
end;
procedure Torderdetail_orderprint.QuickRep1BeforePrint(
Sender: TCustomQuickRep;
var PrintReport: Boolean);
begin
If Not adoquery1.Active then
adoquery1.Open;
adoquery1.First;
ifnew:=True;
end;

procedure Torderdetail_orderprint.QuickRep1NeedData(Sender: TObject;
var MoreData: Boolean);
var begin
num,endnum,countnum:integer;
begin
Moredata:=True;
If adoquery1.Eof then
begin
moredata:=false;
Exit;
end;

qrlabel1.Caption :=adoquery1.fieldbyname('clientname').AsString;
qrlabel3.Caption :=copy(Gettaiwandate(),1,2)+' '+copy(Gettaiwandate(),4,2)+' '+copy(Gettaiwandate(),7,2);
qrlabel2.Caption :=adoquery1.fieldbyname('outno').AsString;
qrlabel5.Caption :=adoquery1.fieldbyname('phone').AsString;
If trim(adoquery1.FieldByName('getidea').AsString) ='0' then
qrlabel6.Caption :='送達'
else
If trim(adoquery1.FieldByName('getidea').AsString) ='1' then
qrlabel6.Caption :='自取'
else
If trim(adoquery1.FieldByName('getidea').AsString) ='2' then
qrlabel6.Caption :='貨運'
else
If trim(adoquery1.FieldByName('getidea').AsString) ='3' then
qrlabel6.Caption :='其他';
qrlabel7.Caption :=adoquery1.fieldbyname('addr1').AsString;
qrlabel8.Caption :=adoquery1.fieldbyname('workname').AsString;

If ifnew then
begin
ids:=1;
adoquery2.Close;
adoquery2.SQL.Text :=' select outno,proname,spec,type,num,unit,price,countnum as money from x_outdetail '
+' where outno='''+adoquery1.fieldbyname('outno').AsString+''' and ifcheck=1 ';
adoquery2.Open;
adoquery2.First;
pagenum:=1;
end;

begin
num:=ids;
Notvisible;
Getdata;
// endnum:=ids-1;
Queryopen(' select sum (case when len(spec) % '+inttostr(leng)+'=0 then
len(spec)/'+inttostr(leng)+' when len(spec) % '+inttostr(leng)+'<>0 then
len(spec)/'+inttostr(leng)+'+1 end) as cols from x_outdetail where outno='''+adoquery1.fieldbyname('outno').AsString+''' and ifcheck=1');
// Queryopen(' select count(*) from x_outdetail where outno='''+adoquery1.fieldbyname('outno').AsString+''' and ifcheck=1');
countnum:=basedm.sharequery.Fields[0].AsInteger;
if (countnum mod 8)=0 then
endnum:=countnum div 8;
If (countnum mod 8)<>0 then
endnum:=(countnum div 8) +1;
// If endnum>countnum then
endnum:=countnum;
qrlabel4.Caption :=inttostr(pagenum) +' / '+inttostr(endnum);

If adoquery2.Eof then
begin
Queryopen(' select isnull(countnum1,0),isnull(feemoney,0),isnull(countnum2,0),isnull(endnum,0),isnull(notendnum,0) from x_outwork where outno='''+trim(adoquery1.fieldbyname('outno').AsString)+''' ');
count1.Caption :=getpointnumlen(basedm.sharequery.Fields[0].AsString,0);
count2.Caption :=getpointnumlen(basedm.sharequery.Fields[1].AsString,0);
count3.Caption :=getpointnumlen(basedm.sharequery.Fields[2].AsString,0);
count4.Caption :=getpointnumlen(basedm.sharequery.Fields[3].AsString,0);
count5.Caption :=getpointnumlen(basedm.sharequery.Fields[4].AsString,0);
adoquery1.Next;
ifnew:=true;
end
else
if Not adoquery2.Eof then
ifnew:=false;

pagenum:=pagenum+1;
end;
end.
 
把数据导入到一个临时表,然后记录数不足10的倍数插入空行
 
如果你用fastreport做报表,可以按如下方法:
1、增加一主项脚,设置visible=false
2、设置主项脚的onbeforeprint方法,
begin
while freespace>30(指页边距,有总结部分时,要加上总结栏的高度) do
showband(child1)(child1指子项名)
3、增加一栏子(child),画上相应的空表格。
细从表也如此,只是把主项脚改为细项脚。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1094717
 
我加了一个child1设置visible=true,
一个mast foot band visible=false onbeforeprint (begin
while freespace>child1.heightdo
showband(child1)
end)
但是不行啊
谁能给我用fastreport做一个报表方案,用dbdemos数据库做一个演示,先谢了!!
 
忙了留邮箱louchanghong@163.com
 
多人接受答案了。
 
后退
顶部