Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Nur ausgewählte Einträge einer Listview drucken (https://www.delphipraxis.net/198056-nur-ausgewaehlte-eintraege-einer-listview-drucken.html)

verkouter 30. Sep 2018 16:29

Nur ausgewählte Einträge einer Listview drucken
 
Hallo, brauche wiedermal Hilfe.

Ich habe im Internet folgenden Code gefunden, der ein Listview ausdruckt.Blicke leider nicht durch.

Delphi-Quellcode:
procedure tform1.PrintListview(oListView: TListView; PrintDialog: TPrintDialog; lvTitel: string);
var
pWidth, pHeight, i: Integer;
v, h: Real;
CurItem, iColumnCount: Integer;
aCols: array of Integer;
iTotColsWidth, iInnerWidth, TopMarg, LinesOnPage, CurLine, TekstHeight, CurCol: Integer;
CurRect: TRect;
CurStr: string;
CurLeft, NumPages, TmpPos: Integer;
begin
if PrintDialog.Execute then
begin
iColumnCount := oListview.Columns.Count;
SetLength(aCols, iColumnCount + 1);
Printer.Title := 'Mischungsliste';
Printer.Copies := 1;
Printer.Orientation := poLandscape;
Printer.BeginDoc;
pHeight := Printer.PageHeight;
pWidth := Printer.PageWidth;
v := (pHeight + (2 * GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY))) / (29.7 * 0.95);
h := (pWidth + (2 * GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX))) / 21;
iTotColsWidth := 0;
for i := 0 to iColumnCount - 1 do
iTotColsWidth := iTotColsWidth + oListView.Columns[i].Width;
aCols[0] := Round(1.5 * h); //left margin ?
aCols[iColumnCount + 0] := pWidth - Round(1.5 * h); //rigth margin ?
iInnerWidth := aCols[iColumnCount + 0] - aCols[0]; // space between margins ?
for i := 0 to iColumnCount - 1 do
aCols[i + 1] := aCols[i] + Round(oListView.Columns[i].Width / iTotColsWidth * iInnerWidth);
TopMarg := Round(2.5 * v);
with Printer.Canvas do
begin
Font.Size := 6;
Font.Style := [];
Font.Name := 'Times New Roman';
Font.Color := RGB(0, 0, 0);
TekstHeight := Printer.Canvas.TextHeight('dummy');
LinesOnPage := Round((PHeight - (5 * v)) / TekstHeight);
NumPages := 1;
while (NumPages * LinesOnPage) < oListView.Items.Count do
inc(NumPages);
CurLine := 0;
for CurItem := 0 to oListView.Items.Count - 1 do
begin
if (CurLine > LinesOnPage) or (CurLine = 0) then
begin
if (CurLine > LinesOnPage) then Printer.NewPage;
CurLine := 1;
if Printer.PageNumber = NumPages then
begin
MoveTo(aCols[1], topMarg);
for i := 1 to iColumnCount - 1 do
begin
LineTo(aCols[i], TopMarg + (TekstHeight * (oListView.Items.Count - CurItem + 2)));
MoveTo(aCols[i + 1], topMarg);
end;
end
else
begin
for i := 1 to iColumnCount - 1 do
begin
MoveTo(aCols[i], topMarg);
LineTo(aCols[i], TopMarg + (TekstHeight * (LinesOnPage + 1)));
end;
end;
Font.Style := [fsBold];
for i := 0 to iColumnCount - 1 do
begin
TextRect(Rect(aCols[i] + Round(0.1 * h), TopMarg - Round(0.1 * v), aCols[i + 1] - Round(0.1 * h)
, TopMarg + TekstHeight - Round(0.1 * v)), ((aCols[i + 1] - aCols[i]) div 2) +
aCols[i] - (TextWidth(oListview.Columns.Items[i].Caption) div 2),
TopMarg - Round(0.1 * v), oListview.Columns.Items[i].Caption);
end;
MoveTo(aCols[0] - Round(0.1 * h), TopMarg + TekstHeight - Round(0.05 * v));
LineTo(aCols[iColumnCount] + Round(0.1 * h), TopMarg + TekstHeight - Round(0.05 * v));
Font.Size := 8;
Font.Style := [];
TmpPos := (TextWidth(DateToStr(Date) + '   Seite: ' +
IntToStr(Printer.PageNumber) + ' / ' + IntToStr(NumPages))) div 2;
TmpPos := PWidth - Round(1.5 * h) - (TmpPos * 2);
Font.Size := 8;
Font.Style := [];
TextOut(TmpPos, Round(0.5 * v),DateToStr(Date) +
'   Seite: ' + IntToStr(Printer.PageNumber) + ' / ' + IntToStr(NumPages));
Font.Size := 18;
if TmpPos < ((PWidth + TextWidth(lvTitel)) div 2 + Round(0.75 * h)) then
TextOut((PWidth - TextWidth(lvTitel)) div 2, Round(1 * v), lvTitel)
else
TextOut(Round(3 * h), Round(1 * v), lvTitel);
Font.Size := 7;
Font.Style := [];
end;
CurRect.Top := TopMarg + (CurLine * TekstHeight);
CurRect.Bottom := TopMarg + ((CurLine + 1) * TekstHeight);
for CurCol := -1 to iColumnCount - 2 do
begin
CurRect.Left := aCols[CurCol + 1] + Round(0.1 * h);
CurRect.Right := aCols[CurCol + 2] - Round(0.1 * h);
try
if CurCol = -1 then
CurStr := oListView.Items[CurItem].Caption
else
CurStr := oListView.Items[CurItem].SubItems[CurCol];
except
CurStr := '';
end;
CurLeft := CurRect.Left; // align left side
// write string in TextRect
TextRect(CurRect, CurLeft, CurRect.Top, CurStr);
end;
Inc(CurLine);
end;
end;
Printer.EndDoc
end;
end;
Ich habe ein Listview mit Checkboxen und nur ausgewähle Items sollen gedruckt werden.

