I am using following code for printing Listview records in vb express 2008.
The code is working fine except a few requirements:
a) The lines at the end of listview " Net Amount, Paid Amout and Balance" need some adjustments. Like upto 45 records of listview these lines are displayed perfectly on one page. When the number of records are 46, only NetAmount and PaidAmount are displayed and when the number of records are 47 only NetAmount is displayed. I think I have a problem in the code segment of HasMorePages. How i can limit that the three lines of " Net Amount, Paid Amout and Balance" are displayed on first page correctly.
b) how i can add a footer to the print preview to display number of pages in the format 1 of 1 , 1 of 2 and so on.
Code:
#Region "Print related declarations"
Protected WithEvents pd As Printing.PrintDocument 'used by Print sub
Protected Ratio As Single = 0, CurrRow As Integer = 0
#End Region
#Region "Simple Printing of ListView"
''' <summary>
''' Print the List view as a simple report
''' </summary>
Public Sub Print()
pd = New Printing.PrintDocument
pd.DocumentName = "Print of " & ListView1.Name
Ratio = 1
CurrRow = 0
pd.Print()
End Sub
''' <summary>
''' Print Preview the List view as a simple report
''' </summary>
Public Sub PrintPreview()
pd = New Printing.PrintDocument
pd.DocumentName = "Print of " & ListView1.Name
Ratio = 1
CurrRow = 0
Dim ppv As New PrintPreviewDialog
ppv.Document = pd
ppv.ShowDialog()
End Sub
Private Sub pd_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles pd.PrintPage
Dim c As ColumnHeader
Dim g As Graphics = e.Graphics
Dim l As Integer = 0 'stores current left
Dim iCount As Integer
Dim f As Font = ListView1.Font
Dim b As Brush = Brushes.Black
Dim currentY As Integer = 0
Dim maxY As Integer = 0
Dim gap As Integer = 1
Dim lvsi As ListViewItem.ListViewSubItem
Dim colLefts(ListView1.Columns.Count) As Integer
Dim colWidths(ListView1.Columns.Count) As Integer
Dim idx As Integer = 0
Dim ii As Integer
Dim lr As RectangleF
e.HasMorePages = False
'Page Settings
Dim PSize As Integer = ListView1.Items.Count
Dim PHi As Double
With pd.DefaultPageSettings
Dim Ps As PaperSize
PHi = PSize * 20 + 350
Ps = New PaperSize("Cust", 800, PHi)
.Margins.Top = 15
.Margins.Bottom = 20
.PaperSize = Ps
End With
'Title
Dim headfont As Font
Dim X1 As Integer
Dim Y As Integer
headfont = New Font("Courier New", 16, FontStyle.Bold)
X1 = pd.DefaultPageSettings.Margins.Left
Y = pd.DefaultPageSettings.Margins.Top + 5
e.Graphics.DrawString("CompanyName", headfont, Brushes.DarkRed, X1 + 80, Y)
e.Graphics.DrawString("Address", headfont, Brushes.Black, X1 + 10, Y + 20)
e.Graphics.DrawString("Telefone: ", headfont, Brushes.Black, X1 + 80, Y + 40)
With pd.DefaultPageSettings
e.Graphics.DrawLine(Pens.Black, 0, Y + 70, e.PageBounds.Width, Y + 70)
End With
'Headings
currentY = 100
For Each c In ListView1.Columns
maxY = Math.Max(maxY, g.MeasureString(c.Text, f, c.Width).Height)
colLefts(idx) = l
colWidths(idx) = c.Width
lr = New RectangleF(colLefts(idx), currentY, colWidths(idx), maxY)
'g.DrawString(c.Text, f, b, lr) ' print all columns including hidden columns
If lr.Width > 0 Then g.DrawString(c.Text, f, b, lr)
l += c.Width
idx += 1
Next
currentY += maxY + gap
g.DrawLine(Pens.Black, 0, currentY, e.PageBounds.Width, currentY)
currentY += gap
'Rows
iCount = ListView1.Items.Count - 1
For ii = CurrRow To iCount
If (currentY + maxY + maxY) > e.PageBounds.Height Then 'jump down another line to see if this line will fit
CurrRow = ii - 1
e.HasMorePages = True
currentY += maxY + gap
e.Graphics.DrawString("Net Amount : ", headfont, Brushes.Black, X1 + 80, currentY)
e.Graphics.DrawString("Paid Amount: ", headfont, Brushes.Black, X1 + 80, currentY + 20)
e.Graphics.DrawString("Balance : ", headfont, Brushes.Black, X1 + 80, currentY + 40)
Exit For 'does next page
End If
l = 0
maxY = 0
idx = 0
For Each lvsi In ListView1.Items(ii).SubItems
maxY = Math.Max(maxY, g.MeasureString(lvsi.Text, f, colWidths(idx)).Height)
lr = New RectangleF(colLefts(idx), currentY, colWidths(idx), maxY)
'g.DrawString(lvsi.Text, f, b, lr)
If lr.Width > 0 Then g.DrawString(lvsi.Text, f, b, lr)
idx += 1
Next
currentY += maxY + gap
Next
e.Graphics.DrawString("Net Amount : ", headfont, Brushes.Black, X1 + 80, currentY)
e.Graphics.DrawString("Paid Amount: ", headfont, Brushes.Black, X1 + 80, currentY + 20)
e.Graphics.DrawString("Balance : ", headfont, Brushes.Black, X1 + 80, currentY + 40)
End Sub
#End Region
Private Sub btnPrintPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintPreview.Click
PrintPreview()
End Sub
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
Print()
End Sub
The code is working fine except a few requirements:
a) The lines at the end of listview " Net Amount, Paid Amout and Balance" need some adjustments. Like upto 45 records of listview these lines are displayed perfectly on one page. When the number of records are 46, only NetAmount and PaidAmount are displayed and when the number of records are 47 only NetAmount is displayed. I think I have a problem in the code segment of HasMorePages. How i can limit that the three lines of " Net Amount, Paid Amout and Balance" are displayed on first page correctly.
b) how i can add a footer to the print preview to display number of pages in the format 1 of 1 , 1 of 2 and so on.