打印中一些问题的解决方法 (taogou) 以下quickrpt版本都为3.6
关于自动折行 需求:将超过长度的文本自动折行 解决方法:根据DELPHI的判断函数来控制超过长度文本的取舍,其实它本身有判断并截取中文字符的功能, 但是只取了第一行,所以就没有折行的效果。 源码:文件 QRCtrls;函数 FormatLines;子函数AddWord
procedure AddWord(aWord : string); {$ifdef ver100} var S: string; {$endif} begin while aLineWidth(NewLine + aWord) > Width do //字符长度超过指定长度 begin if NewLine = '''''''' then begin {$ifdef ver100} //版本控制 似乎只分了{$ifdef VER36} 和这个。 if SysLocale.FarEast then begin while true do 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)) < Width do begin NewLine := NewLine + copy(aWord, 1, 1); Delete(aWord, 1, 1); end; {$else} while aLineWidth(NewLine + copy(aWord, 1, 1)) <= Width do 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) > Width do {$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 CanPrint do if (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint then begin PrintLine(FCurrentLine); inc(FCurrentLine); end; 修改为 while (FCurrentLine <= FFormattedLines.Count - 1) and CanPrint do //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 MoreData do 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-1 do begin if FDetail.Controls[j] is TQRDBText then TQRDBText(FDetail.Controls[j]).Enabled:=False; if FDetail.Controls[j] is TQRLabel then &n
[1] [2] 下一页 [Sql Server]Sql精妙语句--各种求值函数 [网页制作]网页表格之---多个表格纵向排列 [网页制作]JavaScript另类用法--读取和写入cookie [网页制作]号称非常安全的上网工具---360安全浏览器介绍 [办公软件]信息技术教学篇---Word工具栏的显示、隐藏及四种菜… [操作系统]开始菜单---运行命令大总结 [操作系统]网络转载---64位操作系统与32位的区别 [操作系统]ldap:///(没有响应)Windows无法访问指定设备、路径… [网络技术]安全篇---交换机设置方法介绍 [聊天工具]Real10 & Xpdf installation on Linux Box
|