pdf File Writer Rahmen für bestimmte Zellen einer Tabelle

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

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

    pdf File Writer Rahmen für bestimmte Zellen einer Tabelle

    Hallo ihr lieben
    Ich erzeuge mittels pdf File Writer eine pdf, welche u.a. eine Tabelle ohne Ramen enthält.

    VB.NET-Quellcode

    1. 'Artikeltabelle
    2. Dim table As PdfTable = New PdfTable(_page, _contents, _font, 12.0)
    3. table.TableArea = New PdfRectangle(Leftborder, 50, Leftborder + 170, 190) 'Left, Bottom, Right, Top
    4. table.SetColumnWidth(15, 25, 60, 15, 25, 25)
    5. 'Ränder setzen
    6. table.Borders.SetAllBorders(0.5, Color.White, 0.00, Color.White)
    7. 'Cell Style ändern
    8. table.DefaultCellStyle.Alignment = ContentAlignment.MiddleLeft
    9. Dim centerstyle As PdfTableStyle = table.CellStyle
    10. centerstyle.Alignment = ContentAlignment.MiddleCenter
    11. Dim rightstyle As PdfTableStyle = table.CellStyle
    12. rightstyle.Alignment = ContentAlignment.MiddleRight
    13. 'Zellen beschriften
    14. table.Cell(0).Value = "Menge"
    15. table.Cell(0).Style = centerstyle
    16. table.Cell(1).Value = "Art. Nr."
    17. table.Cell(1).Style = rightstyle
    18. table.Cell(2).Value = "Name"
    19. table.Cell(3).Value = "Mwst."
    20. table.Cell(3).Style = centerstyle
    21. table.Cell(4).Value = "Einzelpreis"
    22. table.Cell(4).Style = rightstyle
    23. table.Cell(5).Value = "Gesamtpreis"
    24. table.Cell(5).Style = rightstyle
    25. table.DrawRow()
    26. '[...]

    Kann ich hier eine Linie einfügen? Also quasi einen Rahmen unter die erste Zeile, oder einen Ramen über der zweiten Zeile?
    @DerSmurf Was sagt die Beschreibung des PDF-File-Writers?
    Schon mal Frau Google befragt? PDF-File-Writer Linie zeichnen
    =>
    pdfannotator.com/de/help/toolslinearrow
    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!
    Natürlich bin ich in der Lage zu googlen, aber inwieweit die Ergebnisse deiner Vorgeschlagenen Google Suche helfen, kannst du bestimmt auch selbst beurteilen...

    DerSmurf schrieb:

    Ich erzeuge mittels pdf File Writer eine pdf, welche u.a. eine Tabelle ohne Ramen enthält.

    nicht mittels pdf annotator - wie in deinem Link.
    Ich habe mir aus der Demo des pdfFileWriters auf codeproject, folgendes zusammengereimt:

    VB.NET-Quellcode

    1. Dim ColumnPosition = table.ColumnPosition
    2. Dim PosY = table.RowTopPosition - 2 * 0.04 - table.DefaultCellStyle.FontAscent + 5
    3. _contents.DrawLine(ColumnPosition(0), PosY, ColumnPosition(6), PosY)

    Ich verstehe aber - mangels Dokumantation - nicht, was da passiert. Und die entstandene Linie ist an den Übergängen der Spalten leicht unterbrochen.

    DerSmurf schrieb:

    Und die entstandene Linie ist an den Übergängen der Spalten leicht unterbrochen.
    Wenn Du schon einiges hast, kannst Du ja mal ein Bildchen posten.
    ====
    Falsche Herangegensweise.
    Warum verwendest Du nicht die Print-Funktionalität vom Framework: Drucken mehrseitiger Dokumente
    und druckst das ganze dann mit Microsoft Print to PDF aus?
    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!

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

    Mein Fehler war, dass ich das Gitternetz der Tabelle nicht entfernt habe, sondern weiß gemacht habe.
    Diese weißen Linien wurden dann auf meiner schwarzen Trennlinie angezeigt und es kommt zu leichten Unterbrechungen der Linie - weil man auf schwarz auf einmal den weißen Rahmen sieht.
    Ich weiß immernoch nicht so recht, was ich hier tue, aber Zeile 6 habe ich geändert in: ​ table.Borders.SetFrame(0, Color.White)
    Gerade hatte ich meine Trennlinien (aus Post 3) allerdings an einer falschen Stelle. Das werde ich aber wohl mit schrittweisem durchgehen behoben bekommen - keine Ahnung.

    @RodFromGermany Deine Variante nutze ich nicht, weil ich sie nicht kannte :o)
    Generell finde ich aber den Print Dialog interessanter, denn in den allermeisten Fällen möchte ich das Ergebnis ohnehin ausdrucken und nicht als pdf speichern.
    Meine mittels pdf File Writer erzeugte PDF, lasse ich direkt im Standartprogramm öffnen, um sie dann zu drucken.
    Da wäre deins schon schöner.

    Ich schmeiße dir hier mal meine pdf Erstellsub ran - auch wenn du den pdf file writer evtl. nicht kennst, sollte klar sein was hier passiert:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. ​Private Sub DrawPdf(Biller1 As List(Of String), Biller2 As List(Of String), Recipient1 As List(Of String), recipient2 As List(Of String),
    2. Invoicedate As List(Of String), Invoicetype As String, Invoicetext As String, ArticleList As List(Of String),
    3. Net7 As Double, Net19 As Double, NetTotal As Double, Tax7 As Double, tax19 As Double, Bruttotal As Double, ShowNetSums As Boolean)
    4. 'Dateiname erstellen
    5. Dim Filename = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\" & "Rechnung vom " & _InvoiceDate.ToString("dd.MM.yyyy") & ".pdf"
    6. 'neues Pdf Dokument erstellen
    7. _document = New PdfDocument(PaperType.A4, False, UnitOfMeasure.mm, Filename)
    8. _font = PdfFont.CreatePdfFont(_document, "Times New Roman", FontStyle.Regular, True)
    9. 'Pdf Dokument beschreiben
    10. Dim FontName As String = "Times New Roman"
    11. Dim TimesNormal = PdfFont.CreatePdfFont(_document, FontName, FontStyle.Regular, True)
    12. 'Neue Seite einfügen
    13. _page = New PdfPage(_document)
    14. 'Inhalt zur Seite hinzufügen
    15. _contents = New PdfContents(_page)
    16. Dim Leftborder As Integer = 20
    17. 'Ausstelleradresse der Rechnung - rechte Seite
    18. Dim BoxBiller1 As TextBox = New TextBox(50, 0.25)
    19. For Each item In Biller1
    20. BoxBiller1.AddText(TimesNormal, 12, item & Environment.NewLine)
    21. Next
    22. _contents.DrawText(Leftborder, 280, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, BoxBiller1)
    23. 'Ausstelleradresse der Rechnung - rechte Seite
    24. Dim BoxBiller2 As TextBox = New TextBox(70, 0.25)
    25. For Each item In Biller2
    26. BoxBiller2.AddText(TimesNormal, 12, item & Environment.NewLine)
    27. Next
    28. _contents.DrawText(Leftborder + 100, 280, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, BoxBiller2)
    29. 'Empfänger der Rechnung - linke Seite
    30. Dim BoxRecipient1 As TextBox = New TextBox(50, 0.25)
    31. For Each item In Recipient1
    32. BoxRecipient1.AddText(TimesNormal, 12, item & Environment.NewLine)
    33. Next
    34. _contents.DrawText(Leftborder, 250, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, BoxRecipient1)
    35. 'Empfänger der Rechnung - rechte Seite
    36. Dim BoxRecipient2 As TextBox = New TextBox(80, 0.25)
    37. For Each item In recipient2
    38. BoxRecipient2.AddText(TimesNormal, 12, item & Environment.NewLine)
    39. Next
    40. _contents.DrawText(Leftborder + 100, 250, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, BoxRecipient2)
    41. 'Rechnungsdatum
    42. Dim BoxDate As TextBox = New TextBox(80, 0.25)
    43. For Each item In Invoicedate
    44. BoxDate.AddText(TimesNormal, 12, item & Environment.NewLine)
    45. Next
    46. _contents.DrawText(Leftborder + 100, 220, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, BoxDate)
    47. 'Rechnungsart
    48. Dim BoxInvoiceType As TextBox = New TextBox(50, 0.25)
    49. BoxInvoiceType.AddText(TimesNormal, 18, Invoicetype & Environment.NewLine)
    50. _contents.DrawText(Leftborder, 220, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, BoxInvoiceType)
    51. 'Rechnungstext
    52. Dim BoxInvoiceText As TextBox = New TextBox(170, 0.25)
    53. BoxInvoiceText.AddText(TimesNormal, 12, Invoicetext & Environment.NewLine)
    54. _contents.DrawText(Leftborder, 205, 0.0, 0, 0.015, 0.05, TextBoxJustify.FitToWidth, BoxInvoiceText)
    55. 'Artikeltabelle
    56. Dim table As PdfTable = New PdfTable(_page, _contents, _font, 12.0)
    57. table.TableArea = New PdfRectangle(Leftborder, 50, Leftborder + 170, 190) 'Left, Bottom, Right, Top
    58. table.SetColumnWidth(15, 25, 60, 15, 25, 25)
    59. 'Ränder setzenW
    60. table.Borders.SetFrame(0, Color.White)
    61. 'Cell Style ändern
    62. table.DefaultCellStyle.Alignment = ContentAlignment.MiddleLeft
    63. Dim centerstyle As PdfTableStyle = table.CellStyle
    64. centerstyle.Alignment = ContentAlignment.MiddleCenter
    65. Dim rightstyle As PdfTableStyle = table.CellStyle
    66. rightstyle.Alignment = ContentAlignment.MiddleRight
    67. Dim leftstyle As PdfTableStyle = table.CellStyle
    68. leftstyle.Alignment = ContentAlignment.MiddleLeft
    69. Dim MultiLineStyle As PdfTableStyle = table.CellStyle
    70. MultiLineStyle.MultiLineText = True
    71. 'Zellen beschriften
    72. table.Cell(0).Value = "Menge"
    73. table.Cell(0).Style = centerstyle
    74. table.Cell(1).Value = "Art. Nr."
    75. table.Cell(1).Style = rightstyle
    76. table.Cell(2).Value = "Name"
    77. table.Cell(3).Value = "Mwst."
    78. table.Cell(3).Style = centerstyle
    79. table.Cell(4).Value = "Einzelpreis"
    80. table.Cell(4).Style = rightstyle
    81. table.Cell(5).Value = "Gesamtpreis"
    82. table.Cell(5).Style = rightstyle
    83. table.DrawRow()
    84. table.Cell(0).Value = ""
    85. table.DrawRow()
    86. For Each article In ArticleList
    87. Dim Articleinfos() As String
    88. Articleinfos = article.Split("~"c)
    89. For i = 0 To Articleinfos.Count - 1
    90. table.Cell(i).Value = Articleinfos(i)
    91. Next
    92. table.Cell(0).Style = centerstyle
    93. table.Cell(1).Style = rightstyle
    94. table.Cell(2).Style = MultiLineStyle
    95. table.Cell(3).Style = centerstyle
    96. table.Cell(4).Style = rightstyle
    97. table.Cell(5).Style = rightstyle
    98. table.DrawRow()
    99. table.Cell(0).Value = ""
    100. table.DrawRow()
    101. Next
    102. Dim ColumnPosition = table.ColumnPosition
    103. Dim PosY = table.RowTopPosition - 2 * 0.04 - table.DefaultCellStyle.FontAscent + 5
    104. _contents.DrawLine(ColumnPosition(0), PosY, ColumnPosition(6), PosY)
    105. table.DrawRow()
    106. If ShowNetSums Then
    107. table.Cell(2).Value = "Netto - Betrag"
    108. table.Cell(2).Style = leftstyle
    109. table.Cell(5).Value = NetTotal.ToString("#,##0.00 €")
    110. table.DrawRow()
    111. table.DrawRow()
    112. If Net7 > 0 Then
    113. table.Cell(2).Value = "7% Mwst. auf"
    114. table.Cell(2).Style = rightstyle
    115. table.Cell(4).Value = Net7.ToString("#,##0.00 €")
    116. table.Cell(4).Style = rightstyle
    117. table.Cell(5).Value = Tax7.ToString("#,##0.00 €")
    118. table.DrawRow()
    119. End If
    120. If Net19 > 0 Then
    121. table.Cell(2).Value = "19% Mwst. auf"
    122. table.Cell(2).Style = rightstyle
    123. table.Cell(4).Value = Net19.ToString("#,##0.00 €")
    124. table.Cell(4).Style = rightstyle
    125. table.Cell(5).Value = tax19.ToString("#,##0.00 €")
    126. table.DrawRow()
    127. End If
    128. table.Cell(0).Value = ""
    129. table.DrawRow()
    130. ColumnPosition = table.ColumnPosition
    131. PosY = table.RowTopPosition - 2.0 * 0.04 - table.DefaultCellStyle.FontAscent + 5
    132. _contents.DrawLine(ColumnPosition(0), PosY, ColumnPosition(6), PosY)
    133. End If
    134. table.Cell(2).Value = "Endsumme"
    135. table.Cell(2).Style = leftstyle
    136. table.Cell(5).Value = Bruttotal.ToString("#,##0.00 €")
    137. table.DrawRow()
    138. table.Close()
    139. _document.CreateFile()
    140. Process.Start(Filename)
    141. End Sub


    Die Sub hat so viele Parameter, damit es möglich ist - Warenausgangsrechnung, Wareneingangsrechnung, Angebot und Artikelrückgabe, mit der gleichen Sub zu verarbeiten und eine entsprechende PDF zu erstellen.
    Die Daten werden dabei in der entsprechenden Aufrufsub gesammelt und validiert.

    Herzstück ist das erstellen der Artikeltabelle - Zu Tabellen finde ich aber in deinem Tutorial nichts. Hast du da noch was für mich?
    @DerSmurf Bei der Verwendung von PrintDocument hast Du nur ein Mal den Aufwand und kannst es speichern und / oder drucken.
    Mit dem PDF-Writer musst Du das Dokument in jedem Falle noch mal in die Hand nehmen, wenn Du die Papier-Version brauchst.
    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!

    RodFromGermany schrieb:

    Mit dem PDF-Writer musst Du das Dokument in jedem Falle noch mal in die Hand nehmen, wenn Du die Papier-Version brauchst.

    Da ich die Papierversion immer brauche und nur sehr selten die pdf, finde ich deinen Ansatz ja so interessant.

    DerSmurf schrieb:

    Herzstück ist das erstellen der Artikeltabelle - Zu Tabellen finde ich aber in deinem Tutorial nichts. Hast du da noch was für mich?


    Edit: Die Alternative ist, dass ich die erstellte pdf in einem WebView2 anzeigen lasse. Hier habe ich ja dann auch die druck - und sogar eine Emailfunktion.

    Und edit nr2. Ich habe noch ein Youtube Tutorial gefunden, ich denke das könnte mir auch helfen - weil schön umfangreich: youtube.com/watch?v=yeR_q7kdYsI
    Also werde ich heute Abend mal ein Demoprojekt erstellen und mir eben dieses Video und dein Tutorial zu Gemüte führen.
    @RodFromGermany Ich versuche so weit wie möglich zu kommen, wäre aber dankbar, wenn du mir ggf. helfen könntest.
    Außerdem würde ich dir gerne das fertige Ergebnis präsentieren, damit du einmal gucken kannst, ob alles was ich so gemacht habe, Sinn macht :o)

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

    @DerSmurf Ich habe mal den Druck einer Tabelle meinem Print-Tutorial hinzugefügt, da müssen wir nun warten, bis es freigeschaltet ist.
    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!
    Soho
    Ich habe das ganze jetzt mal ungefähr so, wie vorher mit dem Pdf FIle Writer. Es fehlen nur noch die Artikel in meiner pdf - und die Unterstützung für Mehrseitigkeit.
    Soweit lad ich hier mal meine Demo hoch.
    In der Original Solution habe ich in der Sub ​CreateInvoice die Daten validiert und gesammelt und mittels ​DrawPdf in eine Pdf geschrieben.
    Die CreateInvoice Sub habe ich hier in der Demo mal dringelassen.

    Zwei Fragen habe ich soweit erstmal.
    1. wie findest du die Umsetzung bis hier her
    2. Um die Artikel auszugeben, würdest du da überhaupt eine Tabelle verwenden, oder das ganze einfach "normal" mittels e.Graphics.DrawString aufs Blatt bringen?
    Ich habe gesehen, dass ich die Textausrichtung festlegen kann, also mit ein bisschen gefummel, gehts ja auch ohne Tabelle, denke ich.

    Ich habe noch eine fertige Rechnung angehängt. So ungefähr sollte das am Ende aussehen.
    Dateien
    @DerSmurf Ich empfehle Dir, ein jeues Projekt zu beginnen und das Dokument zeilenweise aufzubauen.
    Auch Zelleninhalte einer Tabelle werden mit e.Graphics.DrawString() gedruckt, der Aufwand besteht ja darin, dee Inhalt der Tabelle positionsrichtig zu Papier zu bringen.
    Du brauchst Zeilen und Spalten, wenn es elegant werden soll, arbeitest Du mit StringFormat für zentriert, links- und rechtsbündig usw., das ist sehr mächtig.
    Mach für Teilaufgaben je ein separates Projekt, wo Du das einzeln untersuchen kannst (z.B. StringFormat).
    Wenn Du es verstanden hast und alles so läuft, wie Du es Dir vorstellst, pack es in Dein "Hauptprogramm".
    Führe flaggesteuert einen Leerdruck durch, wo Du nur die Zeilen zählst, so dass Du Deine Seitensteuerung optimieren kannst.
    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!
    @DerSmurf Du sollst nicht sofort das komplette Dokument fertig stylen, sondern jede einzelne Zeile oder Zeilengruppe einzeln stylen, bevor Du die nächste Zeile / Zeilengruppe anfasst.
    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!
    Ah OK. Das bekomm ich hin - auchz wangsweise, weil ich mir noch nicht vorstellen kann, wo der Text bei verschiedenen Koordinaten landet.
    Wenn der Text meiner "Tabelle" dann rechtsbündig wird, wirds ja nochmal schwerer.
    Da muss ich eh immer erste 10 mal die Koordinaten ändern, bis es halbwegs passt.

    Was sagst du hierzu? Ist mein "CodestiL" soweit i.O.?

    DerSmurf schrieb:

    1. wie findest du die Umsetzung bis hier her

    DerSmurf schrieb:

    "CodestiL"

    RodFromGermany schrieb:

    Ich empfehle Dir, ein jeues Projekt zu beginnen und das Dokument zeilenweise aufzubauen.
    Bei links- und rechtsbündig musst Du nur das Prinzip verstehen, deswegen sollst Du ja ein separates Testprogramm dafür machen.
    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!
    @RodFromGermany

    Ich denke smurf möchte das PDF deshalb direkt zusammenstellen, da es damit erstens skalierbar ist und zweitens nicht so viel Dateigröße einnimmt als ein als PDF gedrucktes, im Speicher zusammengestelltes Bild. Zudem benötigt man bei Deiner Variante immer einen PDF-Drucker, der aber nicht auf jedem System verfügbar ist und wo man auch oft die Kontrolle an externe Tasks abgeben muss. Daher ist das direkte zusammenstellen von PDFs in solchen Fällen immer die sauberste Variante. Das ist ein Thema wo ich bereits viele Jahre in der Praxis Erfahrung sammeln konnte.

    @smurf
    Hast Du Dir schon mal die Komponente VPE Control (Virtual Print Enginge) angesehen?
    idealsoftware.com/de/pdf-library/report-engine.html
    Die kostet zwar ein paar Euro, bietet aber alles um PDF Dateien einfach und mit wenig Code zu erstellen.
    Ich verwende diese Komponente nun bereits sein über 8 Jahren immer in der aktuellsten Version und erstelle damit alle meine Formulare. Egal ob Rechnungen, Berichte oder andere PDF-Dokumente.
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Moin

    dive26 schrieb:

    Ich denke smurf möchte das PDF deshalb direkt zusammenstellen

    Das ist falsch.
    Ich habe das pdf direkt zusammengestellt, da ich mit der pdf file writer dll schon mal gearbeitet habe und es an anderer Stelle nutze.
    In diesem Fall hier möchte ich KEINE PDF erstellen, sondern ausdrucken - auf Papier.
    Hier brauche ich später nicht mal mehr die PrintPreview. Das Erstellte kann direkt an den Drucker gesendet werden.
    In sehr sehr seltenen Ausnahmen, brauche ich nur eine PDF - dieser Fall kann vernachlässigt werden, da wie gesagt sehr selten.
    Da tuts dann der PDF Printer.

    RodFromGermany schrieb:

    Bei links- und rechtsbündig musst Du nur das Prinzip verstehen, deswegen sollst Du ja ein separates Testprogramm dafür machen.

    logisch. Mir ging es um den Code, den ich bereits erstellt habe - also die Demo Solution.
    Mit viel viel rumprobieren, hab ichs nun hinbekommen. Eine Beispiel pdf hängt an. Ich muss das ganze mal zu Papier bringen und ein Linieal an die Tabelle halten, damit es wirklich alles passt - aber erstmal kann sich das Ergebnis sehen lassen.
    Hier der Erstellcode:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub DrawPdf(sender As Object, e As Printing.PrintPageEventArgs, Biller1 As List(Of String), Biller2 As List(Of String), Recipient1 As List(Of String),
    2. recipient2 As List(Of String), Invoicedate As List(Of String), Invoicetype As String, Invoicetext As String, ArticleList As List(Of String),
    3. Net7 As Double, Net19 As Double, NetTotal As Double, Tax7 As Double, tax19 As Double, Bruttotal As Double, ShowNetSums As Boolean)
    4. Dim xlinks As Integer = 100
    5. Dim xrechts As Integer = 500
    6. Dim y As Integer = 30
    7. Dim yStart As Integer = y
    8. Dim TextFont As Font = New Font("times new roman", 12)
    9. Dim HeaderFont As Font = New Font("times new roman", 18)
    10. Dim TableFont As Font = New Font("times new roman", 12)
    11. Dim textrechts As New StringFormat
    12. textrechts.Alignment = StringAlignment.Far
    13. Dim TextLinks As New StringFormat
    14. TextLinks.Alignment = StringAlignment.Near
    15. Dim TextMitte As New StringFormat
    16. TextMitte.Alignment = StringAlignment.Center
    17. Dim TextFormat As New StringFormat
    18. 'Ausstelleradresse der Rechnung - linke Seite
    19. For Each item In Biller1
    20. e.Graphics.DrawString(item, TextFont, Brushes.Black, New Point(xlinks, y))
    21. y += 20
    22. Next
    23. y = yStart
    24. 'Ausstelleradresse der Rechnung - rechte Seite
    25. For Each item In Biller2
    26. e.Graphics.DrawString(item, TextFont, Brushes.Black, New Point(xrechts, y))
    27. y += 20
    28. Next
    29. y += 70
    30. yStart = y
    31. 'Empfänger der Rechnung - linke Seite
    32. For Each item In Recipient1
    33. e.Graphics.DrawString(item, TextFont, Brushes.Black, New Point(xlinks, y))
    34. y += 20
    35. Next
    36. Dim yTemp = y + 50
    37. y = yStart
    38. 'Empfänger der Rechnung - rechte Seite
    39. For Each item In recipient2
    40. e.Graphics.DrawString(item, TextFont, Brushes.Black, New Point(xrechts, y))
    41. y += 20
    42. Next
    43. y = yTemp
    44. 'Rechnungsart
    45. e.Graphics.DrawString(Invoicetype, HeaderFont, Brushes.Black, New Point(xlinks, y))
    46. 'Rechnungsdatum
    47. For Each item In Invoicedate
    48. e.Graphics.DrawString(item, TextFont, Brushes.Black, New Point(xrechts, y))
    49. y += 20
    50. Next
    51. y += 30
    52. 'Rechnungstext
    53. e.Graphics.DrawString(Invoicetext, TextFont, Brushes.Black, New Point(xlinks, y))
    54. y += 50
    55. 'Artikeltabelle
    56. Dim Row_Position As Single = 0
    57. Dim RowHeight As Single = CType(e.Graphics.MeasureString("W", TableFont).Height * 1.25, Single)
    58. Dim Colcounter As Integer = 1
    59. Dim RowCounter As Integer = 1
    60. Dim x As Integer
    61. For Each article In ArticleList
    62. Dim cols() As String = Split(article, "~"c)
    63. For i = 0 To cols.Length - 1
    64. If RowCounter = 1 Then
    65. Select Case Colcounter
    66. Case = 1 : x = xlinks
    67. Case = 2 : x = xlinks + 80
    68. Case = 3 : x = xlinks + 150
    69. Case = 4 : x = xlinks + 410
    70. Case = 5 : x = xlinks + 480
    71. Case = 6 : x = xlinks + 580
    72. Case Else : x = xlinks + 100
    73. End Select
    74. TextFormat = TextLinks
    75. Else
    76. Select Case Colcounter
    77. Case = 1
    78. TextFormat = textrechts
    79. x = xlinks + 40
    80. Case = 2
    81. TextFormat = textrechts
    82. x = xlinks + 130
    83. Case = 3
    84. TextFormat = TextLinks
    85. x = xlinks + 150
    86. Case = 4
    87. TextFormat = TextLinks
    88. x = xlinks + 435
    89. Case = 5
    90. TextFormat = textrechts
    91. x = xlinks + 560
    92. Case = 6
    93. TextFormat = textrechts
    94. x = xlinks + 670
    95. Case Else
    96. TextFormat = TextLinks
    97. x = xlinks + 100
    98. End Select
    99. End If
    100. e.Graphics.DrawString(cols(i), TableFont, System.Drawing.Brushes.Black, x, y + Row_Position, TextFormat)
    101. Colcounter += 1
    102. Next
    103. Row_Position += RowHeight
    104. Colcounter = 1
    105. RowCounter += 1
    106. Next
    107. y += CInt(Row_Position)
    108. e.Graphics.DrawRectangle(Pens.Black, xlinks, y, 670, 1)
    109. y += 10
    110. Dim x1 = xlinks + 150
    111. Dim x2 = xlinks + 310
    112. 'Netto Text
    113. e.Graphics.DrawString("Netto - Betrag", TextFont, Brushes.Black, New Point(x1, y))
    114. e.Graphics.DrawString(NetTotal.ToString("#,##0.00 €"), TextFont, Brushes.Black, New Point(xlinks + 670, y), textrechts)
    115. y += 20
    116. e.Graphics.DrawString("7% Mwst auf", TextFont, Brushes.Black, New Point(x2, y))
    117. e.Graphics.DrawString(Net7.ToString("#,##0.00 €"), TextFont, Brushes.Black, New Point(xlinks + 560, y), textrechts)
    118. e.Graphics.DrawString(Tax7.ToString("#,##0.00 €"), TextFont, Brushes.Black, New Point(xlinks + 670, y), textrechts)
    119. y += 20
    120. e.Graphics.DrawString("19% Mwst auf", TextFont, Brushes.Black, New Point(x2, y))
    121. e.Graphics.DrawString(Net19.ToString("#,##0.00 €"), TextFont, Brushes.Black, New Point(xlinks + 560, y), textrechts)
    122. e.Graphics.DrawString(tax19.ToString("#,##0.00 €"), TextFont, Brushes.Black, New Point(xlinks + 670, y), textrechts)
    123. y += 25
    124. e.Graphics.DrawRectangle(Pens.Black, xlinks, y, 670, 1)
    125. y += 10
    126. e.Graphics.DrawString("Endsumme", TextFont, Brushes.Black, New Point(x1, y))
    127. e.Graphics.DrawString(Bruttotal.ToString("#,##0.00 €"), TextFont, Brushes.Black, New Point(xlinks + 670, y), textrechts)
    128. End Sub


    Eine Frage habe ich aber noch:
    Im pdf File Write kann ich einstellen, dass ein automatischer Zeilenumbruch erfolgt, wenn der Text zu lang für eine Zelle ist. Das geht ja hier so in der Form nicht.
    Ich würde nun mal testen wie viele "m" ich z.B. beim Artikelnamen in eine Zeile bekomme und dann entweder manuell einen Zeilenumbruch einfügen, oder abschneiden (je nachdem wie viele Zeichen passen).
    Oder gibt es da eine elegantere Lösung?

    Zur Mehrseitigkeit:

    RodFromGermany schrieb:

    Führe flaggesteuert einen Leerdruck durch, wo Du nur die Zeilen zählst, so dass Du Deine Seitensteuerung optimieren kannst.

    Das verstehe ich nicht ganz. Bzw. ich finde keine Lösung, wie ich das Beispiel in deinem Tutorial auf meine Anwendung hier passend bekomme, denn ich habe ja keinen String, wo ich nur die Zeichen zählen muss.
    Außerdem hätte ich gerne den Teil ab "Netto - Betrag" (unter der ersten Linie) immer zusammenhängend.
    Wenn also der Seitenumbruch z-B. eine Zeile unter "7" Mwst auf" entstünde, würde ich diesen gerne schon vorher durchführen, sodass die nächste Seite mit "Netto - Betrag" beginnt
    Wäre es da eine Option zu schauen, wie tief die Tabelle runter kann, bis es nicht mehr auf eine Seite passt und dann manuell einen Seitenumbruch einzufügen?
    Also:

    VB.NET-Quellcode

    1. if y + Row_Position = 450 then ' wenn 450 die Grenze auf der y Achse ist
    2. '"neue Seite einfügen"
    3. End if
    Dateien
    • Rechnung.pdf

      (105,46 kB, 287 mal heruntergeladen, zuletzt: )

    DerSmurf schrieb:

    denn ich habe ja keinen String, wo ich nur die Zeichen zählen muss.

    RodFromGermany schrieb:

    Die Herangehensweise ist, für jede Spalte die maximal erforderliche Breite zu bestimmen. Dazu bedienen wir uns Graphics.MeasureString(), jede einzelne Zelle wird veremessen.

    VB.NET-Quellcode

    1. ' *** Breite das Textes im Spaltenkopf als Mindestbreite
    2. ZellInhalt = dgvTabelle.Columns(DGVSpalte).HeaderText
    3. Dim Breite = g.MeasureString(ZellInhalt, dgvTabelle.Font).Width + ZellPadding
    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!
    Also in der dritten Spalte habe ich wie folgt herausgefunden, dass die maximale Breite 270 betragen darf:

    VB.NET-Quellcode

    1. ​If Colcounter = 3 Then
    2. Dim CellWidth = e.Graphics.MeasureString(cols(i), TableFont).Width
    3. MessageBox.Show(CellWidth.ToString)
    4. End If
    5. e.Graphics.DrawString(cols(i), TableFont, System.Drawing.Brushes.Black, x, y + Row_Position, TextFormat)


    Aber ich finde keine Eigenschaft der DrawString Methode mit der ich die maximale Breite festlegen kann.
    Wie kürze ich meinen Text also auf diese Länge?