Appunti di Programmazione

Creative Commons License

Stampare Tabella DataGridView con VB .Net

Introduzione:

Recentemente ho avuto la necessità di stampare su carta i dati raccolti in una DataGridView, perciò mi sono impegnato a capire come poter risolvere questo problema.
In rete ho trovato molto materiale che ho elaborato, modificato e riunito nel codice che vi propongo.
L'esempio di applicazione è un punto di partenza per riuscire ad ottenere la stampa di una tabella. Non ho introdotto algoritmi per la gestione delle eccezioni, né controlli sulla larghezza totale della tabella o del contenuto delle colonne.

Va da sé che la DataGridView deve occupare uno spazio uguale o inferiore all'area stampabile. Il codice così come è stato scritto funziona e può essere adattato alle esigenze di ognuno.

Il Codice:

Il processo di stampa è identificabile in 2 punti:
- Definizione e formattazione del documento da stampare.
- Esecuzione della stampa.

Generalmente si definisce un oggetto System.Drawing.Printing.PrintDocument che raccoglie tutte le istruzioni necessarie a stampare i nostri dati. Una volta definito questo oggetto, sarà sufficiente inviarlo alla stampante per avere una copia su carta della nostra DataGridView.

Avviamo un nuovo progetto Visual Basic .Net e digitiamo il codice seguente:

Public Class Form1

    Private WithEvents Tabella As New System.Windows.Forms.DataGridView
    Private WithEvents btnStampa As New System.Windows.Forms.Button
    Private WithEvents docToPrint As New System.Drawing.Printing.PrintDocument
    Friend PrintDialog1 As New System.Windows.Forms.PrintDialog

    Private Sub StampaDataGridView_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles Me.Load

        Me.Size = New Size(430, 300)
        ImpostaControlli()
        RiempiDataGridView()

    End Sub

    Private Sub ImpostaControlli()

        With (Tabella.ColumnHeadersDefaultCellStyle)

            .Font = New Font(Tabella.Font, FontStyle.Bold)
            .Alignment = DataGridViewContentAlignment.TopCenter

        End With

        With Tabella

            .Name = "dgv"
            .Size = New Size(400, 180)
            .ColumnCount = 4
            .ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single
            .CellBorderStyle = DataGridViewCellBorderStyle.Single
            .GridColor = Color.Black
            .RowHeadersVisible = True
            .Dock = DockStyle.Top

            .Columns(0).Name = "Cognome"
            .Columns(0).Width = 80
            .Columns(1).Name = "Nome"
            .Columns(1).Width = 80
            .Columns(2).Name = "Telefono"
            .Columns(2).Width = 100
            .Columns(3).Name = "Cellulare"
            .Columns(3).Width = 100

        End With

        With btnStampa

            .Text = "Stampa"
            .Size = New Size(80, 30)
            .Location = New Point(175, 200)

        End With

        Me.Controls.Add(Tabella)
        Me.Controls.Add(Me.btnStampa)

    End Sub

Abbiamo inizializzato una form, una DataGridView e un Button e impostato le loro proprietà per una rappresentazione grafica dei nostri dati.
Notate che all'inizio della classe è stato definito un oggetto (docToPrint) che rappresenta il nostro documento da impostare e inviare alla stampante.
Adesso popoliamo la nostra tabella con varie informazioni, per un totale di 66 righe, tanto per essere sicuri di occupare lo spazio di 2 pagine da stampare.

    Private Sub RiempiDataGridView()

        Dim riga0 As String() = {"Rossi", "Mario", "123/456789", "0999/987654"}
        Dim riga1 As String() = {"Bianchi", "Carlo", "231/566889", "0111/998877"}
        Dim riga2 As String() = {"Neri", "Antonio", "321/445566", "0222/552469"}
        Dim riga3 As String() = {"Gialli", "Luisa", "132/696987", "0333/487962"}
        Dim riga4 As String() = {"Verdi", "Franca", "213/323539", "0444/1258974"}

        For i As Integer = 0 To 12

            With Tabella.Rows

                .Add(riga0)
                .Add(riga1)
                .Add(riga2)
                .Add(riga3)
                .Add(riga4)

            End With

        Next

    End Sub

