Impression d'un stringgrid sur plusieur page [Résolu]

Signaler
Messages postés
12
Date d'inscription
mardi 16 janvier 2007
Statut
Membre
Dernière intervention
22 février 2007
-
Messages postés
12
Date d'inscription
mardi 16 janvier 2007
Statut
Membre
Dernière intervention
22 février 2007
-
Bonjour voila mon souci

j'ai un stringgrid avec beaucoup d'information et quand je fait mon impression je n'imprime que sur une seule page
ca fait que les première information qui se situ au debut de ma stringgrid sont imprimer mes pas ce de la fin.

j'utilise la methode printers pour imprimer avec un petit bout de code.

merci d'avance pour vos reponses

4 réponses

Messages postés
418
Date d'inscription
mardi 3 janvier 2006
Statut
Membre
Dernière intervention
26 novembre 2013
3
Salut arsenejeff.

Ton code ne permettait pas de placer la condition de saut de page puisque ta boucle de rows se trouve dans la boucle de cols. C'est l'inverse qu'il faut faire.
Le code ci-dessous te donne ce que tu voulais avec quelques améliorations :
- marges gauche, haute, droite, basse
- passage en paramètres des colonnes masquées (j'ai vu que tu n'imprimais pas la 0,8,10).
- remplacement de TextRect par la fonction DrawText avec alignement vertical centré.
- impression d'un entête à chaque page comprenant le titre et la ligne 0 (figée). Tu pourrais y ajouter le numéro de la page.

La procédure contient des procédures et fonctions imbriquées : si tu n'es pas habitué à cela, sache que ces procédures ne peuvent être appelées que par la procédure dans laquelle elles ont été déclarées (PrintGrid2), mais elles ont accès aux variables de celle-ci.

Un mot sur ton facteur "5".
La résolution d'un écran classique est de 72 pixels par pouce. Une imprimante de bureau travaille généralement en 300dpi.
Ce qui donne 300/72 = 4,17 que tu as arrondi vers le haut à 5.
Donc une largeur de colonne écran de 50 pixels va s'imprimer sur 250 pixels.
Pas de problèmes sauf si tu passes ton prog à quelqu'un qui imprime en 600 dpi : la largeur des colonnes va être diminuée de moitié, alors que le texte lui va s'adapter à la résolution de l'imprimante. 
Ton facteur devrait donc être adapté en fonction de la résolution imprimante.
Ou mieux : travailler en millimètres.Exemple : une colonne de 144 pixels écran doit faire 2 pouces (50,8 mm) en imprimante (144/72 2). Avec une résolution de 300dpi, cela donne : (50,8 * 300) / 25,4 600 pixels.
Avec une résolution de 600dpi : (50,8 * 600) / 25,4 = 1200 pixels.

Bonne prog
A +
Thierry

procedure PrintGrid2(sGrid: TStringGrid; sTitle: String; const AColMasked: array of word);
type
  TColCoord = record
    X1: integer;
    X2: integer;
  end;