DieDolly 30. Sep 2018 16:39

AW: Nur ausgewählte Einträge einer Listview drucken
 
Ich kann dir nicht helfen, aber ich habe den Code mal durch den Formatter gejagt, damit man wenigstens eine Chance hat ihn zu lesen.
Ich würde den Code schon alleine deswegen nicht verwenden, weil er ein
Delphi-Quellcode:
with
enthält.

Ich kann dir aber sagen, dass du dort wo die ListView-Items durchgegangen werden prüfen musst, ob das aktuelle Item checked ist oder nicht.

Delphi-Quellcode:
procedure tform1.PrintListview(oListView: TListView; PrintDialog: TPrintDialog; lvTitel: string);
var
 pWidth, pHeight, i: Integer;
 v, h: Real;
 CurItem, iColumnCount: Integer;
 aCols: array of Integer;
 iTotColsWidth, iInnerWidth, TopMarg, LinesOnPage, CurLine, TekstHeight, CurCol: Integer;
 CurRect: TRect;
 CurStr: string;
 CurLeft, NumPages, TmpPos: Integer;
begin
 if PrintDialog.Execute then
  begin
   iColumnCount := oListView.Columns.Count;
   SetLength(aCols, iColumnCount + 1);
   Printer.Title := 'Mischungsliste';
   Printer.Copies := 1;
   Printer.Orientation := poLandscape;
   Printer.BeginDoc;
   pHeight := Printer.PageHeight;
   pWidth := Printer.PageWidth;
   v := (pHeight + (2 * GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY))) / (29.7 * 0.95);
   h := (pWidth + (2 * GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX))) / 21;
   iTotColsWidth := 0;

   for i := 0 to iColumnCount - 1 do
    iTotColsWidth := iTotColsWidth + oListView.Columns[i].Width;

   aCols[0] := Round(1.5 * h); // left margin ?
   aCols[iColumnCount + 0] := pWidth - Round(1.5 * h); // rigth margin ?
   iInnerWidth := aCols[iColumnCount + 0] - aCols[0]; // space between margins ?

   for i := 0 to iColumnCount - 1 do
    aCols[i + 1] := aCols[i] + Round(oListView.Columns[i].Width / iTotColsWidth * iInnerWidth);

   TopMarg := Round(2.5 * v);

  with Printer.Canvas do
    begin
     Font.Size := 6;
     Font.Style := [];
     Font.Name := 'Times New Roman';
     Font.Color := RGB(0, 0, 0);
     TekstHeight := Printer.Canvas.TextHeight('dummy');
     LinesOnPage := Round((pHeight - (5 * v)) / TekstHeight);
     NumPages := 1;

     while (NumPages * LinesOnPage) < oListView.Items.Count do
      inc(NumPages);

     CurLine := 0;
     for CurItem := 0 to oListView.Items.Count - 1 do
      begin
       if (CurLine > LinesOnPage) or (CurLine = 0) then
        begin
         if (CurLine > LinesOnPage) then
          Printer.NewPage;

         CurLine := 1;
         if Printer.PageNumber = NumPages then
          begin
           MoveTo(aCols[1], TopMarg);
           for i := 1 to iColumnCount - 1 do
            begin
             LineTo(aCols[i], TopMarg + (TekstHeight * (oListView.Items.Count - CurItem + 2)));
             MoveTo(aCols[i + 1], TopMarg);
            end;
          end
         else
          begin
           for i := 1 to iColumnCount - 1 do
            begin
             MoveTo(aCols[i], TopMarg);
             LineTo(aCols[i], TopMarg + (TekstHeight * (LinesOnPage + 1)));
            end;
          end;

         Font.Style := [fsBold];

         for i := 0 to iColumnCount - 1 do
          begin
           TextRect(Rect(aCols[i] + Round(0.1 * h), TopMarg - Round(0.1 * v), aCols[i + 1] - Round(0.1 * h), TopMarg + TekstHeight - Round(0.1 * v)),
            ((aCols[i + 1] - aCols[i]) div 2) + aCols[i] - (TextWidth(oListView.Columns.Items[i].Caption) div 2), TopMarg - Round(0.1 * v), oListView.Columns.Items[i].Caption);
          end;

         MoveTo(aCols[0] - Round(0.1 * h), TopMarg + TekstHeight - Round(0.05 * v));
         LineTo(aCols[iColumnCount] + Round(0.1 * h), TopMarg + TekstHeight - Round(0.05 * v));
         Font.Size := 8;
         Font.Style := [];
         TmpPos := (TextWidth(DateToStr(Date) + ' Seite: ' + IntToStr(Printer.PageNumber) + ' / ' + IntToStr(NumPages))) div 2;
         TmpPos := pWidth - Round(1.5 * h) - (TmpPos * 2);
         Font.Size := 8;
         Font.Style := [];
         TextOut(TmpPos, Round(0.5 * v), DateToStr(Date) + ' Seite: ' + IntToStr(Printer.PageNumber) + ' / ' + IntToStr(NumPages));
         Font.Size := 18;

         if TmpPos < ((pWidth + TextWidth(lvTitel)) div 2 + Round(0.75 * h)) then
          TextOut((pWidth - TextWidth(lvTitel)) div 2, Round(1 * v), lvTitel)
         else
          TextOut(Round(3 * h), Round(1 * v), lvTitel);

         Font.Size := 7;
         Font.Style := [];
        end;

       CurRect.Top := TopMarg + (CurLine * TekstHeight);
       CurRect.Bottom := TopMarg + ((CurLine + 1) * TekstHeight);

       for CurCol := -1 to iColumnCount - 2 do
        begin
         CurRect.Left := aCols[CurCol + 1] + Round(0.1 * h);
         CurRect.Right := aCols[CurCol + 2] - Round(0.1 * h);

         try
          if CurCol = -1 then
           CurStr := oListView.Items[CurItem].Caption
          else
           CurStr := oListView.Items[CurItem].SubItems[CurCol];
         except
          CurStr := '';
         end;

         CurLeft := CurRect.Left; // align left side

         // write string in TextRect
         TextRect(CurRect, CurLeft, CurRect.Top, CurStr);
        end;
       inc(CurLine);
      end;
    end;

   Printer.EndDoc
  end;
