Πώς εκτυπώνουμε μία λίστα εγγραφών από μία Access database
(γενικός τρόπος)
Το προηγούμενο tip αναφέρεται στην εκτύπωση με γραμματοσειρά σταθερού
πλάτους. Στο παρόν, θα δούμε έναν γενικό τρόπο εκτύπωσης μίας λίστας
εγγραφών με γραμματοσειρά σταθερού ή μεταβλητού πλάτους.
Το κλειδί στην
όλη υπόθεση είναι να προσδιορίσουμε επακριβώς τα σημεία έναρξης των στηλών στον
x-άξονα (οριζόντιο) της σελίδας, με βάση την καθορισμένη μονάδα μέτρησης (pixels ή points). Για το λόγο
αυτό, χρησιμοποιούμε έναν πίνακα με όνομα XCoord.
Τα πλάτη των στηλών των πεδίων, τα προσδιορίζουμε (σε pixels
ή points) σε έναν άλλον πίνακα με όνομα FieldsWidth. Οι δύο πίνακες προφανώς θα έχουν τον
ίδιο αριθμό θέσεων. Στον κώδικα, τα σημεία έναρξης των στηλών του XCoord θα υπολογιστούν με βάση τα πλάτη του FieldsWidth. Ως σημείο εκκίνησης της πρώτης στήλης, δηλ. XCoord(0), θα είναι το αριστερό περιθώριο της σελίδας. Να
σημειωθεί ότι, αν τα περιεχόμενα μίας στήλης δεν χωρούν στο καθορισμένο πλάτος
της τότε αποκόπτονται ώστε να μην "παραβιάσει" το χώρο της επόμενης.
Το πλάτος των περιεχομένων ενός πεδίου (στήλης) θα υπολογιστεί με τη μέθοδο MeasureString του αντικειμένου e.Graphics.
Επίσης, στο
παρακάτω παράδειγμα, χρησιμοποιούμε Bold style για την αυτόματη αρίθμηση των εγγραφών, και Italic style για το έτος
γέννησης.
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
'Τα fonts για Αυτόματη
αρίθμηση, κανονικό, και ειδικά για το έτος γέννησης.
'Αυτά θα οριστούν συγκεκριμένα στο γεγονός BeginPrint
του αντικειμένου ‘PrintDocument.
Dim FontAA
As Font, FontNormal As Font,
FontEtosGen As Font
'Τα πλάτη εκτύπωσης (σε pixels)
για κάθε στήλη-πεδίο, ως πίνακας.
‘Κι αυτά, καλό είναι να οριστούν στο γεγονός BeginPrint.
Dim FieldsWidth%(4)
'5 πεδία με το ΑΑ. Θέσεις 0-4.
'Πλάτος για το κενό μεταξύ των στηλών.
Dim spaceWidth%
'Tα σημεία έναρξης των
στηλών στο x-άξονα.
‘Θα υπολογιστούν μετά τους ορισμούς για τα πλάτη.
Dim XCoord%(4)
'--------------------------------------------------------------------
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
'------------------------------------------------------------------
'Αρχικοποίηση εκτύπωσης. Συνήθως καθορισμός fonts.
Private Sub PrintDoc_BeginPrint(ByVal sender As Object,_
ByVal e As System.Drawing.Printing.PrintEventArgs)_
Handles PrintDoc.BeginPrint
'Γραμματοσειρές μεταβλητού πλάτους για τα πεδία.
FontAA = New Font("Arial",
10, FontStyle.Bold)
FontNormal = New Font("Arial", 9)
FontEtosGen = New Font("Arial", 9, FontStyle.Italic)
'Όρισε τα πλάτη των
στηλών-πεδίων , σε pixels.
FieldsWidth(0) = 100 'Για ΑΑ
FieldsWidth(1) = 400 'Για Eπώνυμο
FieldsWidth(2) = 300 'Για Όνομα
FieldsWidth(3) = 250 'Για Ημερ/νία εγγραφής.
FieldsWidth(4) = 150 'Για Έτος γέννησης.
'Πλάτος για το κενό
μεταξύ των στηλών.
spaceWidth = 5 'pixels.
End Sub
'-----------------------------------------------------------------
'Η βασική ρουτίνα για την εκτύπωση.
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 LinePrinted As
Boolean = False
e.Graphics.PageUnit = GraphicsUnit.Pixel 'Σε pixels οι υπολογισμοί.
'Tα
σημεία έναρξης των στηλών στο x-άξονα.
XCoord(0) = LeftMargin 'Για το ΑΑ.
Dim i%
For i = 1 To 4 'Για τα υπόλοιπα πεδία.
XCoord(i) = XCoord(i - 1) + FieldsWidth(i - 1) + spaceWidth
Next
'Υπολόγισε το πλήθος
των γραμμών ανά σελίδα.
LinesPerPage = e.MarginBounds.Height
/ FontAA.GetHeight(e.Graphics)
'Τύπωσε μία-μία
εγγραφή μέχρι να γεμίσει η σελίδα.
While NbrLine < LinesPerPage
'Υπολόγισε τό ύψος της σελίδας στο οποίο θα τυπωθεί η γραμμή.
y = TopMargin
+ NbrLine * FontAA.GetHeight(e.Graphics)
'Εφόσον, υπάρχει κι
άλλη εγγραφή, τύπωσέ τη, αλλιώς τέρμα.
LinePrinted = PrintLine(y,
e)
If Not LinePrinted Then Exit While
'Και αύξησε τον αριθμό
γραμμής κατά 1
‘και τον αριθμό εγγραφής κατά 1.
NbrLine += 1 : DataRowNbr += 1
End While
'Αν υπάρχουν κι άλλες
σελίδες, τύπωσε κι άλλες.
If LinePrinted Then
`e.HasMorePages
= True
Else
e.HasMorePages = False
EndIf
End Sub
'--------------------------------------------------------------------
'Τυπώνει μία γραμμή με τα πεδία της εγγραφής που
θέλουμε.
Private Function PrintLine(ByVal y#, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs)
_
As Boolean
Try
If DataRowNbr <= NbrOfDataRows - 1 Then
'Πάρε την εγγραφή.
Dim r As DataRowView = MathitesView(DataRowNbr)
'Τύπωσε τα πεδία στοιχισμένα.
PrintFieldAlign(DataRowNbr
+ 1, 0, FontAA, _
PrintAlignFieldEnum.Right,
y, e)
PrintFieldAlign(r.Item("ΕΠΩΝΥΜΟ"), 1, FontNormal,
_
PrintAlignFieldEnum.Left, y, e)
PrintFieldAlign(r.Item("ΟΝΟΜΑ"), 2, FontNormal,_
PrintAlignFieldEnum.Center,
y, e)
PrintFieldAlign(r.Item("ΗΜΕΡΟΜ_ΕΓΓΡΑΦΗΣ"), 3, FontNormal, _
PrintAlignFieldEnum.Right, y, e)
PrintFieldAlign(r.Item("ΕΤΟΣ_ΓΕΝΝΗΣΗΣ"), 4, FontEtosGen, _
PrintAlignFieldEnum.Right, y, e)
Return True
Else
Return False
End If
Catch ex As Exception
MsgBox("Πρόβλημα στην εκτύπωση της γραμμής " & DataRowNbr
& _
vbCrLf
& ex.Message)
Return False
End Try
End Function
'---------------------------------------------------------------
'Επιστρέφει το πεδίο στοιχισμένο αριστερά, δεξιά ή
κέντρο στο διαθέσιμο χώρο MaxLen.
‘Χρήσιμη ρουτίνα! Ο υπόλοιπος χώρος που περισσεύει , συμπληρώνεται με κενά.
Private Function PrintFieldAlign(ByVal strField$, ByVal nbrField%, _
ByVal whatFont As Font, ByVal whatAlign As PrintAlignFieldEnum, _
ByVal y#, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
_
As String
Dim rect As
RectangleF 'Το πλαίσιο εντός του
οποίου θα τυπωθεί το πεδίο.
Dim x# 'Το σημείο έναρξης εκτύπωσης του πεδίου στη στήλη.
'Υπολόγισε το πλάτος που πιάνουν οι χαρακτήρες του πεδίου με βάση το Font.
'Αν είναι παραπάνω, περιορίσου σε αυτό που έχει οριστεί για τη στήλη.
Dim fldWidth As SizeF =
e.Graphics.MeasureString(strField, whatFont,
_
FieldsWidth(nbrField))
'Υπολόγισε, τώρα, το
σημείο έναρξης της εκτύπωσης στη στήλη με βάση τη στοίχιση.
Select Case whatAlign
Case Is = PrintAlignFieldEnum.Left
x = XCoord(nbrField)
Case Is = PrintAlignFieldEnum.Right
x = XCoord(nbrField)
+ FieldsWidth(nbrField) - fldWidth.Width
Case Is = PrintAlignFieldEnum.Center
x = XCoord(nbrField)
+ FieldsWidth(nbrField) / 2
- fldWidth.Width / 2
End Select
'Υπολόγισε το πλαίσιο
εντός του οποίου θα τυπωθεί το πεδίο.
With rect
.X = x : .Y = y
.Width = fldWidth.Width : .Height = whatFont.GetHeight(e.Graphics)
End With
'Τύπωσέ το.
e.Graphics.DrawString(strField, whatFont,
Brushes.Black, rect)
End Function
'---------------------------------------------------------------
End Class
Να έχετε υπόψη
ότι στον καθορισμό της θέσης έναρξης μίας στήλης XCoord(i)
θα πρέπει να ελέγξετε μην υπερβεί το δεξί περιθώριο της σελίδας. Ελέγξτε τη
θέση σε σχέση με την τιμή e.MarginBounds.Right, στο
γεγονός PrintPage.
Μελετώντας τον
κώδικα, μπορεί κάποιος να πάρει ιδέες για να φτιάξει μία δική του μηχανή εκτύπωσης.
·
Χρήστος
Μουρατίδης