Πώς εκτυπώνουμε μία λίστα από εγγραφές μίας Access database

Στο παρόν παράδειγμα, θα δούμε πώς εκτυπώνουμε έναν κατάλογο με συγκεκριμένα στοιχεία μαθητών, με γραμματοσειρά σταθερού πλάτους. Δηλαδή, θα τυπώνουμε μία γραμμή ανά μαθητή. Θα επιστρατεύσουμε το αντικείμενο PrintPreviewDialog, που ενσωματώνει ένα PrintPreview control για προεπισκόπηση της εκτύπωσης. Στην ιδιότητα Document, του αντικειμένου PrintPreviewDialog, εκχωρούμε ένα αντικείμενο PrintDocument (υπάρχει στο Toolbox της VB.NET). Το τελευταίο αποτελεί το βασικό αντικείμενο που προσφέρει η VB.NET για εκτύπωση εγγράφων. Στο γεγονός PrintPage, τοποθετούμε το σχετικό κώδικα εκτύπωσης (το rendering εκτύπωσης). Στο δε γεγονός BeginPrint, αν θέλουμε, τοποθετούμε κώδικα αρχικοποίησης (όπως καθορισμό γραμματοσειρών, αρχείων δεδομένων κλπ).

Στην παρακάτω εικόνα βάζουμε σε ένα Datagrid τα στοιχεία των μαθητών που προέρχονται από ένα DataView ενός πίνακα. Μόλις πατήσουμε το button Προεπισκόπηση εκτύπωσης θα ανοίξει το διπλανό παράθυρο με τυπωμένη τη λίστα των μαθητών με τα στοιχεία ΕΠΩΝΥΜΟ, ΟΝΟΜΑ, ΗΜΕΡΟΜ_ΕΓΓΡΑΦΗΣ και ΕΤΟΣ_ΓΕΝΝΗΣΗΣ. Επίσης, δημιουργούμε και αυτόματη αρίθμηση (για λόγους απλότητας παραλείπουμε τίτλους και επικεφαλίδες). Το παράθυρο αυτό προσφέρει τις κλασσικές δυνατότητες zoom, μετάβασης σε ορισμένη σελίδα, επισκόπηση πολλαπλών σελίδων και φυσικά αποστολή στον εκτυπωτή.

http://users.sch.gr/mouratx/VB-NET_Tips/DataManagement/Images/PrintData.gif

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"

' 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 που προσφέρει έναν γενικό τρόπο εκτύπωσης με γραμματοσειρές σταθερού ή μεταβλητού πλάτους.

 

·         Χρήστος Μουρατίδης