end;

KodeZwerg 30. Sep 2018 16:47

AW: Nur ausgewählte Einträge einer Listview drucken
 
Deine fehlende formatierung macht mir das lesen auf die schnelle unmöglich aber hier ein Beispiel für alles, änder das "alle" halt mit einer "nur diese" variante.
Delphi-Quellcode:
Uses Printers;

procedure PrintLVSelection(const LV: TListView);
Var
 LineHeight,i,j,Y,X:Integer;
begin
 With Printer do
  begin
   BeginDoc;
   LineHeight:=Round(Canvas.TextHeight('H')*1.2);
   Y:=0;
   for i:=0 to lv.Items.Count-1 do
   if lv.Items[i].Selected then
    begin
     If Y+LineHeight>PageHeight Then
      begin
       NewPage;
       Y:=0;
      end;
//     Canvas.TextOut(0,Y,lv1.Items[i].Caption);
       With lv.Items[i] do
        begin
          X:=0;
          Canvas.TextOut(X*PageWidth Div lv1.Width,Y,Caption);   
          for j:=0 to SubItems.Count-1 do
           begin
             X:=X+Columns[j].Width;
             Canvas.TextOut(X*PageWidth Div lv1.Width,Y,Caption);
           end;
        end;
     Y:=Y+LineHeight;
    end;
   EndDoc;
  end;
