QuickReport Delphi7完全解决方案

来源:互联网 发布:mac怎么切换大写字母 编辑:程序博客网 时间:2024/06/13 18:54

 前言
      本人很不喜欢QuickReport,因为其有太多问题,也太不灵活。但在开发过程中,还是无法避免接触到这种问题,特别是历史遗留下来的控件,几乎是不可能把那么多的报表去换成其他报表控件的。我把自己在改造一个项目中使用QuickReport的经验写出来,当然,有部分是从别的地方摘抄的,就一起整合了。
1.使用delphi自带控件。
    Delphi 7中仍然存在Quick Report,只是因为Delphi 7默认的报表工具为Rave,所以在工具条上找不到。你可以使用Components|Install Packages,然后点击Add,找到delphi7安装目录/bin目录并添加dclqrt70.bpl。
然而,自带控件是没有源码的,只要有一点不满足要求,就得每个报表进行改动,项目根本无法进行下去。所以,源码太重要了。
2.使用QuickReport 4.0 professionalfor Delphi7.
www.playicq.com上有一个带源码的版本,先去下载下来,安装。默认在Delphi安装目录的quickrpt子目录下面。
别急着使用!因为有太多问题。让我们来逐一解决下面的问题:
(1)QRDBText中文折行问题
   QRDBText中有一个属性WordWrap,本来以为这个属性一设置为True,就万事大吉了,可事与愿违,全乱了!
查了半天资料,据说3.06版曾经解决了这个问题,后来的版本却又走了回头路!我晕,但有什么办法。千辛万苦,终于在大富翁上找到一个解决办法
原文见:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=620364

第一步:
在.../Delphi7/lib目录下,找到qrctrls.dcu,删除之或改名,将.../Delphi7/quickrpt
目录下的qrctrls.pas和qrdefs.inc两个文件copy到.../Delphi7/lib目录下,然后将
qrdefs.inc中的
  //{$DEFINE VER100}
一句改为
  {$DEFINE VER100}

第二步:
然后在qrctrls.pas中找到TQRCustomLabel.FormatLines过程,将其修改如下:

procedure TQRCustomLabel.FormatLines;var  I, J : integer;  NewLine : string;  LineFinished : boolean;  HasParent : boolean;  MaxLineWidth : integer;  AAlignment: TAlignment;  function aLineWidth(Line : string) : integer;  begin    if HasParent then      result := Muldiv(Longint(ParentReport.TextWidth(Font, Line)),Zoom,100)    else      Result := Canvas.TextWidth(Line);  end;  procedure FlushLine;  begin    FFormattedLines.Add(NewLine);    NewLine := '';  end;  procedure AddWord(aWord : string);//{$ifdef ver100}  var    S: string;//{$endif}  begin    if aLineWidth(NewLine + aWord) > Width then    begin      if NewLine = '' then      begin//{$ifdef ver100}        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//          NewLine := NewLine + copy(aWord, 1, 1);//          Delete(aWord, 1, 1);//        end;//{$endif}        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}                Delete(aWord, Length(aWord), 1);        end;        NewLine := aWord;        FlushLine;        aWord := '';      end;      if not WordWrap then      begin        aWord := '';        LineFinished := true;      end;    end;    NewLine := NewLine + aWord;  end;  procedure AddLine(Line : string);  var    aPos : integer;  begin    while pos(#10, Line) > 0 do      Delete(Line, Pos(#10, Line), 1);    aPos := pos(#13, Line);    if aPos > 0 then    begin      repeat        AddLine(copy(Line, 1, aPos - 1));        Delete(Line, 1 , aPos);        aPos := pos(#13, Line);      until aPos = 0;      AddLine(Line);    end else    begin      J := 0;      NewLine := '';      LineFinished := false;      if AutoSize then      begin        NewLine := Line;        FlushLine;        LineFinished := True;      end else      begin        while (J < Length(Line)) and (Length(Line) > 0) do        begin          repeat//{$ifdef ver100}            begin              inc(J);              if Line[J] in LeadBytes then              begin                inc(J);                break;              end;            end;//{$else}//            inc(J)//{$endif}          until (Line[J] in BreakChars) or (J >= Length(Line));          AddWord(copy(Line, 1, J));          Delete(Line, 1, J);          J := 0;        end;        if not LineFinished then          FlushLine;      end;    end;  end;  procedure FormatFromCaption;  begin    AddLine(FPrintCaption);    if not UpdatingBounds and HasParent then    begin      UpdatingBounds := true;      if Height < (longint(ParentReport.TextHeight(Font, 'W') * Zoom div 100) + 1) then         Height := (longint(ParentReport.TextHeight(Font, 'W')) * Zoom div 100) + 1;      UpdatingBounds := false;    end  end;  procedure FormatFromStringList;  var    J : integer;  begin    if (FLines.Count <> 0) then    begin      if AutoSize then        FFormattedLines.Assign(FLines)      else        for J := 0 to FLines.Count - 1 do          AddLine(FLines[J]);    end else      if csDesigning in ComponentState then      begin        FCaption := Name;        FormatFromCaption;        FCaption := '';      end;  end;begin  if Parent <> nil then  begin    if assigned(FFormattedLines) then      FFormattedLines.Clear    else      FFormattedLines := TStringList.Create;    HasParent := ParentReport <> nil;    LineFinished := false;    if CaptionBased then      FormatFromCaption    else      FormatFromStringList;    if AutoSize and (not UpdatingBounds) and HasParent then    begin      MaxLineWidth := 0;      for I := 0 to FFormattedLines.Count - 1 do        if aLineWidth(FFormattedLines[I]) > MaxLineWidth then          MaxLineWidth := aLineWidth(FFormattedLines[I]);      if Frame.DrawLeft then        MaxLineWidth := MaxLineWidth + Frame.Width;      if Frame.DrawRight then        MaxLineWidth := MaxLineWidth + Frame.Width;      UpdatingBounds := true;      AAlignment := Alignment;//  {$ifdef ver110}      if UseRightToLeftAlignment then        ChangeBiDiModeAlignment(AAlignment);//  {$endif}      case AAlignment of        taCenter : Left := Left + ((Width - MaxLineWidth) div 2);        taRightJustify : Left := Left + Width - MaxLineWidth;      end;      Width := MaxLineWidth;      if (FFormattedLines.Count = 0) and (csDesigning in ComponentState) then        Height := (longint(ParentReport.TextHeight(Font, 'W')) * Zoom div 100) + 1;      if (Height < (longint(ParentReport.TextHeight(Font, 'W') * Zoom div 100) + 1)) then        Height := (longint(ParentReport.TextHeight(Font, 'W')) * Zoom div 100) + 1;      UpdatingBounds := false;    end;  end;  DoneFormat := true;end;


(2)汉化问题

QuickReport的预览框一向是很丑的,而且还是英文,安装了4.0之后一看,噢?打印预览界面变了,增加了缩略图和搜索文字的功能。如下图(这个界面是我汉化后的效果)


找到文件qrprev.dfm,想怎么汉化,就怎么汉化吧;另外QR4Const中有一些常量需要汉化








(3)给QuickRpt增加输出文件类型,以rtf为例:

constructor TQuickRep.CreateNew(AOwner : TComponent; Dummy: Integer);

var

  aaa :TQRRTFFilter;//added

begin

  inherited CreateNew(AOwner);

  Controller := TQRController.Create(self);

  Controller.ParentReport := Self;

  Controller.SelfCheck := Self;

  aaa := TQRRTFFilter.Create(Self);//added by sss 

end;


这样,在预览的时候,点击保存按钮,就可以选择保存为rtf文件了。

原创粉丝点击