打印 TDBGrid

发布于 2024-12-05 23:51:46 字数 92 浏览 1 评论 0原文

如何在不安装或下载组件的情况下打印 DBGrid?

或者

如何将 DBGrid 的数据放入 RichEdit 中,以便我可以从那里打印它?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

女中豪杰 2024-12-12 23:51:46

数据感知控件从 DataSource 属性获取数据,并使用它。不过,您必须手动遍历它,不可能立即完成(没有第三方库/组件)。

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).

您需要能够为每个字段计算出适当的打印宽度,大致如下:

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;

然后循环遍历所有记录,并循环遍历每个字段进行打印。

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 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.

笑红尘 2024-12-12 23:51:46

您可以循环进入网格并手动将其全部放入您的 Richedit 中。
但为什么要重新发明轮子呢?只需使用报告组件即可。
在 delphi 7 - delphi2010 上,您已经安装了 rave 组件。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文