var
  AColCoord: array of TColCoord;
  I, J : Integer;
  GridW: integer;
  R : TRect;
  PageH : integer;
  CurTop: integer;
  K: integer;
  LeftMargin, RightMargin, TopMargin, BottomMargin: word;
  LineH: integer;


         procedure PrintLine(P1, P2: TPoint);
         begin
            with Printer.Canvas do
            begin
               MoveTo(P1.X, P1.Y);
               LineTo(P2.X, P2.Y);
            end;
         end;


         function IsColMasked(ACol: integer): boolean;
         var
           T: integer;
         begin
           Result:= false;
           for T:= 0 to High(AColMasked) do
             if AColMasked[T] = ACol then Result:= true;
         end;


         procedure PrintCell(ARow, ACol: integer);
         var
           X1, X2, Y1, Y2 : Integer;
         begin
             X1:= AColCoord[ACol].X1;
             X2:= AColCoord[ACol].X2;
             Y1:= CurTop;
             Y2:= Y1 + LineH;
             PrintLine(Point(X1,Y1), Point(X1,Y2));
             R:= Rect(X1 + 50, Y1 + 25, X2 - 30, Y2 - 25);
             DrawText(Printer.Canvas.Handle, PChar(sGrid.Cells[ACol,ARow]), -1, R,
                       DT_SINGLELINE or DT_LEFT or DT_VCENTER);
             PrintLine(Point(X2,Y1), Point(X2,Y2));
         end;


         procedure PrintHeader;
         var
           T: integer;
         begin
             with Printer.Canvas do
             begin
                // Fonte pour le titre
                Font.Size:= 12;
                Font.Style:= [fsBold, fsUnderline];
                Font.Color:= clBlack;
                // écriture du titre
                TextOut(LeftMargin, TopMargin, Printer.Title);
                // Fonte pour la ligne 0
                Font.Size:= 8;
                Font.Style:= [fsBold];
                Font.Color:= clBlack;
             end;
             // écriture de la ligne 0
             CurTop:= TopMargin + 200;
             PrintLine(Point(LeftMargin, CurTop),
                       Point(GridW, CurTop));
             for T:= 0 to sGrid.ColCount - 1 do
               if not IsColMasked(T) then PrintCell(0,T);
             CurTop:= CurTop + LineH;
             PrintLine(Point(LeftMargin, CurTop),
                       Point(GridW, CurTop));
             // Fonte pour les autres lignes
             with Printer.Canvas do
             begin
                Font.Size:= 10;
                Font.Style:= [];
                Font.Color:= clBlack;
             end;
         end;




begin
  K:= 5;
  LeftMargin:= 100;
  RightMargin:= 100;
  TopMargin:= 100;
  BottomMargin:= 100;
  LineH:= 140;
  with Printer do
  begin
     Orientation := poPortrait;
     PageH:= PageHeight;
     Title:= sTitle;
     Canvas.Pen.Color:= clBlack;
     Canvas.Pen.Width:= 7;
     Canvas.Font.Name:= 'Times New Roman';
  end;
  // on remplit le tableau AColCoord
  SetLength(AColCoord, sGrid.ColCount);
  GridW:= LeftMargin;
  for I:= 0 to High(AColCoord) do
    if not IsColMasked(I) then
    begin
       AColCoord[I].X1:= GridW;
       AColCoord[I].X2:= GridW + (sGrid.ColWidths[I] * K);
       GridW:= AColCoord[I].X2;
    end;
  // on vérifie si on peut tout imprimer en largeur
  if GridW > (Printer.PageWidth - RightMargin) then
  begin
    ShowMessage('Largeur de page insuffisante');
    Finalize(AColCoord);
    Exit;
  end;


  Printer.BeginDoc;


  PrintHeader;


  for I:= 1 to sGrid.RowCount -1 do // la ligne 0 est imprimée dans PrintHeader
  begin
     if CurTop + LineH > PageH - BottomMargin then
     begin
        Printer.NewPage;
        PrintHeader;
     end;
     for J:= 0 to sGrid.ColCount -1 do
        if not IsColMasked(J) then PrintCell(I,J);
     PrintLine(Point(LeftMargin, CurTop + LineH),
               Point(GridW, CurTop + LineH));
     CurTop:= CurTop + LineH;
  end;


  Printer.EndDoc;
  Finalize(AColCoord);
end;




procedure TForm1.Button1Click(Sender: TObject);
begin
  Printgrid2(stringgrid1, 'Titre', [0,8,10]);
end;
Messages postés
418
Date d'inscription
mardi 3 janvier 2006
Statut
Membre
Dernière intervention
26 novembre 2013
3
Salut,

