Link to home
Start Free TrialLog in
Avatar of mrod0
mrod0

asked on

Print a stringgrid

Hello, I wounder how I do to dump a stringgrid to the printer the easiest way. Can someone please tell me how to do? I use Delphi 5. Answer quick, this question is worth lots to me!
Avatar of SuperSy
SuperSy
Flag of United States of America image

Can you put it on a temporary form and print it out?  I am assuming you just want to print out a stringgrid.
Avatar of Epsylon
Epsylon

You can also use a QRImage on a QuickReport. Use a TQuickRep, a TQRBand and a TQRImage. The TQRImage must be in the TQRBand.


procedure TForm1.Button1Click(Sender: TObject);
begin
  QRImage1.Canvas.CopyRect(StringGrid1.ClientRect, StringGrid1.Canvas, StringGrid1.ClientRect);
  QuickRep1.Preview;
//  QuickRep1.Print;
end;
quick and simple

    with Printer do
    begin
      BeginDoc;
      StringGrid1.PaintTo(Handle, 10, 10)
      EndDoc;
    end; // with
can't guarantee it will work, because I can't test it until I get to work tomorrow, but give it a try supposedly it should work...
Avatar of kretzschmar
procedure PrintGrid(sGrid: TStringGrid; sTitle: String);
var
 X1, X2 : Integer;
 Y1, Y2 : Integer;
 TmpI   : Integer;
 F      : Integer;
 TR     : TRect;
begin
 Printer.Title:=sTitle;
 Printer.BeginDoc;
 Printer.Canvas.Pen.Color:=0;
 Printer.Canvas.Font.Name:='Times New Roman';
 Printer.Canvas.Font.Size:=12;
 Printer.Canvas.Font.Style:=[fsBold, fsUnderline];
 Printer.Canvas.TextOut(0, 100, Printer.Title);
 For F:=1 to sGrid.ColCount-1 do begin
   X1:=0;
   For TmpI:=1 to (F-1) do
     X1:=X1+5*(sGrid.ColWidths[TmpI]);
   Y1:=300;
   X2:=0;
   For TmpI:=1 to F do
     X2:=X2+5*(sGrid.ColWidths[TmpI]);
   Y2:=450;
   TR:=Rect(X1, Y1, X2-30, Y2);
   Printer.Canvas.Font.Style:=[fsBold];
   Printer.Canvas.Font.Size:=7;
   Printer.Canvas.TextRect(TR, X1+50, 350, sGrid.Cells[F, 0]);
   Printer.Canvas.Font.Style:=[];
   For TmpI:=1 to sGrid.RowCount-1 do begin
     Y1:=150*TmpI+300;
     Y2:=150*(TmpI+1)+300;
     TR:=Rect(X1, Y1, X2-30, Y2);
     Printer.Canvas.TextRect(TR, X1+50, Y1+50, sGrid.Cells[F, TmpI]);
   end;
 end;
 Printer.EndDoc;