end;
edit
hab noch ne "ists markiert" abfrage rangehangen, sollte theoretisch funktionieren, auch subitems sind nun drinnen.

verkouter 3. Okt 2018 17:16

AW: Nur ausgewählte Einträge einer Listview drucken
 
Hallo Kodezwerg,
habe deinen Code etwas umgeändert.

Delphi-Quellcode:
procedure TForm1.ToolButton8Click(Sender: TObject);
Var
 LineHeight,i,j,Y,X:Integer;
begin
if PrintDialog1.Execute then
begin
Printer.Title := 'Mischungsliste';
Printer.Copies := 1;
Printer.Orientation := poLandscape;
 With Printer do
  begin
   BeginDoc;
   LineHeight:=Round(Canvas.TextHeight('H')*1.2);
   Y:=0;
   for i:=0 to listview1.Items.Count-1 do
   if listview1.Items[i].Checked then
    begin
     If Y+LineHeight>PageHeight Then
      begin
       NewPage;
       Y:=0;
      end;
// Canvas.TextOut(0,Y,lv1.Items[i].Caption);
       With listview1.Items[i] do
        begin
          X:=0;
          printer.Canvas.TextOut(X*PageWidth Div listview1.Width,Y,Caption);
          for j:=0 to SubItems.Count-1 do
           begin
             X:=X+listview1.Columns[j].width;
             printer.Canvas.TextOut(X*PageWidth Div listview1.Width,Y,subitems[j]);
           end;
        end;
     Y:=Y+LineHeight;
    end;
   EndDoc;
  end;
end;
end;
Mir war schon klar, daß ich eine Abfrage machen muß, die prüft ob Checkbox an oder aus ist. Der Code den ich verwände,baut soweit ich ihn verstanden habe, die Formatierung
spaltenweise auf, was eine Abfrage zeilenweise schwierig macht. Ich wollte den fertigen Ausdruck aber nicht nochmal komplett neu programmieren.

DieDolly 3. Okt 2018 17:38

AW: Nur ausgewählte Einträge einer Listview drucken
 
Ich würde den Code an deiner Stelle nochmal komplett neu schreiben.
Du wirst den Code in einem Jahr nicht mehr lesen können. Speziell wegen des ziemlich bösen with.
With ist schlecht.