Si ton nombre de lignes dépasse le nombre de lignes imrpimables sur une page, tu dois faire un saut de page : Printer.NewPage;
Tu dois donc savoir quand faire ce saut de page. Pour cela, tu as la propriété Printer.PageHeight qui te renvoie le nombre de pixels de la hauteur de ta page (à appeler une fois avant de lancer l'impression).
TotalPixels:= Printer.PageHeight;

Connaissant la hauteur d'une ligne à imprimer que tu peux obtenir avec:
HLine:= Printer.Canvas.TextHeight('M') ,
valeur que tu incrémentes pour avoir un bel interligne, tu peux voir facilement si il te reste assez de place sur la page en cours.
Sinon, tu fais un saut de page et bien sûr tu réinitialises ta valeur Y (emplacement vertical dans la page) comme au début de l'impression.

A +
Thierry
Messages postés
12
Date d'inscription
mardi 16 janvier 2007
Statut
Membre
Dernière intervention
22 février 2007

Je voit tout a fait le principe dont tu parle

il y a juste un truc c'est que je ne sais pas ou placer ces bout de code
ou plutot ou placer ma condition (une fois arrivé a la fin de la page ==> saut de page)

jte met mon code pour imprimer si tu veut bien regarder ca serait vraiment simpa :)

procedure PrintGrid2(sGrid: TStringGrid; sTitle: String);
var
 X1, X2 : Integer;
 Y1, Y2 : Integer;
 TmpI : Integer;
 F : Integer;
 TR : TRect;
 TotalPixels : integer;
begin
 TotalPixels:= Printer.PageHeight;
 Printer.Orientation := poPortrait;
 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, 0, Printer.Title);

 For F:=1 to sGrid.ColCount-1 do begin
   X1:=0;
   if F <> 8  then
   begin
   if F <> 10 then
   begin


   For TmpI:=1 to (F-1) do
     X1:=X1+5*(sGrid.ColWidths[TmpI]);
   Y1:=200;              
    X2:=0;
   For TmpI:=1 to F do
     X2:=X2+5*(sGrid.ColWidths[TmpI]);
   Y2:=350;       
   TR:=Rect(X1, Y1, X2-30, Y2);
   Printer.Canvas.Font.Style:=[fsBold];
   Printer.Canvas.Font.Size:=8;
   Printer.Canvas.TextRect(TR, X1+50, 250, sGrid.Cells[F, 0]);   


   Printer.Canvas.Font.Style:=[];
   Printer.canvas.Pen.Width := 7;       //épaisseur de la ligne


   Printer.Canvas.MoveTo(X1,Y1);          //1
   Printer.Canvas.LineTo(X2,Y1);


   Printer.Canvas.MoveTo(X1,Y1);          //2
   Printer.Canvas.LineTo(X1,Y2);


   Printer.Canvas.MoveTo(X2,Y2);          //3
   Printer.Canvas.LineTo(X2,Y1);
   
   For TmpI:=1 to sGrid.RowCount-1 do begin
     Y1:=140*TmpI + 200;                    
     Y2:=140*(TmpI+1)+ 200;                
     TR:=Rect(X1, Y1, X2-30, Y2);         
     Printer.Canvas.TextRect(TR, X1+50, Y1+25, sGrid.Cells[F, TmpI]);  //X1+50, Y1+50,


   Printer.Canvas.MoveTo(X1,Y1);          //1
   Printer.Canvas.LineTo(X2,Y1);


   Printer.Canvas.MoveTo(X1,Y1);          //2
   Printer.Canvas.LineTo(X1,Y2);


   Printer.Canvas.MoveTo(X2,Y2);          //3
   Printer.Canvas.LineTo(X2,Y1);


   Printer.Canvas.MoveTo(X2,Y2);          //4
   Printer.Canvas.LineTo(X1,Y2);
   end;
 end;
end;
end;
 Printer.EndDoc;
end;

Merci pour ton aide
Messages postés
12
Date d'inscription
mardi 16 janvier 2007
Statut
Membre
Dernière intervention
22 février 2007

C'est trop bien !!!!!

Un grand merci à toi c'est vraiment simpa d'avoir pris le temps de regarder a mon probléme !

Vraiment merci beaucoup :D