Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Drucken einer Listview als Tabelle


Lux - Mo 11.04.05 08:53
Titel: Drucken einer Listview als Tabelle
Hallo Leute.
Ich wollte eine Listview drucken, was an sich kein Problem ist, weil ich dafür etwas gefunden habe:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
procedure Drucken(lv: TListview);
var zeile, x, y : integer;
    breite, hoehe, randlinks, randoben: integer;
begin

  if hauptmenue_frm.Printdialog1.Execute then
   Printer.BeginDoc; //Druckjob beginnen

   //Blattgröße in 1/10 mm ermitteln
   breite := GetDeviceCaps(Printer.Canvas.Handle, HORZSIZE)*10;
   hoehe := GetDeviceCaps(Printer.Canvas.Handle, VERTSIZE)*10;

   randlinks := 100//2,5cm
   randoben := 100//2,5cm

   x := randlinks;
   y := randoben * -1;


   for zeile := 0 to lv.items.Count-1 do begin
     if -y > (hoehe-2 * randoben) then begin
       y := randoben * -1;
       Printer.Newpage;
     end;
     SetMapMode(Printer.Canvas.Handle, MM_LOMETRIC); //Umstellen auf 1/10 mm

     //Schrifteinstellungen
     Printer.Canvas.Font.Name := 'Arial';
     Printer.Canvas.Brush.Color := clWhite;
     Printer.Canvas.Font.Height := 30//5 mm

     if y = -randoben then begin
        Printer.Canvas.Font.Style := [fsBold];
        Printer.Canvas.TextOut(x, y, lv.Columns[0].caption);
        Printer.Canvas.TextOut(x+280, y, lv.Columns[1].caption);
        Printer.Canvas.TextOut(x+460, y, lv.Columns[2].caption);
        Printer.Canvas.TextOut(x+840, y, lv.Columns[3].caption);
        Printer.Canvas.TextOut(x+950, y, lv.Columns[4].caption);
        Printer.Canvas.TextOut(x+1100, y, lv.Columns[5].caption);
        Printer.Canvas.TextOut(x+1220, y, lv.Columns[6].caption);
        Printer.Canvas.TextOut(x+1330, y, lv.Columns[7].caption);
        Printer.Canvas.Font.Style := [];

        y := y - Printer.Canvas.TextHeight(lv.Items[0].Caption);
     end;

       Printer.Canvas.TextOut(x, y, lv.Items[zeile].caption);
       Printer.Canvas.TextOut(x+280, y, lv.Items[zeile].SubItems[0]);
       Printer.Canvas.TextOut(x+460, y, lv.Items[zeile].SubItems[1]);
       Printer.Canvas.TextOut(x+840, y, lv.Items[zeile].SubItems[2]);
       Printer.Canvas.TextOut(x+950, y, lv.Items[zeile].SubItems[3]);
       Printer.Canvas.TextOut(x+1100, y, lv.Items[zeile].SubItems[4]);
       Printer.Canvas.TextOut(x+1220, y, lv.Items[zeile].SubItems[5]);
       Printer.Canvas.TextOut(x+1330, y, lv.Items[zeile].SubItems[6]);

       y := y - Printer.Canvas.TextHeight(lv.Items[zeile].Caption);

  end;
  Printer.EndDoc;
end;


Allerdings druckt er dann die Listview einfach so aus, ohne Linien.
Ich wollte das ganz gern in Form einer Tabelle haben.
Muss ich dafür dann mit Canvas Linienzeichnen? Oder was muss ich dann machen?


matze - Mo 11.04.05 14:00

ich hatt da mal folgenden code gefunden: http://www.delphipraxis.net/post164046.html#164046
(der von Toms)


Lux - Mo 11.04.05 14:02

Um das Problem selber zu lösen :)
Man kann es mit Canvas machen. Ist auch eigentlich recht einfach. In meinem Beispiel sieht der Code dann so aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
procedure Drucken(lv: TListview);
var zeile, x, y : integer;
    breite, hoehe, randlinks, randoben: integer;