verkouter 3. Okt 2018 18:05

AW: Nur ausgewählte Einträge einer Listview drucken
 
Mein Problem ist ja, das ich den Code jetzt schon nicht verstehe, alle Umrechnungen auf Papiergröße und Positionierungen.
Aber es kommt halt ein fertiges Formular bei raus.

KodeZwerg 3. Okt 2018 18:09

AW: Nur ausgewählte Einträge einer Listview drucken
 
Hier ohne "with" aber mit Deinen Änderungen
Delphi-Quellcode:
procedure PrintDlgSelLv(PDlg: TPrintDialog; const LV: TListView; const Title: String = 'by KodeZwerg');
Var
 LineHeight,i,j,Y,X:Integer;
begin
  if PDlg.Execute then
  begin
    Printer.Title := Title;
    Printer.Copies := PDlg.Copies;
    Printer.Orientation := poLandscape;
    Printer.BeginDoc;
    LineHeight:=Round(Printer.Canvas.TextHeight('H')*1.2);
    Y:=0;
    for i:=0 to LV.Items.Count-1 do
     if LV.Items[i].Checked then
      begin
       If Y+LineHeight>Printer.PageHeight Then
        begin
          Printer.NewPage;
          Y:=0;
        end;
//       Printer.Canvas.TextOut(0,Y,LV.Items[i].Caption);
        X:=0;
        Printer.Canvas.TextOut(X*Printer.PageWidth Div LV.Width,Y,LV.Items[i].Caption);
        for j:=0 to LV.Items[i].SubItems.Count-1 do
         begin
           X:=X+LV.Columns[j].width;
           Printer.Canvas.TextOut(X*Printer.PageWidth Div LV.Width,Y,LV.Items[i].SubItems[j]);
         end;
        Y:=Y+LineHeight;
      end;
    Printer.EndDoc;
  end;
end;
Aufrufen so in etwa:
Delphi-Quellcode:
PrintDlgSelLv(PrintDialog1, ListView1, 'Mischungsliste');


Erklärung:
Bei "BeginDoc" fängt man an ein Formular fürs Drucken Vorzubereiten, bei "EndDoc" sagt man dem Drucker das man fertig ist.

verkouter 3. Okt 2018 18:36

AW: Nur ausgewählte Einträge einer Listview drucken
 
Liste der Anhänge anzeigen (Anzahl: 2)
Meine Vermutung ist, das der Code Spaltenweise arbeitet um senkrechte Linien zu Zeichnen. Und diesen ganzen Aufbau verstehe ich nicht.
Beim Orginalcode sieht das Protokoll aus, wie in 1.pdf und mit dem Code von Kodezwerg wie in 2.pdf . Ist schon ein kleiner Unterschied.

DieDolly 3. Okt 2018 18:39

AW: Nur ausgewählte Einträge einer Listview drucken
 
Ich würde es mir da ehrlich gesagt viel einfacher machen...

ich würde die ListView durchgehen und alle Daten im HTML-Format in eine Datei speichern und diese anschließend ausdrucken.
So bekommt man auch alles genau so hin wie es in 1.pdf zu sehen ist und muss sich nicht mit Printers etc rumschlagen.

KodeZwerg 3. Okt 2018 18:47

AW: Nur ausgewählte Einträge einer Listview drucken
 
Ich find, jetzt wo ich sehe was gedruckt wird, mein Beispiel gar nicht mal so schlecht, bei Nadeldrucker konnte man ein "|" Zeichen vorm Item Hängen um damit ne Vertikale Linie zu drucken, kannst Du gerne mal Versuchen aber ich garantiere für nichts.

edit
Und jetzt habe ich auch erst Verstanden was TE möchte, seine Funktion mit meiner Abfrage kombiniert.
Ich schau mir das nach her noch mal an, DieDolly kann ja ein Html Beispiel erschaffen :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:59 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz