FastReport
or 
我写的:
procedure TForm_AdoQuery.PrintResult();
var
  i:Integer;
  j:Integer;
  w:Integer;
  TextHeight:Integer;
  TextWidth:Integer;
  PageMarginLeft:Integer;
  PageMarginTop:Integer;
  PageMarginRight:Integer;
  PageMarginBottom:Integer;
  PrintWidth:Integer;
  PrintHeight:Integer;
  SheetWidth:Integer;
  SheetHeight:Integer;
  SheetLines:Integer;
  FirstPageSheetLines:Integer;
  OtherPageSheetLines:Integer;
  RowHeight:Integer;
  InchPixelsX:Integer;
  InchPixelsY:Integer;
  WidthScale:Integer;
  Row:Integer;
  CurrPosX:Integer;
  CurrPosY:Integer;
  Tx,Ty:Integer;
  tmpStr:String;
  Space0,Space1,Space2:Integer;
  CurrPage:Integer;
  TotalPages:Integer;
  DataRows:Integer;
  Form_Printing : TForm_Printing;
  IsAbort:Boolean;
begin//  Form_Printing  := TForm_Printing.Create(Self);
//  Form_Printing.Show();
// 请删除关于 Form_Printing 的语句  IsAbort := false;
  PageMarginLeft :=0;        //0.001 inch
  PageMarginTop :=0;
  PageMarginRight :=0;
  PageMarginBottom :=0;  DbGrid1.BeginUpdate;
  with Printer do
  begin    BeginDoc;
    InchPixelsX := GetDeviceCaps(Canvas.Handle,LOGPIXELSX);
    InchPixelsY := GetDeviceCaps(Canvas.Handle,LOGPIXELSY);
    PrintWidth := PageWidth - ( PageMarginLeft + PageMarginRight ) * InchPixelsX div 1000;
    PrintHeight :=PageHeight - ( PageMarginTop - PageMarginBottom ) * InchPixelsY div 1000;    WidthScale := 86; //72 = Std
    Space0 := 0;
    Space1 := (InchPixelsY + 99) div 100;
    Space2 := (InchPixelsY + 12) div 13;
    CurrPage := 1;
    Row := 0;
    DataRows := AdoQuery1.RecordCount;  
            //应将AdoQuery1改为DBGrid1.DataSource.DateSet,以下同
    AdoQuery1.First;
    for j := 1 to DataRows do
      begin
        if Row = 0 then
          begin
            if j <> 1 then
              NewPage;            CurrPosY := Space0;
            Ty :=  CurrPosY ;            if j = 1 then
              begin
                //打印标题
                Canvas.Font.Size := 12;
                tmpStr := 'XXX查询结果';
                TextWidth := Canvas.TextWidth(tmpStr);
                TextHeight := Canvas.TextHeight(tmpStr);
                Tx := (PrintWidth - TextWidth) div 2;
                Ty :=  CurrPosY ;
                Canvas.TextOut(Tx,Ty,tmpStr);
                CurrPosY := CurrPosY+TextHeight;                //打印日期
                Canvas.Font.Size := 9;
                tmpStr := '打印日期:2002-04-02 操作员:Artman';
                TextWidth := Canvas.TextWidth(tmpStr);
                TextHeight := Canvas.TextHeight(tmpStr);
                Tx := (PrintWidth - TextWidth) div 2;
                Ty :=  CurrPosY+Space1;
                Canvas.TextOut(Tx,Ty,tmpStr);
                CurrPosY := CurrPosY+TextHeight;               //计算表格宽度
                Canvas.Font.Size := 10;
                w :=0;
                for i := 1 to DbGrid1.FieldCount do
                    w := w + (DbGrid1.Columns[i-1].Width * InchPixelsX) div WidthScale;
                SheetWidth := w;
                CurrPosX := (PrintWidth - SheetWidth) div 2;                Canvas.Font.Size := 9;
                //打印条件
                tmpStr := '查询条件:开户日期 从 2001-01-01 到 2002-03-03 ';
                TextHeight := Canvas.TextHeight(tmpStr);
                Tx := CurrPosX;
                Ty :=  CurrPosY + Space2 ;
                Canvas.TextOut(Tx,Ty,tmpStr);
                CurrPosY := Ty+TextHeight;                //计算表格行数                Canvas.Font.Size := 10;
                RowHeight := Canvas.TextHeight('张') + Space1 * 2;
                FirstPageSheetLines := (PrintHeight - CurrPosY - Space1 - RowHeight * 2 ) div RowHeight;                if FirstPageSheetLines >= DataRows then
                  begin
                      TotalPages := 1;
                      Form_Printing.PageNum := TotalPages;
                  end
                else
                  begin
                    OtherPageSheetLines := (PrintHeight - Space0 - Space1 - RowHeight * 2 ) div RowHeight;
                    TotalPages := (DataRows  - FirstPageSheetLines + OtherPageSheetLines - 1) div OtherPageSheetLines + 1;
                    Form_Printing.PageNum := TotalPages;
                  end;
              end;