Scriviamo il codice relativo all'evento _Click del Pulsante "Stampa"

    Private Sub btnStampa_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStampa.Click

        PrintDialog1.Document = docToPrint
        If (PrintDialog1.ShowDialog) = Windows.Forms.DialogResult.OK Then docToPrint.Print()

    End Sub

Il nostro documento (docToPrint) viene associato a quello della finestra di dialogo Stampa per il recupero delle impostazioni che possono occorrere.
Se l'utente seleziona il pulsante OK della finestra di Stampa, il nostro documento viene processato e inviato alla stampante con le specifiche impostate nella stessa finestra di dialogo ( Tipo Stampante, Numero di copie...) e realizzato con quanto definito nel codice seguente:

    Private Sub docToPrint_PrintPage(ByVal sender As Object, ByVal e As  _
                                         System.Drawing.Printing.PrintPageEventArgs) Handles docToPrint.PrintPage

        Dim posX As Integer

        Dim posY As Integer = e.MarginBounds.Top

        Dim Rettangolo As Rectangle

        Dim Altezza As Integer = Tabella.RowTemplate.Height

        Dim NormalFont As Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, FontStyle.Regular)

        Dim BoldFont As Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, FontStyle.Bold)

        Static righeStampate As Integer = 0

        Static pagineStampate As Integer = 0

        Dim righeTotali As Integer = Tabella.Rows.Count

        Dim righePerPagina As Integer = CType(e.MarginBounds.Height / Altezza, Integer)

        Dim nPagine As Integer

        If righeTotali Mod righePerPagina > 0 Then
        
            nPagine = (righeTotali \ righePerPagina) + 1
            
        Else
        
            nPagine = (righeTotali \ righePerPagina)
            
        End If

        posX = CType((e.MarginBounds.Width - 360) / 2 + e.MarginBounds.Left, Integer)

        Dim dimensioneCella As System.Drawing.SizeF

        Dim incremento As Integer

        For Each colonna As DataGridViewColumn In Tabella.Columns

            dimensioneCella = e.Graphics.MeasureString(colonna.HeaderText.ToString, NormalFont)
            incremento = CType((colonna.Width - dimensioneCella.Width) / 2, Integer)

            Rettangolo = New Rectangle(posX, posY, colonna.Width, Altezza)

            e.Graphics.DrawRectangle(Pens.Black, Rettangolo)

            e.Graphics.DrawString(colonna.HeaderText, BoldFont, Brushes.Black, posX + incremento, posY + 5)
            posX += colonna.Width

        Next

        posY += Altezza

        Dim testo As String

        For i As Integer = righeStampate To righeStampate + righePerPagina - 2

            posX = CType((e.MarginBounds.Width - 360) / 2 + e.MarginBounds.Left, Integer)

            If i = righeTotali - 1 Then
            
                e.HasMorePages = False                
                Exit For
                
            End If

            For Each colonna As DataGridViewColumn In Tabella.Columns

                testo = Tabella.Rows(i).Cells(colonna.Name).Value.ToString
                dimensioneCella = e.Graphics.MeasureString(testo.ToString, NormalFont)
                incremento = CType((colonna.Width - dimensioneCella.Width) / 2, Integer)
                Rettangolo = New Rectangle(posX, posY, colonna.Width, Altezza)

                e.Graphics.DrawRectangle(Pens.Black, Rettangolo)

                e.Graphics.DrawString(testo, NormalFont, Brushes.Black, posX + incremento, posY + 5)
                posX += colonna.Width

            Next

            righeStampate += 1
            posY += Altezza

        Next

        pagineStampate += 1

        If pagineStampate < nPagine Then
        
            e.HasMorePages = True
            posY = e.MarginBounds.Top
            
        Else
        
            e.HasMorePages = False
            righeStampate = 0
            pagineStampate = 0
            
        End If

    End Sub

End Class

E il gioco è fatto!

Download sorgente "Print_DataGridView.zip" ( 69KB )