Πώς εκτυπώνουμε μία λίστα από εγγραφές μίας Access database
Στο παρόν
παράδειγμα, θα δούμε πώς εκτυπώνουμε έναν κατάλογο με συγκεκριμένα στοιχεία
μαθητών, με γραμματοσειρά σταθερού πλάτους. Δηλαδή, θα τυπώνουμε μία γραμμή ανά
μαθητή. Θα επιστρατεύσουμε το αντικείμενο PrintPreviewDialog,
που ενσωματώνει ένα PrintPreview control
για προεπισκόπηση της εκτύπωσης. Στην ιδιότητα Document,
του αντικειμένου PrintPreviewDialog, εκχωρούμε ένα
αντικείμενο PrintDocument (υπάρχει στο Toolbox της VB.NET). Το τελευταίο αποτελεί το βασικό
αντικείμενο που προσφέρει η VB.NET για εκτύπωση εγγράφων. Στο γεγονός PrintPage, τοποθετούμε το σχετικό κώδικα εκτύπωσης
(το rendering εκτύπωσης). Στο δε γεγονός BeginPrint,
αν θέλουμε, τοποθετούμε κώδικα αρχικοποίησης (όπως καθορισμό γραμματοσειρών,
αρχείων δεδομένων κλπ).
Στην παρακάτω
εικόνα βάζουμε σε ένα Datagrid τα στοιχεία των
μαθητών που προέρχονται από ένα DataView ενός πίνακα. Μόλις πατήσουμε το button Προεπισκόπηση εκτύπωσης θα ανοίξει το διπλανό
παράθυρο με τυπωμένη τη λίστα των μαθητών με τα στοιχεία ΕΠΩΝΥΜΟ, ΟΝΟΜΑ,
ΗΜΕΡΟΜ_ΕΓΓΡΑΦΗΣ και ΕΤΟΣ_ΓΕΝΝΗΣΗΣ. Επίσης, δημιουργούμε και αυτόματη αρίθμηση
(για λόγους απλότητας παραλείπουμε τίτλους και επικεφαλίδες). Το παράθυρο αυτό
προσφέρει τις κλασσικές δυνατότητες zoom, μετάβασης
σε ορισμένη σελίδα, επισκόπηση πολλαπλών σελίδων και φυσικά αποστολή στον
εκτυπωτή.
Imports System.Data.OleDb
Imports System.Drawing.Printing
Public Class Form1
Inherits System.Windows.Forms.Form
Dim strConn$ =
"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=ΜΑΘΗΤΕΣ.MDB"
'Tα ADO.NET αντικείμενα για
την πρόσβαση στη ΒΔ.
Dim daAdapter As OleDbDataAdapter
Dim dsMathites As DataSet
Dim MathitesView As DataView
'Το πλήθος των γραμμών (εγγραφών) του View.
Dim NbrOfDataRows%
'Ο αριθμός της τρέχουσας εγγραφής εκτύπωσης. Η πρώτη
έχει θέση 0.
Dim DataRowNbr%
= 0
'Για καθορισμό τύπου στοιχισης
πεδίου.
Private Enum PrintAlignFieldEnum
Left = 1
Center = 2
Right = 3
End Enum
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
'Συνδεση με τη ΒΔ και δημιουργία του DataView για τους μαθητές.
daAdapter = New OleDbDataAdapter("Select * from ΜΑΘΗΤΕΣ
order by ΕΠΩΝΥΜΟ,ΟΝΟΜΑ", strConn)
dsMathites = New DataSet()
daAdapter.Fill(dsMathites,
"tblMathites")
MathitesView = New DataView(dsMathites.Tables("tblMathites"))
'Πάρε το πλήθος των μαθητών.
NbrOfDataRows = MathitesView.Count
'Σύνδεσέ το με το Datagrid
για εμφάνιση των δεδομένων.
DataGrid1.DataSource = MathitesView
End Sub
'-----------------------------------------------------------------------
'Προεπισκόπηση εκτύπωσης και εκτύπωση.
Private Sub btnPrintPreview_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnPrintPreview.Click
Dim PrintPreview As
New PrintPreviewDialog()
PrintPreview.Document = PrintDoc
PrintPreview.StartPosition = FormStartPosition.CenterScreen
PrintPreview.ShowDialog()
End Sub
'-------------------------------------------------------------------------
'Η βασική ρουτίνα για την εκτύπωση (rendering
εκτύπωσης).
Private Sub PrintDoc_PrintPage(ByVal sender As Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs)
_
Handles PrintDoc.PrintPage
Dim LinesPerPage# = 0 'πόσες γραμμές ανά σελίδα.
Dim NbrLine%
= 0 'σε ποιά γραμμή στη σελίδα είμαστε.
Dim LeftMargin# = e.MarginBounds.Left
'αριστερό περιθώριο σελίδας.
Dim TopMargin# = e.MarginBounds.Top
'πάνω περιθώριο σελίδας.
Dim y# = 0 'Η θέση (ως προς το ύψος) της τρέχουσας γραμμής.
Dim strLineData$ = "" 'Η γραμμή με τα δεδομένα της εγγραφής.
'H γραμματοσειρά εκτύπωσης σταθερού πλάτους.
Dim PrintFont As Font = New Font("Courier
new", 9)
'Σε στιγμές οι υπολογισμοί στη σελίδα.
e.Graphics.PageUnit = GraphicsUnit.Point
'Υπολόγισε το πλήθος
των γραμμών ανά σελίδα.
LinesPerPage = e.MarginBounds.Height
/ PrintFont.GetHeight(e.Graphics)
'Τύπωσε μία-μία
εγγραφή μέχρι να γεμίσει η σελίδα.
While NbrLine < LinesPerPage
'Πάρε τη γραμμή η
οποία επιστρέφεται διαμορφωμένη
‘όπως θέλουμε από τη συνάρτηση.
strLineData = GetDataLine()
If strLineData.Length = 0 Then Exit While
'Υπολόγισε το ύψος της
σελίδας στο οποίο θα τυπωθεί η γραμμή.
y = TopMargin
+ NbrLine * PrintFont.GetHeight(e.Graphics)
'Τύπωσέ τη.
e.Graphics.DrawString(strLineData, PrintFont,
_
Brushes.Black, LeftMargin, _
y, New StringFormat())
'Και αύξησε τον αριθμό
γραμμής κατά 1 και
‘τον αριθμό εγγραφής κατά 1.
NbrLine += 1 : DataRowNbr += 1
End While
' Αν υπάρχουν κι άλλες
σελίδες, τύπωσε κι άλλες.
If strLineData.Length > 0 Then
e.HasMorePages = True
Else
e.HasMorePages = False
EndIf
End Sub
'-------------------------------------------------------------------------
'Διαμορφώνει τη γραμμή δεδομένων με τα στοιχεία της
τρέχουσας εγγραφής.
Private Function GetDataLine() As String
Try
If DataRowNbr <= NbrOfDataRows - 1 Then
Dim r As DataRowView =
MathitesView(DataRowNbr)
Dim strLine$ = ""
strLine = PrintAlign(DataRowNbr + 1, 3, _
PrintAlignFieldEnum.Right)
& " "
strLine += PrintAlign(r.Item("ΕΠΩΝΥΜΟ"), 15, _
PrintAlignFieldEnum.Left)
& " "
strLine += PrintAlign(r.Item("ΟΝΟΜΑ"), 10, _
PrintAlignFieldEnum.Center)
& " "
strLine += PrintAlign(r.Item("ΗΜΕΡΟΜ_ΕΓΓΡΑΦΗΣ"), 12, _
PrintAlignFieldEnum.Center) & " "
strLine += PrintAlign(r.Item("ΕΤΟΣ_ΓΕΝΝΗΣΗΣ"), 4, _
PrintAlignFieldEnum.Left)
Return strLine
Else
Return ""
End If
Catch ex As Exception
MsgBox("Πρόβλημα στην εκτύπωση της γραμμής " & _
DataRowNbr & vbCrLf & ex.Message)
Return ""
End Try
End Function
'----------------------------------------------------------------------
'Επιστρέφει το πεδίο στοιχισμένο αριστερά, δεξιά ή
κέντρο στο διαθέσιμο χώρο 'MaxLen. Χρήσιμη ρουτίνα! Ο
υπόλοιπος χώρος που περισσεύει , συμπληρώνεται με 'κενά.
Private Function PrintAlign(ByVal strField$, ByVal MaxLen%, _
ByVal whatAlign As PrintAlignFieldEnum)
_
As String
Dim strReturnField$ =
""
Dim spaces%
'Πάρε όσους χαρακτήρες βρεις…
If strField.Length > MaxLen
Then
strReturnField = strField.Substring(1, MaxLen)
spaces = 0
Else
strReturnField = strField
spaces = MaxLen - strField.Length
End If
'…και για τον υπόλοιπο χώρο γέμισε με κενά.
Select Case whatAlign
Case Is = PrintAlignFieldEnum.Left
strReturnField += FillString(spaces,
" ")
Case Is = PrintAlignFieldEnum.Right
strReturnField = FillString(spaces,
" ") + strReturnField
Case Is = PrintAlignFieldEnum.Center
If (spaces Mod 2) = 0 Then
strReturnField = FillString(spaces / 2, " ") + _
strReturnField + FillString(spaces / 2, " ")
Else
strReturnField = FillString(spaces \ 2 + 1, " ") + _
strReturnField + FillString(spaces \ 2, " ")
End If
End Select
Return strReturnField
End Function
'---------------------------------------------------------------------
'Επιστρέφει ένα string
γεμάτο με τον χαρακτήρα ch, nbr
φορές.
‘Στη VB6 ήταν η String ρουτίνα.
Public Function FillString$(ByVal nbr%, ByVal
ch$)
Dim i%
Dim strReturn$ = ""
For i = 1 To nbr
strReturn += ch
Next
Return strReturn
End Function
End Class
Ο μηχανισμός
εκτύπωσης στη VB.NET διαφέρει ριζικά από αυτόν στη VB6. Παρέχει, σαφώς,
περισσότερες δυνατότητες και το παραπάνω παράδειγμα είναι ένα τυπικό δείγμα
εκτύπωσης με γραμματοσειρά σταθερού πλάτους (πχ. Courier
new). Ωστόσο, δεν δουλεύει καλά με γραμματοσειρές
μεταβλητού πλάτους (π.χ. Arial, Times
Νew Roman κλπ) διότι δεν
επιτυγχάνεται σωστή στοίχιση. Στην περίπτωση αυτή, η στρατηγική είναι λίγο
διαφορετική : Για κάθε γραμμή πρέπει να τυπώνουμε, με τη μέθοδο DrawString, πεδίο-πεδίο. Το κάθε πεδίο θα ξεκινά σε
συγκεκριμένη υπολογισμένη θέση (στον άξονα-x). Δείτε το επόμενο tip που προσφέρει έναν γενικό τρόπο εκτύπωσης με
γραμματοσειρές σταθερού ή μεταβλητού πλάτους.
·
Χρήστος
Μουρατίδης