解决方案 »

  1.   

    if j = 1 then
                  SheetLines := FirstPageSheetLines
                else
                  SheetLines := OtherPageSheetLines;            //打印标题行
                w := 0;
                Ty := CurrPosY + Space1;
                Canvas.Font.Style := [fsBold];
                for i := 1 to DbGrid1.FieldCount do
                  begin
                    Canvas.TextOut(Tx+w + Space1,Ty + Space1,DbGrid1.Columns[i -1].Title.Caption);
                    w := w + (DbGrid1.Columns[i-1].Width * InchPixelsX) div WidthScale;
                  Application.ProcessMessages;
                  if Form_Printing.IsAbort then
                    begin
                      IsAbort := true;
                      break;
                    end;
                  end;
                if Form_Printing.IsAbort then
                  begin
                    IsAbort := true;
                    break;
                  end;
                Canvas.Font.Style := [];
                Canvas.MoveTo(Tx,Ty);
                Canvas.LineTo(Tx+w,Ty);
                Canvas.MoveTo(Tx,Ty+RowHeight);
                Canvas.LineTo(Tx+w,Ty+RowHeight);
              end;          //打印明晰行
              Canvas.Font.Size := 10;
              w := 0;
              Row := Row + 1;
              for i := 1 to DbGrid1.FieldCount do
                begin
                  Canvas.TextOut(Tx+w+Space1,Ty+RowHeight*Row + Space1,DbGrid1.Fields[i -1].AsString);
                  w := w + (DbGrid1.Columns[i-1].Width * InchPixelsX) div WidthScale;
                  Application.ProcessMessages;
                  if Form_Printing.IsAbort then
                    begin
                      IsAbort := true;
                      break;
                    end;
              end;          if Form_Printing.IsAbort then
                begin
                  IsAbort := true;
                  break;
                end;          AdoQuery1.Next;          Canvas.MoveTo(Tx,Ty+RowHeight*Row);
              Canvas.LineTo(Tx+w,Ty+RowHeight*Row);
              if Row = SheetLines then
                begin
                  w :=0;
                  for i := 1 to DbGrid1.FieldCount do
                    begin
                      Canvas.MoveTo(Tx+w,Ty);
                      Canvas.LineTo(Tx+w,Ty+RowHeight*(SheetLines +1));
                      w := w + (DbGrid1.Columns[i-1].Width * Canvas.Font.PixelsPerInch) div WidthScale;
                      Application.ProcessMessages;
                      if Form_Printing.IsAbort then
                        begin
                          IsAbort := true;
                          break;
                        end;
                    end;
                    if Form_Printing.IsAbort then
                      begin
                        IsAbort := true;
                        break;
                      end;
                  Canvas.MoveTo(Tx+w,Ty);
                  Canvas.LineTo(Tx+w,Ty+RowHeight*(SheetLines +1));
                  Canvas.MoveTo(Tx,Ty+RowHeight*(SheetLines +1));
                  Canvas.LineTo(Tx+w,Ty+RowHeight*(SheetLines +1));
                   //页码
                  Canvas.Font.Size := 9;
                  tmpStr := '第 '+IntToStr(CurrPage)+' 页 共 '+IntToStr(TotalPages)+' 页';
                  TextWidth := Canvas.TextWidth(tmpstr);
                  Ty :=  Ty + RowHeight*(SheetLines + 1) + Space1   ;
                  Canvas.TextOut((PrintWidth - TextWidth) div 2,Ty,tmpStr);
                  Row :=0;
                  Form_Printing.ShowProgress(CurrPage);              CurrPage := CurrPage + 1;
                  Application.ProcessMessages;
                  If Form_Printing.IsAbort Then
                    break;
                end;
        end;
        if Row <> SheetLines then
          begin
                  w :=0;
                  for i := 1 to DbGrid1.FieldCount do
                    begin
                      Canvas.MoveTo(Tx+w,Ty);
                      Canvas.LineTo(Tx+w,Ty+RowHeight*(Row +1));
                      w := w + (DbGrid1.Columns[i-1].Width * Canvas.Font.PixelsPerInch) div WidthScale;
                      Application.ProcessMessages;
                      if Form_Printing.IsAbort then
                        begin
                          IsAbort := true;
                          break;
                        end;
                    end;
                  Canvas.MoveTo(Tx+w,Ty);
                  Canvas.LineTo(Tx+w,Ty+RowHeight*(Row +1));
                  Canvas.LineTo(Tx,Ty+RowHeight*(Row +1));
                  Canvas.LineTo(Tx+w,Ty+RowHeight*(Row +1));
                   //页码
                  tmpStr := '第 '+IntToStr(CurrPage)+' 页 共 '+IntToStr(TotalPages)+' 页';
                  TextWidth := Canvas.TextWidth(tmpstr);
                  Ty :=  Ty + RowHeight*(SheetLines + 1) + Space1   ;
                  Canvas.TextOut((PrintWidth - TextWidth) div 2,Ty,tmpStr);
                  Form_Printing.ShowProgress(CurrPage);
          end;
        EndDoc;
      end;
      DbGrid1.EndUpdate;
      Form_Printing.Hide;
      Form_Printing.Free;
    end;
      

  2.   

    两位兄台说的可行,不过要打印DBGrid控件中的内容就不行;而且不能提供打印预览。