This question already has an answer here:
- Printing a TDBGrid 4 answers
How can I print a DBGrid without installing or downloading components?
OR
How can I get a DBGrid's data into a RichEdit so that I can print it from there?
Data aware controls get their data from DataSource property, use that. You have to manually traverse it though, no instant way possible (without third party libraries / components).
You will need to be able to work out an appropriate print width for each field, something along these lines:
function PrintFieldWidth(Field: TField): Integer;
var
CharWidth: Integer; // an average character width
TitleWidth: Integer; // the width of the field title
FieldWidth: Integer; // the width of the field content
begin
CharWidth := Printer.Canvas.TextWidth('0');
TitleWidth := Printer.Canvas.TextWidth(Field.DisplayName);
FieldWidth := Field.DisplayWidth*CharWidth;
if TitleWidth > FieldWidth then
Result := TitleWidth+CharWidth
else
Result := FieldWidth+CharWidth;
end;
Then loop through all the records, and loop through each field to print.
procedure PrintText(S: String; X, Y, W, H: Integer);
begin
Printer.Canvas.TextRect(Rect(X,Y,X+W,Y+H),S);
end;
procedure PrintHeader(DataSet: TDataSet; X, Y, H: Integer);
var
I: Integer; // record loop
W: Integer; // field width
begin
for I := 0 to DataSet.FieldCount-1 do
begin
if DataSet.Fields[I].Visible then
begin
W := PrintFieldWidth(DataSet.Fields[I]);
PrintText(DataSet.Fields[I].FieldName, X, Y, W, H);
X := X + W;
end;
end;
end;
procedure PrintRecord(DataSet: TDataSet; X, Y, H: Integer);
var
I: Integer; // record loop
W: Integer; // field width
begin
for I := 0 to DataSet.FieldCount-1 do
begin
if DataSet.Fields[I].Visible then
begin
W := PrintFieldWidth(DataSet.Fields[I]);
PrintText(DataSet.Fields[I].AsString, X, Y, W, H);
X := X + W;
end;
end;
end;
procedure PrintDataSet(DataSet: TDataSet; X, Y: Integer);
var
OldPos: TBookmark;
H: Integer; // line height
begin
if DataSet <> nil then
begin
H := Printer.Canvas.TextHeight('0');
SaveAfterScroll := DataSet.AfterScroll;
DataSet.AfterScroll := nil;
try
DataSet.DisableControls;
OldPos := DataSet.GetBookmark;
DataSet.First;
PrintHeader(DataSet, X, Y, H);
Y := Y + H * 2;
while not DataSet.Eof do
begin
PrintRecord(DataSet, X, Y, H);
Y := Y + H;
DataSet.Next;
end;
DataSet.GotoBookmark(OldPos);
DataSet.FreeBookmark(OldPos);
finally
DataSet.AfterScroll := SaveAfterScroll;
DataSet.EnableControls;
end; // try
end;
end;
You'll need to add some code to handle page breaks.
You can loop into your grid and put it all into your richedit manually. But why reinvent the wheel. Just use a report component. On delphi 7 - delphi2010 you have the rave components installed.
来源:https://stackoverflow.com/questions/7496813/print-a-tdbgrid