end;
Or you could use something like TAdvStringGrid which supports printing (you can download it from DSP (http://sunsite.icm.edu.pl/delphi).

Cheers,

Raymond.
Here is some more code that may help you out. PaintTo works but you would have to do more than what I had said. This will work bettter.

procedure Grid.DrawToCanvas(ACanvas: TCanvas; Mode: TPrintMode; FromRow, ToRow: Integer);
var
  PageWidth, PageHeight, PageRow,PageCol,I, iRow, FromCol,ToCol, X,Y: Integer;
  DoPaint,haslogo: Boolean;
  Hheader,Hfooter:integer;
  logopic,logopics:TBitmap;

  function ScaleX(I:Integer): Integer;
  begin
    if Mode = pmPreview then
      Result := I
    else
      Result :=round( I * (GetDeviceCaps(Printer.Handle, LOGPIXELSX) / Screen.PixelsPerInch));
  end;
  function ScaleY(I:Integer): Integer;
  begin
    if Mode = pmPreview then
      Result := I
    else
      Result := round(I * (GetDeviceCaps(Printer.Handle, LOGPIXELSY) / Screen.PixelsPerInch));
  end;

  procedure DrawCells(iRow:Integer);
  var
    iCol,I: Integer;
    R: TRect;
    drs:string;
    nr:boolean;
    v:extended;
  begin
//Alignment must be done another day
    for iCol := FromCol to ToCol do
    begin
     if ColWidths[iCol]<>0 then begin
      //X Offset
      X := scaleX(printoptions.marginleft);
      for I := FromCol to iCol-1 do
        Inc(X, ScaleX(ColWidths[I]+1));
      //Text Rect
      R := Rect(X,Y, X+ScaleX(ColWidths[iCol]), Y+ScaleY(RowHeights[iRow]));
      //Draw on the Canvas
      if DoPaint then begin
        if PrintOptions.BorderStyle =bssingle then begin
          Acanvas.brush.Style :=bsclear;
          Acanvas.Rectangle (r.left,r.top,r.right+ScaleX(2),r.bottom+scaleY(1));
          end;
        drs:=Cells[iCol, iRow];
        nr:=false;
        if FShowValues then
         if drs<>'' then
          if drs[1]='=' then begin
           drs:=format(FNumberFormat,[FCellValues[icol,irow]]);
           if NumbersalRight then nr:=true;
           end;
        if ((irow=0)and(icol>0)) then
         Acanvas.font.style:=Acanvas.Font.style+[fsbold]
         else
         Acanvas.font.style:=Acanvas.Font.style-[fsbold];
        R.left:=R.left+scaleX(PrintOptions.Leftpadding);
        if (FWordWrap and (iCol<>0) and (iRow<>0)) then begin
        if (NumbersalRight and (not nr))then
          try
            v:=strtofloat(drs);
            nr:=true;
            drs:=format(FNumberFormat,[v]);
            except
            // do nothing
            end;
         if nr then
          DrawText(Acanvas.handle,pchar(drs),-1,R,DT_WORDBREAK or DT_RIGHT)
          else
          DrawText(Acanvas.handle,pchar(drs),-1,R,DT_WORDBREAK or DT_LEFT)
         end
         else begin
          if (NumbersalRight and (not nr)) then
          try
            v:=strtofloat(drs);
            nr:=true;
            drs:=format(FNumberFormat,[v]);
            except
            // do nothing
            end;
          if nr then
            DrawText(Acanvas.handle,pchar(drs),-1,R,DT_SINGLELINE or DT_RIGHT)
            else
            DrawText(Acanvas.handle,pchar(drs),-1,R,DT_SINGLELINE or DT_LEFT)
          end;
        end;
     end;
    end;
  Inc(Y, ScaleY(RowHeights[iRow]));
  end;

  procedure DrawTitle; //draw Header and Footer
  var
    S,fstr: String;
    flist:tstringlist;
    fcnt,i:integer;
    tmpfont:tfont;//I have no idea why you can't use gettextwidth when acanvas = printer.canvas, it returns wrong value
  begin
    if DoPaint then
      begin
      ACanvas.Font.Size := FprintOptions.HeaderSize ;
      tmpfont:=font;
      canvas.font := acanvas.font;
      end;
    //Title
    Y := ScaleY(PrintOptions.MarginTop);
    S := PrintOptions.PageTitle;
    HHeader:=canvas.textheight(s);
    if haslogo then if logopic.Height >HHeader then HHeader:=logopic.height;
    if DoPaint then begin
      if haslogo then begin
       Acanvas.Draw(scaleX(printoptions.marginleft),Y,logopics);
       end;
      ACanvas.TextOut( (PageWidth div 2) - (ScaleX(Canvas.TextWidth(S) div 2)), Y, S);
      end;
    Y:=Y+ScaleY(HHeader);
    //Page nr
    S := 'Page '+IntToStr(PageRow);
    if (ToCol < ColCount-1) or (PageCol > 1) then
      S := S+'-'+IntToStr(PageCol);
    fstr:=Printoptions.PageFooter ;
    HFooter:=canvas.textheight(fstr);
    if fstr<>'' then
     if DoPaint then begin
      ACanvas.Font.Size := FprintOptions.FooterSize ;
      canvas.font := acanvas.font;
      HFooter:=canvas.textheight(fstr);
      flist:=tstringlist.create;
      flist.text:=stringreplace(fstr,'|',cr,[rfreplaceall]);
      while flist.count<3 do
       flist.Append ('');
      for i:=0 to 2 do begin
       flist[i]:=stringreplace(flist[i],'date',formatdatetime(PrintOptions.Dateformat,now),[]);
       flist[i]:=stringreplace(flist[i],'time',formatdatetime(PrintOptions.Timeformat,now),[]);
       flist[i]:=stringreplace(flist[i],'page',s,[]);
       end;
      //paint left footer
      if flist[0]<>'' then
       ACanvas.TextOut( scaleX(Printoptions.marginleft+Canvas.TextWidth(flist[0])), PageHeight-ScaleY(PrintOptions.marginbottom+canvas.TextHeight(flist[0])), flist[0]);
      //paint center footer
      if flist[1]<>'' then
       ACanvas.TextOut( (PageWidth div 2)-(scaleX(Canvas.TextWidth(flist[1]))div 2), PageHeight-ScaleY(PrintOptions.marginbottom+canvas.TextHeight(flist[1])), flist[1]);
      //paint right footer
      if flist[2]<>'' then
       ACanvas.TextOut( PageWidth-scaleX(Printoptions.marginright+Canvas.TextWidth(flist[2])+10), PageHeight-ScaleY(PrintOptions.marginbottom+canvas.TextHeight(flist[2])), flist[2]);
      flist.free;
      end;

    if DoPaint then
     begin
      ACanvas.Font.Size := Font.Size;
      canvas.font := tmpfont;//Delphi 4.0 warning is wrong
      end;
    Y := Y+ScaleY(PrintOptions.PageTitleMargin);
    DrawCells(0);
  end;

begin
  //page size
  Printer.Orientation :=PrintOptions.Orientation ;
  PageWidth := Printer.PageWidth;
  PageHeight := Printer.PageHeight;
  if Mode = pmPreview then
  begin
    PageWidth := PageWidth div ((GetDeviceCaps(Printer.Handle, LOGPIXELSX) div Screen.PixelsPerInch));
    PageHeight := PageHeight div ((GetDeviceCaps(Printer.Handle, LOGPIXELSY) div Screen.PixelsPerInch));
    FPrintImage.width:=pagewidth;
    FPrintImage.height:=pageheight;
    ACanvas.Brush.Color := ClWhite;
    ACanvas.FillRect( Rect(0,0,PageWidth,PageHeight));
  end;
    haslogo:=false;
    if printoptions.Logo <>'' then
     if fileexists(printoptions.logo) then begin
      logopic:=tbitmap.create;
      logopic.LoadFromFile (printoptions.logo);
      haslogo:=true;
      logopics:=tbitmap.create;
      logopics.width:=scaleX(logopic.width);
      logopics.height:=scaleY(logopic.height);
      logopic.PixelFormat :=pf24bit;
      logopics.pixelformat:=pf24bit;
      smoothresize(logopic,logopics);
      end;

  if Mode <> pmPageCount then
  begin
    ACanvas.Font := Font;
    ACanvas.Font.Color := clBlack;
  end;
  PageCol := 0;
  FromCol := -1;
  ToCol := -0;
  //scan cols
  repeat
    //Scan missing cols
    if FromCol = ToCol then
      Inc(FromCol)
    else
      FromCol := ToCol+1;
    Inc(ToCol);
    //Get Cols with width that fits page
    X := PrintOptions.MarginLeft ;
    for I := FromCol to ColCount-1 do
    begin
      Inc(X, ScaleX(ColWidths[I]+1));
      if X <= (PageWidth-PrintOptions.MarginRight) then
        ToCol := I;
    end;
    PageRow := 1;
    Inc(PageCol);
    //Mode = PageCount
    Inc(fPageCount);
    //preview mode
    DoPaint := (((Mode = pmPreview) and (fPageCount = PrintOptions.PreviewPage)) or (Mode = pmPrint));
    //Header & Footer
    DrawTitle;
    //Contents
    iRow := FromRow;
    repeat
//      Inc(Y, ScaleY(RowHeights[iRow]));
      if (Y+ScaleY(RowHeights[iRow])) <= (PageHeight-ScaleY(Printoptions.marginbottom+20+HFooter)) then
      begin //draw contents to canvas
        if RowHeights[iRow]<>0 then
         DrawCells(iRow);
        Inc(iRow);
      end
      else//New page
      begin
        if (DoPaint = True) and (Mode = pmPreview) then
          Exit;
        if Mode = pmPrint then
          Printer.NewPage;
        Inc(fPageCount);//pagecount
        DoPaint := (((Mode = pmPreview) and (fPageCount = PrintOptions.PreviewPage)) or (Mode = pmPrint));
        Inc(PageRow);
        DrawTitle;
      end;
      if (iRow = ToRow+1) and (ToCol < ColCount-1) and (Y <= PageHeight-ScaleY(20)) then
      begin
        if (DoPaint = True) and (Mode = pmPreview) then
          Exit;
        if Mode = pmPrint then
          Printer.NewPage;
        DrawTitle;
      end;
    until
      iRow = ToRow+1;
  until
    ToCol = ColCount-1;
  if haslogo then begin
   logopic.free;
   logopics.free;
   end;
end;
> Answer quick, this question is worth lots to me!

Why don't respond then?


Johnch: Withdraw your answer. Others have also proposed solutions so it's inappropriate of you to lock this question.
mrod0 - Please return to your question and review the posts made by the Experts.

darinw
Customer Service
Johnch changed the proposed answer to a comment
Avatar of mrod0

ASKER

Johnch, answer and I'll give you the points, sorry I havn't done this but I havn't had the possibility until today.

ASKER CERTIFIED SOLUTION
Avatar of Johnch
Johnch

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mrod0

ASKER

Answer accepted