begin

  if hauptmenue_frm.Printdialog1.Execute then
   Printer.BeginDoc; //Druckjob beginnen

   //Blattgröße in 1/10 mm ermitteln
   breite := GetDeviceCaps(Printer.Canvas.Handle, HORZSIZE)*10;
   hoehe := GetDeviceCaps(Printer.Canvas.Handle, VERTSIZE)*10;

   randlinks := 100//2,5cm
   randoben := 100//2,5cm

   x := randlinks;
   y := randoben * -1;


   for zeile := 0 to lv.items.Count-1 do begin
     if -y > (hoehe-2 * randoben) then begin
       y := randoben * -1;
       Printer.Newpage;
     end;
     SetMapMode(Printer.Canvas.Handle, MM_LOMETRIC); //Umstellen auf 1/10 mm

     //Schrifteinstellungen
     with Printer.Canvas do begin
     Font.Name := 'Arial';
     Brush.Color := clWhite;
     Font.Height := 30//5 mm
     Pen.Color := clBlack;
     Pen.Width := 2;
     Pen.Style := pssolid;
     end;

     if y = -randoben then begin
        Printer.Canvas.Font.Style := [fsBold];
        Printer.Canvas.TextOut(x, y, lv.Columns[0].caption);
        Printer.Canvas.MoveTo(x+275, y);
        Printer.Canvas.LineTo(x+275, y-30);
        Printer.Canvas.TextOut(x+280, y, lv.Columns[1].caption);
        Printer.Canvas.MoveTo(x+455, y);
        Printer.Canvas.LineTo(x+455, y-30);
        Printer.Canvas.TextOut(x+460, y, lv.Columns[2].caption);
        Printer.Canvas.MoveTo(x+835, y);
        Printer.Canvas.LineTo(x+835, y-30);
        Printer.Canvas.TextOut(x+840, y, lv.Columns[3].caption);
        Printer.Canvas.MoveTo(x+945, y);
        Printer.Canvas.LineTo(x+945, y-30);
        Printer.Canvas.TextOut(x+950, y, lv.Columns[4].caption);
        Printer.Canvas.MoveTo(x+1095, y);
        Printer.Canvas.LineTo(x+1095, y-30);
        Printer.Canvas.TextOut(x+1100, y, lv.Columns[5].caption);
        Printer.Canvas.MoveTo(x+1095, y);
        Printer.Canvas.LineTo(x+1095, y-30);
        Printer.Canvas.TextOut(x+1220, y, lv.Columns[6].caption);
        Printer.Canvas.MoveTo(x+1215, y);
        Printer.Canvas.LineTo(x+1215, y-30);
        Printer.Canvas.TextOut(x+1330, y, lv.Columns[7].caption);
        Printer.Canvas.MoveTo(x+1325, y);
        Printer.Canvas.LineTo(x+1325, y-30);
        Printer.Canvas.MoveTo(x, y-28);
        Printer.Canvas.LineTo(x+1800, y-28);
        Printer.Canvas.Font.Style := [];

        y := y - Printer.Canvas.TextHeight(lv.Items[0].Caption);
     end;

       Printer.Canvas.TextOut(x, y, lv.Items[zeile].caption);
       Printer.Canvas.MoveTo(x+275, y);
       Printer.Canvas.LineTo(x+275, y-30);
       Printer.Canvas.TextOut(x+280, y, lv.Items[zeile].SubItems[0]);
       Printer.Canvas.MoveTo(x+455, y);
       Printer.Canvas.LineTo(x+455, y-30);
       Printer.Canvas.TextOut(x+460, y, lv.Items[zeile].SubItems[1]);
       Printer.Canvas.MoveTo(x+835, y);
       Printer.Canvas.LineTo(x+835, y-30);
       Printer.Canvas.TextOut(x+840, y, lv.Items[zeile].SubItems[2]);
       Printer.Canvas.MoveTo(x+945, y);
       Printer.Canvas.LineTo(x+945, y-30);
       Printer.Canvas.TextOut(x+950, y, lv.Items[zeile].SubItems[3]);
       Printer.Canvas.MoveTo(x+1095, y);
       Printer.Canvas.LineTo(x+1095, y-30);
       Printer.Canvas.TextOut(x+1100, y, lv.Items[zeile].SubItems[4]);
       Printer.Canvas.MoveTo(x+1215, y);
       Printer.Canvas.LineTo(x+1215, y-30);
       Printer.Canvas.TextOut(x+1220, y, lv.Items[zeile].SubItems[5]);
       Printer.Canvas.MoveTo(x+1325, y);
       Printer.Canvas.LineTo(x+1325, y-30);
       Printer.Canvas.TextOut(x+1330, y, lv.Items[zeile].SubItems[6]);


       y := y - Printer.Canvas.TextHeight(lv.Items[zeile].Caption);

  end;
  Printer.EndDoc;
end;


Also einfach immer folgenden Code eintragen:


Delphi-Quelltext
1:
2:
Printer.Canvas.MoveTo(x, y);
Printer.Canvas.LineTo(x, y-20);


Lux - Mo 11.04.05 14:06

user profile iconmatze hat folgendes geschrieben:
ich hatt da mal folgenden code gefunden: http://www.delphipraxis.net/post164046.html#164046
(der von Toms)


Mist warst ein paar Minuten schneller ;)

Den Code hatte ich auch schonmal gefunden und ausprobiert. Damit klappte das Drucken bei mir noch nicht mal...

Aber vielen Dank für deine Hilfe!

Meine Lösung: Siehe ein Posting weiter oben :)