DGV drucken

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    ausgelagert aus Drucken mehrseitiger Dokumente ~VaporiZed

    Hallo
    Ich bin dabei die Daten aus meinem DGV zu drucken. Das Prg."PrintTable.zip" habe ich mir runtergeladen und soweit ich konnte nach meinen Bedürfnissen angepasst.
    z.b. habe Ich das Zellpadding auf 25 gesetzt weil ich im DGV einige Spalten habe wo WordWrap auf true gesetzt ist um überlangen text in 2 oder mehrere Zeilen anzeigem zu lassen.
    Alles klappt ausgezeichnet. Nur ein Problem dabei ist die Druckbreite. Die Tabell ragt auf beiden Seiten weit hinaus.
    Kann man diese Problem beheben, wenn ja wie??
    Ist es vielleicht auch möglich den einzelnen Columns einen festen Wert zuzuweisen damit der Ausdruck hinterher auf die Seite passt.
    Die Druckränder der Seite sind auch ziemlich groß. (Siehe Bildanhang). Kann man an dieser Einstellung eventuel was ändern?
    Viele Grüße und besten Dank schon mal im Vorraus
    Bilder
    • soll.jpg

      143,5 kB, 1.309×655, 56 mal angesehen
    • ist.jpg

      168,19 kB, 1.856×1.302, 56 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    Mit DGV-Drucken verstehe ich eigentlich immer, dass die gebundenen Daten des DGV zum Drucken gemeint sind...
    Natürlich nur ein gebundenes DGV an eine Datenquelle ist da bei mir gemeint...
    Dazu habe ich einmal ein Tutorial verfasst (Siehe Teil 3):
    ReportViewer-Tutorial für Anfänger?
    Vlt. hilft es dir weiter...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    @echnaton Sieh Dir mal das hier an: Drucken einer Tabelle
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    …was er bereits gemacht hat:

    echnaton schrieb:

    ausgelagert aus Drucken mehrseitiger Dokumente ~VaporiZed

    Hallo
    Ich bin dabei die Daten aus meinem DGV zu drucken. Das Prg."PrintTable.zip" habe ich mir runtergeladen und soweit ich konnte nach meinen Bedürfnissen angepasst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed Dann hat er möglicherweise nicht verstanden, wie die Breite der Spalten bestimmt wird oder hat das falsch überarbeitet.
    @echnaton Starte Dein Projekt und mein Projekt nebeneinander und arbeite beide parallel zeilenweise ab, da solltest Du merken, wo was schiedf läuft:
    Debuggen, Fehler finden und beseitigen
    ansonsten hänge mal Dein Projekt bereinigt (ohne bin, obj- und vs-Ordner) gezippt an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja Hallo

    Ich habe schon verstanden das sich die Breite an den Colums orientiert (sogar die schriftgröße wird berücksichtigt.)
    Ich habe Das "Printtable" Prog nochmal ausgetestet. Es scheint für mich nicht brauchbar-
    Habe einfach mal im Original ""Printtable" ein paar Columns hinzugefügt und da besteht das gleiche Problem.
    siehe Anhang_
    Ich werde mal sehen wie ich eine Tabelle ausdrucken kann. Im zweifelsfall schaufel ich die Daten nach Excel und drucke von dort.
    (Ich hätte aber lieber eine Lösung in .net)


    also vielen Dank für eure Hinweise
    Bilder
    • Test.jpg

      242,41 kB, 1.798×1.069, 43 mal angesehen
    @echnaton

    RodFromGermany schrieb:

    ansonsten hänge mal Dein Projekt bereinigt (ohne bin, obj- und vs-Ordner) gezippt an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das ist wirklich schwierig. Habe in meinem VS jede Menge externer Steuerelemente (Form, Kalender Textboxen,Label usw.)
    alles aus externen Dll
    aber ich lege mal den aktuellen code bei. vielleicht kannst du ja da was mit anfangen-



    Formload

    VB.NET-Quellcode

    1. #Region "Form"
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. Me.AdressenTableAdapter.Fill(Me.DekoDataSet.Adressen)
    4. Me.DatenTableAdapter.Fill(Me.DekoDataSet.Daten)
    5. StyleManager.Style = eStyle.Office2007Blue
    6. Kalender.AktDatum.ToString()
    7. tbx_datum.Text = Kalender.AktDatum.ToString("dd.MM.yyyy")
    8. DatenBindingSource.Filter = String.Format("Jahr= '{0}' and Monat= '{1}'", CStr(Kalender.AktDatum.Year), CStr(Kalender.AktDatum.Month))
    9. Summe()
    10. lbl_anzahl.Text = DekoDataSet.Daten.Rows.Count.ToString()
    11. Me.PrintDocument1.DefaultPageSettings.Landscape = True
    12. End Sub
    13. Private Sub Form_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
    14. Me.SuspendLayout()
    15. With Me.Controls
    16. While .Count > 0 : .Item(.Count - 1).Dispose() : End While
    17. End With
    18. End Sub
    19. #End Region

    Drucken

    VB.NET-Quellcode

    1. #Region "Drucken"
    2. Private ReadOnly SpaltenBreiten As New List(Of Single) ' Auflistung mit der Breite der einzelnen Spalten
    3. Private DGVZeilenIndex As Integer ' Index der aktuell ausgegebenen DGV-Zeile
    4. Private DGVDruckbreite As Single ' Breite der Tabelle
    5. Private ReadOnly ZellPadding As Integer = 25 ' Rahmen um die Zelle
    6. ' Hintergrundfarben für Header und Zellen
    7. Private ReadOnly HeaderColor As Color = Color.LightGray
    8. Private ReadOnly RowColor As Color = Color.White
    9. Private ReadOnly RowColorAlternate As Color = Color.LightYellow
    10. ' Flags zur Druckausgabe => CheckBoxen
    11. Private CenterHorz As Boolean = True
    12. Private PrintGrating As Boolean = True
    13. Private ColumnsAutoSize As Boolean = False
    14. Private AlternateColor As Boolean = True
    15. ' Befüllen des DGV
    16. ' Sofortiger Druck der Tabelle
    17. Private Sub btn_Drucken_sofort_Click(sender As Object, e As EventArgs) Handles btn_Drucken_sofort.Click
    18. Me.SpaltenBreitenErmitteln()
    19. Me.PrintDocument1.Print()
    20. End Sub
    21. ' Anzeige der Druckvorschau
    22. Private Sub btn_vorschau_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_vorschau.Click
    23. Me.SpaltenBreitenErmitteln()
    24. Using dlg As New PrintPreviewDialog
    25. dlg.Document = Me.PrintDocument1
    26. dlg.WindowState = FormWindowState.Maximized
    27. ' 1 Seite anzeigen
    28. dlg.PrintPreviewControl.Columns = 1
    29. dlg.ShowDialog()
    30. End Using
    31. End Sub
    32. ' Ermitteln der Spaltenbreiten
    33. Private Sub SpaltenBreitenErmitteln()
    34. Dim ZellInhalt As String
    35. Dim g As Graphics = DGV.CreateGraphics
    36. Me.SpaltenBreiten.Clear()
    37. Me.DGVDruckbreite = 0
    38. If ColumnsAutoSize Then
    39. For DGVSpalte = 0 To Me.DGV.Columns.Count - 1
    40. ' *** Breite das Textes im Spaltenkopf als Mindestbreite
    41. ZellInhalt = DGV.Columns(DGVSpalte).HeaderText
    42. Dim Breite = g.MeasureString(ZellInhalt, DGV.Font).Width + ZellPadding
    43. SpaltenBreiten.Add(Breite)
    44. ' *** Jede Spalte komplett durchlaufen und größte Textbreite finden und speichern
    45. For DGVZeile As Integer = 0 To DGV.Rows.Count - 1
    46. ' Zellinhalt holen und ggf. formatieren
    47. ZellInhalt = DGV.Rows(DGVZeile).Cells(DGVSpalte).Value.ToString
    48. If Not String.IsNullOrEmpty(DGV.Columns(DGVSpalte).DefaultCellStyle.Format) Then
    49. ZellInhalt = Convert.ToDouble(ZellInhalt).ToString(DGV.Columns(DGVSpalte).DefaultCellStyle.Format)
    50. End If
    51. ' Spaltenbreite feststellen und prüfen, ob größer als bisher und ggf. austauschen
    52. Breite = g.MeasureString(ZellInhalt, DGV.Font).Width + ZellPadding
    53. If SpaltenBreiten(DGVSpalte) < Breite Then
    54. SpaltenBreiten(DGVSpalte) = Breite
    55. End If
    56. Next
    57. DGVDruckbreite += SpaltenBreiten(DGVSpalte)
    58. Next
    59. Else
    60. ' Kein Spalten-AutoSizing
    61. For DGVSpalte As Integer = 0 To DGV.Columns.Count - 1
    62. Dim Breite = DGV.Columns(DGVSpalte).Width + ZellPadding
    63. SpaltenBreiten.Add(Breite)
    64. DGVDruckbreite += Breite
    65. Next
    66. End If
    67. End Sub
    68. ' Vorbereiten des Ausdrucks, wird pro Druckvorgang genau einmalig aufgerufen
    69. Private Sub PrintDocument1_BeginPrint(sender As Object, e As PrintEventArgs) Handles PrintDocument1.BeginPrint
    70. ' Ausgangssituation
    71. DGVZeilenIndex = 0
    72. End Sub
    73. ' der eigentliche Druck, wird für jede einzelne Seite aufgerufen
    74. Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    75. Dim cellBox As New RectangleF
    76. Dim sf As New StringFormat
    77. Dim borderLeft As Single
    78. Dim borderRight As Single
    79. Dim borderTop As Single
    80. Dim borderBottom As Single
    81. Dim PageWidth As Integer
    82. Dim PageHeight As Decimal
    83. Dim dgvMaxRowIndex As Integer
    84. Dim dgvMaxColIndex As Integer
    85. Dim content As String
    86. Dim PosX As Integer
    87. Dim PosY As Integer
    88. Dim PosX1 As Integer
    89. e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
    90. e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
    91. ' Höhe der Schrift ermitteln anhand der Schriftart(Font)
    92. ' mittels Mustertext
    93. ' und Höhe geringfügig erhöhen
    94. Dim g As Graphics = DGV.CreateGraphics
    95. ' Ermittlung der Schrifthöhe (Text mit Ober- und Unterlängen)
    96. ' Font.Height ist nicht so hoch!
    97. Dim TextHöhe = g.MeasureString("Bg", DGV.Font).Height + ZellPadding
    98. With PrintDocument1.DefaultPageSettings
    99. borderLeft = .Margins.Left ' Rand links
    100. borderRight = .Margins.Right ' Rand rechts
    101. borderTop = .Margins.Top ' Rand oben
    102. borderBottom = .Margins.Bottom ' Rand unten
    103. PageWidth = .Bounds.Width - CInt(borderRight + borderLeft) ' Druckbereich Breite
    104. PageHeight = .Bounds.Height - CInt(borderTop + borderBottom) ' Druckbereich Höhe
    105. e.Graphics.DrawRectangle(Pens.Black, borderLeft, borderTop, PageWidth, PageHeight) ' Rahmen um alles
    106. End With
    107. If CenterHorz Then ' Tabelle horizontal zentrieren
    108. borderLeft = CSng(borderLeft + (PageWidth / 2)) - (DGVDruckbreite / 2)
    109. End If
    110. ' Den höchsten ZeilenIndex des DataGridview ermitteln
    111. ' in Abhängigkeit davon, ob eine leere Zeile am Ende steht
    112. If DGV.AllowUserToAddRows Then
    113. dgvMaxRowIndex = DGV.Rows.Count - 2
    114. Else
    115. dgvMaxRowIndex = DGV.Rows.Count - 1
    116. End If
    117. dgvMaxColIndex = DGV.Columns.Count - 1
    118. sf.Alignment = StringAlignment.Near
    119. sf.LineAlignment = StringAlignment.Center
    120. PosY = CInt(borderTop)
    121. PosX = CInt(borderLeft)
    122. ' Spaltenköpfe drucken
    123. For DruckSpalte = 0 To dgvMaxColIndex
    124. cellBox = New RectangleF(PosX, PosY, SpaltenBreiten(DruckSpalte), TextHöhe)
    125. content = DGV.Columns(DruckSpalte).HeaderText
    126. e.Graphics.FillRectangle(New SolidBrush(HeaderColor), cellBox)
    127. If PrintGrating = True Then
    128. e.Graphics.DrawRectangle(Pens.Black, cellBox.X, cellBox.Y, cellBox.Width, cellBox.Height)
    129. End If
    130. e.Graphics.DrawString(content, DGV.Font, Brushes.Black, cellBox, sf)
    131. PosX += CInt(SpaltenBreiten(DruckSpalte))
    132. Next
    133. ' die aktuelle Ausgabeposition
    134. PosX = CInt(borderLeft)
    135. PosY = CInt(borderTop + TextHöhe)
    136. ' Zeilennummer auf der aktuellen Seite
    137. Dim DruckZeile = 0
    138. ' Schleife über alle Zeilen der aktuellen Seite
    139. Do
    140. ' Schleife über alle Spalten
    141. For DruckSpalte = 0 To dgvMaxColIndex
    142. Dim value = DGV.Rows(DruckZeile + DGVZeilenIndex).Cells(DruckSpalte).Value
    143. content = If(value Is Nothing, "", value.ToString)
    144. cellBox = New RectangleF(PosX, PosY, SpaltenBreiten(DruckSpalte), TextHöhe)
    145. If Not String.IsNullOrEmpty(DGV.Columns(DruckSpalte).DefaultCellStyle.Format.ToString) Then
    146. content = Convert.ToDouble(content).ToString(DGV.Columns(DruckSpalte).DefaultCellStyle.Format.ToString)
    147. End If
    148. If AlternateColor Then
    149. ' Zeilen abwechselnd einfärben
    150. If ((DGVZeilenIndex + DruckZeile) Mod 2 = 0) Then
    151. e.Graphics.FillRectangle(New SolidBrush(RowColor), cellBox)
    152. Else
    153. e.Graphics.FillRectangle(New SolidBrush(RowColorAlternate), cellBox)
    154. End If
    155. End If
    156. If PrintGrating = True Then
    157. e.Graphics.DrawRectangle(Pens.Black, cellBox.X, cellBox.Y, cellBox.Width, cellBox.Height)
    158. End If
    159. Select Case DGV.Columns(DruckSpalte).DefaultCellStyle.Alignment
    160. Case DataGridViewContentAlignment.NotSet, DataGridViewContentAlignment.MiddleLeft
    161. cellBox = New RectangleF(PosX, PosY, SpaltenBreiten(DruckSpalte), TextHöhe)
    162. Case DataGridViewContentAlignment.MiddleRight
    163. PosX1 = CInt(PosX + SpaltenBreiten(DruckSpalte) - (g.MeasureString(content, DGV.Font).Width))
    164. cellBox = New RectangleF(PosX1, PosY, SpaltenBreiten(DruckSpalte), TextHöhe)
    165. Case DataGridViewContentAlignment.MiddleCenter
    166. PosX1 = CInt(PosX + (SpaltenBreiten(DruckSpalte) / 2) - (g.MeasureString(content, DGV.Font).Width / 2))
    167. cellBox = New RectangleF(PosX1, PosY, SpaltenBreiten(DruckSpalte), TextHöhe)
    168. Case Else
    169. cellBox = New RectangleF(PosX, PosY, SpaltenBreiten(DruckSpalte), TextHöhe)
    170. End Select
    171. e.Graphics.DrawString(content, DGV.Font, Brushes.Black, cellBox, sf)
    172. PosX += CInt(SpaltenBreiten(DruckSpalte))
    173. Next
    174. PosX = CInt(borderLeft)
    175. PosY += CInt(TextHöhe)
    176. DruckZeile += 1
    177. Loop Until ((DruckZeile + DGVZeilenIndex) > (dgvMaxRowIndex)) OrElse ((PageHeight + borderTop) < PosY + TextHöhe)
    178. If (DruckZeile + DGVZeilenIndex) > dgvMaxRowIndex Then
    179. ' Tabelle fertig gedruckt
    180. e.HasMorePages = False
    181. Else
    182. ' es sind weitere Zeilen zu drucken
    183. e.HasMorePages = True
    184. DGVZeilenIndex = DruckZeile + DGVZeilenIndex
    185. End If
    186. End Sub
    187. #End Region

    echnaton schrieb:

    aber ich lege mal den aktuellen code bei.
    Fein.
    Was soll ich damit?
    Form_Load, 9 Zeilen Code => 15 Fehler.
    ==> Abbruch.

    RodFromGermany schrieb:

    ansonsten hänge mal Dein Projekt bereinigt (ohne bin, obj- und vs-Ordner) gezippt an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    echnaton schrieb:

    sorry ..sind keine Fehler
    Das ist mir klar.
    Wenn Du möchtest, dass Dir geholfen wird, poste solchen Code, der bei uns problemlos compiliert.
    Erstelle ein kleines Testprojekt, erfinde Ersatzvariablen, gib ihnen die richtigen Werte, so dass Dein Effekt reproduziert wird.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja, vielen Dank für deine Hilfe...
    Ich gebe es auf. Ich werde es mal mit dem Reportviewer versuchen.
    vielleicht ist es damit einfacher eine Tabelle nach meinen wünschen zu drucken.

    also nochmals vielen Dank

    PS: Den Fehler kann man ohne weiteres reproduzieren. Einfach deinen Code nehmen, ein paar zusätzliche columns dazulegen
    Programm starten und schon ist der Fehler da...
    MFG

    echnaton schrieb:

    Einfach deinen Code nehmen, ein paar zusätzliche columns dazulegen Programm starten und schon ist der Fehler da...
    OK, das ist ursprünglich nicht mein Code, ich habe ihn nur für das Forum aufbereitet.
    Die Lösung wäre, den Druck nicht nur auf n Seiten untereinander, sondern noch auf m Seiten nebeneinander aufzuteilen.
    Klar, das ist alles machbar. Aber ist es auch sinnvoll?
    Wie Du schreibst, würdest Du die Daten nach Excel schaufeln und von dort drucken.
    Wenn Du eine .NET-Lösung brauchst, musst Du Dir eine schaffen. Poste sie im Forum, und wenn sie ordentlich funktioniert, bekommst Du von mir einen Hilfreich!-Klick.
    Erwarten, dass andere Deine Probleme lösen, ist keine gute Herangehensweise. Sorry.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!