本人很不喜歡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文件了。