AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Nur ausgewählte Einträge einer Listview drucken
Thema durchsuchen
Ansicht
Themen-Optionen

Nur ausgewählte Einträge einer Listview drucken

Ein Thema von verkouter · begonnen am 30. Sep 2018 · letzter Beitrag vom 7. Okt 2018
Antwort Antwort
Seite 1 von 2  1 2      
verkouter

Registriert seit: 29. Dez 2004
64 Beiträge
 
Delphi 2010 Architect
 
#1

Nur ausgewählte Einträge einer Listview drucken

  Alt 30. Sep 2018, 17:29
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.
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#2

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 30. Sep 2018, 17:39
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 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;
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 30. Sep 2018, 17:47
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.
Gruß vom KodeZwerg

Geändert von KodeZwerg (30. Sep 2018 um 18:15 Uhr)
  Mit Zitat antworten Zitat
verkouter

Registriert seit: 29. Dez 2004
64 Beiträge
 
Delphi 2010 Architect
 
#4

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 3. Okt 2018, 18:16
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.
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#5

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 3. Okt 2018, 18:38
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.
  Mit Zitat antworten Zitat
verkouter

Registriert seit: 29. Dez 2004
64 Beiträge
 
Delphi 2010 Architect
 
#6

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 3. Okt 2018, 19:05
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.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 3. Okt 2018, 19:09
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: 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.
Gruß vom KodeZwerg

Geändert von KodeZwerg ( 3. Okt 2018 um 19:35 Uhr) Grund: Code
  Mit Zitat antworten Zitat
verkouter

Registriert seit: 29. Dez 2004
64 Beiträge
 
Delphi 2010 Architect
 
#8

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 3. Okt 2018, 19:36
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.
Angehängte Dateien
Dateityp: pdf 1.pdf (175,4 KB, 10x aufgerufen)
Dateityp: pdf 2.pdf (84,5 KB, 9x aufgerufen)
  Mit Zitat antworten Zitat
DieDolly

Registriert seit: 22. Jun 2018
2.175 Beiträge
 
#9

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 3. Okt 2018, 19:39
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.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Nur ausgewählte Einträge einer Listview drucken

  Alt 3. Okt 2018, 19:47
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
Gruß vom KodeZwerg

Geändert von KodeZwerg ( 3. Okt 2018 um 19:53 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:55 Uhr.
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