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

Το προηγούμενο tip αναφέρεται στην εκτύπωση με γραμματοσειρά σταθερού πλάτους. Στο παρόν, θα δούμε έναν γενικό τρόπο εκτύπωσης μίας λίστας εγγραφών με γραμματοσειρά σταθερού ή μεταβλητού πλάτους.

Το κλειδί στην όλη υπόθεση είναι να προσδιορίσουμε επακριβώς τα σημεία έναρξης των στηλών στον x-άξονα (οριζόντιο) της σελίδας, με βάση την καθορισμένη μονάδα μέτρησης (pixels ή points). Για το λόγο αυτό, χρησιμοποιούμε έναν πίνακα με όνομα XCoord. Τα πλάτη των στηλών των πεδίων, τα προσδιορίζουμε (σε pixels ή points) σε έναν άλλον πίνακα με όνομα FieldsWidth. Οι δύο πίνακες προφανώς θα έχουν τον ίδιο αριθμό θέσεων. Στον κώδικα, τα σημεία έναρξης των στηλών του XCoord θα υπολογιστούν με βάση τα πλάτη του FieldsWidth. Ως σημείο εκκίνησης της πρώτης στήλης, δηλ. XCoord(0), θα είναι το αριστερό περιθώριο της σελίδας. Να σημειωθεί ότι, αν τα περιεχόμενα μίας στήλης δεν χωρούν στο καθορισμένο πλάτος της τότε αποκόπτονται ώστε να μην "παραβιάσει" το χώρο της επόμενης. Το πλάτος των περιεχομένων ενός πεδίου (στήλης) θα υπολογιστεί με τη μέθοδο MeasureString του αντικειμένου e.Graphics.

Επίσης, στο παρακάτω παράδειγμα, χρησιμοποιούμε Bold style για την αυτόματη αρίθμηση των εγγραφών, και Italic style για το έτος γέννησης.

http://users.sch.gr/mouratx/VB-NET_Tips/DataManagement/Images/PrintData2.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

'Τα fonts για Αυτόματη αρίθμηση, κανονικό, και ειδικά για το έτος γέννησης.
'Αυτά θα οριστούν συγκεκριμένα στο γεγονός BeginPrint του αντικειμένου ‘PrintDocument.
Dim FontAA As Font, FontNormal As Font, FontEtosGen As Font

'Τα πλάτη εκτύπωσης (σε pixels) για κάθε στήλη-πεδίο, ως πίνακας.
‘Κι αυτά, καλό είναι να οριστούν στο γεγονός BeginPrint.
Dim FieldsWidth%(4) '5 πεδία με το ΑΑ. Θέσεις 0-4.

'Πλάτος για το κενό μεταξύ των στηλών.
Dim spaceWidth%

' σημεία έναρξης των στηλών στο 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 οι υπολογισμοί.

' σημεία έναρξης των στηλών στο 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.

Μελετώντας τον κώδικα, μπορεί κάποιος να πάρει ιδέες για να φτιάξει μία δική του μηχανή εκτύπωσης.

 

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