Riporto l'articolo scritto per il sito http://www.iprogrammatori.it/articoli/programmazione/art_stampa-di-un-controllo-datagridview-vbne_1050.aspx
Introduzione.
Con quest’articolo si conclude la serie dedica alla gestione della stampa tramite la tecnologia .Net 4.
In quest’ultima parte vedremo come stampare un controllo datagridview tramite il linguaggio di programmazione Visual Basic Net 2010.
Dopo aver creato un nuovo progetto di tipo Windows Application, per il liguaggio Visual Basic, aggiungiamo nella form, tre pulsanti,un controllo datagridview, un controllo printdocument, printDialog, e printPreviewdialog, il tutto come mostrato in figura 1.
Figura 1
Stesura di codice
Ora passiamo in visualizzazione codice, si deve creare una classe (da esplora soluzione, tasto destro sul nome del progetto, nuova classe) che avrà il compito di gestire il controllo datagridView e la relativa stampa.
Qui di seguito si riporta il codice completo di tale classe.
Imports System.Drawing.Printing
Public Class StampaDatagrid
Private PrdPrintDocument As PrintDocument
Private dttTAbella As DataTable
Private dtgDatagrid As DataGridView
Public intContaRighe As Integer = 0
Private Const CintLineaVerticale As Integer = 10
Public IntNumeroPagina As Integer = 1
Public Arrlinee As ArrayList = New ArrayList()
Public intLarghezza As Integer
Public intAltezza As Integer
Public intMargineSuperiore As Integer
Public intMargineInferiore As Integer
'costruttore della classe
Public Sub New(ByVal dtgDatagridCostruttore As DataGridView, ByVal prdPrintDocumentCostruttore As PrintDocument, ByVal DttTAbleCostruttore As DataTable)
'imposto i parametri dell'anteprima di stampa
PrdPrintDocument = prdPrintDocumentCostruttore
dttTAbella = DttTAbleCostruttore
dtgDatagrid = dtgDatagridCostruttore
intLarghezza = PrdPrintDocument.DefaultPageSettings.PaperSize.Width
intAltezza = PrdPrintDocument.DefaultPageSettings.PaperSize.Height
intMargineSuperiore = PrdPrintDocument.DefaultPageSettings.Margins.Top
intMargineInferiore = PrdPrintDocument.DefaultPageSettings.Margins.Bottom
End Sub
'funzione per il disegno dell'intestazione
Public Sub DisegnaIntestazione(ByVal g As Graphics)
Dim ForeBrush As SolidBrush = New SolidBrush(dtgDatagrid.ColumnHeadersDefaultCellStyle.ForeColor)
Dim BackBrush As SolidBrush = New SolidBrush(dtgDatagrid.ColumnHeadersDefaultCellStyle.BackColor)
Dim TheLinePen As Pen = New Pen(dtgDatagrid.GridColor, 1)
Dim FormatoCella As StringFormat = New StringFormat()
FormatoCella.Trimming = StringTrimming.EllipsisCharacter
FormatoCella.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit
Dim intLarghezzaColonna As Integer = intLarghezza / dttTAbella.Columns.Count
Dim IntInizioContaRighe As Integer = intContaRighe
'Disegno l'intestazione
Dim IntXposizione As Single = dtgDatagrid.Location.X
Dim nextcellbounds As RectangleF = New RectangleF(0, 0, 0, 0)
Dim HeaderBounds As RectangleF = New RectangleF(0, 0, 0, 0)
HeaderBounds.X = dtgDatagrid.Location.X
HeaderBounds.Y = dtgDatagrid.Location.Y + intMargineSuperiore + (intContaRighe - IntInizioContaRighe) * (dtgDatagrid.Font.SizeInPoints + CintLineaVerticale)
HeaderBounds.Height = dtgDatagrid.Font.SizeInPoints + CintLineaVerticale
HeaderBounds.Width = intLarghezza
g.FillRectangle(BackBrush, HeaderBounds)
Dim k As Integer
For k = 0 To dttTAbella.Columns.Count - 1 Step k + 1
Dim nextcolumn As String = dttTAbella.Columns(k).ToString()
Dim cellbounds As RectangleF = New RectangleF(IntXposizione, dtgDatagrid.Location.Y + intMargineSuperiore + (intContaRighe - IntInizioContaRighe) * (dtgDatagrid.Font.SizeInPoints + CintLineaVerticale), intLarghezzaColonna, dtgDatagrid.ColumnHeadersDefaultCellStyle.Font.SizeInPoints + CintLineaVerticale)
nextcellbounds = cellbounds
g.DrawString(nextcolumn, dtgDatagrid.ColumnHeadersDefaultCellStyle.Font, ForeBrush, cellbounds, FormatoCella)
IntXposizione = IntXposizione + intLarghezzaColonna
Next
If dtgDatagrid.CellBorderStyle <> DataGridViewCellBorderStyle.None Then
g.DrawLine(TheLinePen, dtgDatagrid.Location.X, nextcellbounds.Bottom, intLarghezza, nextcellbounds.Bottom)
End If
End Sub
'funzione per disegnare le righe
Public Function DisegnaRighe(ByVal g As Graphics) As Boolean
Dim IntRigaSuperiore As Integer = intMargineSuperiore
Try
Dim ForeBrush As SolidBrush = New SolidBrush(dtgDatagrid.ForeColor)
Dim BackBrush As SolidBrush = New SolidBrush(dtgDatagrid.BackColor)
Dim AlternatingBackBrush As SolidBrush = New SolidBrush(dtgDatagrid.AlternatingRowsDefaultCellStyle.BackColor)
Dim TheLinePen As Pen = New Pen(dtgDatagrid.GridColor, 1)
Dim FormatoCella As StringFormat = New StringFormat()
FormatoCella.Trimming = StringTrimming.EllipsisCharacter
FormatoCella.FormatFlags = StringFormatFlags.NoWrap / StringFormatFlags.LineLimit
Dim IntLargehzzaColonna As Integer = intLarghezza / dttTAbella.Columns.Count
Dim IntInizioContaRighe As Integer = intContaRighe
Dim RowBounds As RectangleF = New RectangleF(0, 0, 0, 0)
'disegno la griglia
Dim i As Integer
For i = IntInizioContaRighe To dttTAbella.Rows.Count - 1 Step i + 1
Dim dr As DataRow = dttTAbella.Rows(i)
Dim startxposition As Integer = dtgDatagrid.Location.X
RowBounds.X = dtgDatagrid.Location.X
RowBounds.Y = dtgDatagrid.Location.Y + intMargineSuperiore + ((intContaRighe - IntInizioContaRighe) + 1) * (dtgDatagrid.Font.SizeInPoints + CintLineaVerticale)
RowBounds.Height = dtgDatagrid.Font.SizeInPoints + CintLineaVerticale
RowBounds.Width = intLarghezza
Arrlinee.Add(RowBounds.Bottom)
If i Mod 2 = 0 Then
g.FillRectangle(BackBrush, RowBounds)
Else
g.FillRectangle(AlternatingBackBrush, RowBounds)
End If
Dim j As Integer
For j = 0 To dttTAbella.Columns.Count - 1
Dim cellbounds As RectangleF = New RectangleF(startxposition, dtgDatagrid.Location.Y + intMargineSuperiore + ((intContaRighe - IntInizioContaRighe) + 1) * (dtgDatagrid.Font.SizeInPoints + CintLineaVerticale), IntLargehzzaColonna, dtgDatagrid.Font.SizeInPoints + CintLineaVerticale)
g.DrawString(dr(j).ToString(), dtgDatagrid.Font, ForeBrush, cellbounds, FormatoCella)
IntRigaSuperiore = CType(cellbounds.Bottom, Integer)
startxposition = startxposition + IntLargehzzaColonna
Next
intContaRighe = intContaRighe + 1
If intContaRighe * (dtgDatagrid.Font.SizeInPoints + CintLineaVerticale) > (intAltezza * IntNumeroPagina) - (intMargineInferiore + intMargineSuperiore) Then
DisegnaLineaOrizzontale(g, Arrlinee)
DisegnaLineaVerticale(g, TheLinePen, intLarghezza, IntRigaSuperiore)
Return True
End If
Next
DisegnaLineaOrizzontale(g, Arrlinee)
DisegnaLineaVerticale(g, TheLinePen, IntLargehzzaColonna, IntRigaSuperiore)
Return False
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
Return False
End Try
End Function
'funzione per disegnare la linea orizzontale
Private Sub DisegnaLineaOrizzontale(ByVal g As Graphics, ByVal arlLinee As ArrayList)
Dim PenDisegnaLinea As Pen = New Pen(dtgDatagrid.GridColor, 1)
If dtgDatagrid.CellBorderStyle = DataGridViewCellBorderStyle.None Then
Return
End If
Dim IntConta As Integer
For IntConta = 0 To arlLinee.Count - 1 Step IntConta + 1
g.DrawLine(PenDisegnaLinea, dtgDatagrid.Location.X, arlLinee(IntConta), intLarghezza, arlLinee(IntConta))
Next
End Sub
'funzione per disegnare la linea verticale
Private Sub DisegnaLineaVerticale(ByVal g As Graphics, ByVal penLinea As Pen, ByVal intLarghezzaColonna As Integer, ByVal intInferiore As Integer)
If dtgDatagrid.CellBorderStyle = DataGridViewCellBorderStyle.None Then
Return
End If
Dim intConta As Integer
For intConta = 0 To dttTAbella.Columns.Count - 1 Step intConta + 1
g.DrawLine(penLinea, dtgDatagrid.Location.X + intConta * intLarghezzaColonna, dtgDatagrid.Location.Y + intMargineSuperiore, dtgDatagrid.Location.X + intConta * intLarghezzaColonna, intInferiore)
Next
End Sub
'funzione per disegnare un GridView
Public Function DisegnaDatagridView(ByVal g As Graphics) As Boolean
Try
DisegnaIntestazione(g)
Dim blnContinua As Boolean = DisegnaRighe(g)
Return blnContinua
Catch ex As Exception
MessageBox.Show(ex.Message)
Return False
End Try
End Function
End Class
Terminato ciò, passiamo in visualizzazione codice della form.
Scriviamo una variabile a livello di classe, dopo la dichiarazione di form, scriviamo un oggetto di tipo della classe precedentemente creata.
Qui di seguito si riporta tale esempio
Private stampaGriglia As StampaDatagrid
A questo punto, dobbiamo creare una funzione che permetta il caricamento dei dati del controllo datagridview e che inizializzi l’oggetto della classe StampaDatagrid.
Qui di seguito riportiamo il frammento di codice di tali operazioni.
Private Sub CaricaGriglia()
Dim dttDati As New DataTable()
Dim dtcNome As New DataColumn("Nome")
Dim dtcCognome As New DataColumn("Cognome")
dttDati.Columns.Add(dtcCognome)
dttDati.Columns.Add(dtcNome)
Dim dtrRiga As DataRow
dtrRiga = dttDati.NewRow()
dtrRiga("Nome") = "Emanuele"
dtrRiga("Cognome") = "Mattei"
dttDati.Rows.Add(dtrRiga)
dtrRiga = dttDati.NewRow()
dtrRiga("Nome") = "Emanuele2"
dtrRiga("Cognome") = "Mattei2"
dttDati.Rows.Add(dtrRiga)
dtrRiga = dttDati.NewRow()
dtrRiga("Nome") = "Emanuele3"
dtrRiga("Cognome") = "Mattei3"
dttDati.Rows.Add(dtrRiga)
dgvDati.DataSource = dttDati
stampaGriglia = New StampaDatagrid(dgvDati, PrintDocument1, dttDati)
End Sub
Dopo il caricamento della griglia, si inizializza l’oggetto di tipo StampaDatagrid, impostando i parametri del costruttore con il controllo griglia, il controllo di tipo printdocument e l’oggetto di tipo datatable contenente i dati.
Questa funzione, viene richiamata dall’evento load della form, come riportato qui di seguito.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
CaricaGriglia()
End Sub
Scriviamo il codice, riguardante l’evento printpage, in cui si utilizzerà il metodo DisegnaDataGridView, per impostare l’area di
stampa.
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim g As Graphics = e.Graphics
Dim more As Boolean = stampaGriglia.DisegnaDatagridView(g)
End Sub
Ora non resta che scrivere il codice , riguardante il controllo PrintPreviewDialog, qui di seguito si riporta il frammento di codice.
Private Sub PrintPreviewDialog1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PrintPreviewDialog1.Load
PrintPreviewDialog1.Bounds = ClientRectangle
End Sub
Siamo giunti quasi alla fine della stesura di codice, dobbiamo impostare gli eventi click del pulsante anteprima e stampa.
Nel primo caso utilizziamo il controllo printprewiewdialog, mentre nel secondo caso il controllo printdocument.
Si riporta il frammento di codice di tali operazioni.
Per il pulsante di anteprima, qui di seguito il codice dell’evento click
Private Sub BtnAnteprima_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnAnteprima.Click
stampaGriglia.IntNumeroPagina = 1
stampaGriglia.intContaRighe = 0
If Me.PrintPreviewDialog1.ShowDialog() = DialogResult.OK Then
End If
Mentre qui di seguito, si riporta il codice, riguardante l’evento click del pulsante di stampa.
Private Sub BtnStampa_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStampa.Click
stampaGriglia.IntNumeroPagina = 1
stampaGriglia.intContaRighe = 0
If PrintDialog1.ShowDialog() = DialogResult.OK Then
'non visualizza la popup
Me.PrintDocument1.PrintController = New System.Drawing.Printing.StandardPrintController()
PrintDocument1.Print()
End If
End Sub
Conclusione
In questa serie di articoli, il lettore avrà acquisito le conoscenze per la stampa in ambito delle Windows Application, tramite la tecnologia .Net 4. La stampa è un elemento fondamentale, nel caso si sviluppano applicazioni gestionali, come software per la contabilità, buste paga, ed altro ancora. Le tecniche per la stampa di un controllo Datagridview, sono diverse, in questa guida è stata illustrata una delle tante tecniche.
Tramite la parola download si può scaricare il file d’esempio utilizzato in questo articolo.