|
||||
|
|
#1 (permalink) |
|
Collega della community ![]() ![]()
934 Messaggi
![]() ![]() |
Stampare Tabella DataGridView
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 Programma 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 2005 e digitiamo il codice seguente: codice:
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
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. codice:
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
codice:
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
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: codice:
Private Sub docToPrint_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles docToPrint.PrintPage
‘Coordinata X della posizione delle celle della griglia
Dim posX As Integer
‘Coordinata Y della posizione delle celle della griglia
Dim posY As Integer = e.MarginBounds.Top
‘Rettangolo grafico che rappresenta una cella della griglia
Dim Rettangolo As Rectangle
‘Altezza di una cella
Dim Altezza As Integer = Tabella.RowTemplate.Height
‘Impostazione del Font per le celle
Dim NormalFont As Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, FontStyle.Regular)
‘Impostazione del Font per le Intestazioni
Dim BoldFont As Font = New System.Drawing.Font("Microsoft Sans Serif", 8.25!, FontStyle.Bold)
‘Contatore delle righe che sono state stampate
Static righeStampate As Integer = 0
‘Contatore delle pagine che sono state stampate
Static pagineStampate As Integer = 0
‘Numero di righe totali da stampare
Dim righeTotali As Integer = Tabella.Rows.Count
‘Numero di righe che possono essere stampate in una pagina
Dim righePerPagina As Integer = e.MarginBounds.Height / Altezza
‘Numero di pagine totali da stampare
Dim nPagine As Integer
‘Definisce il corretto numero di pagine totali da stampare
If righeTotali Mod righePerPagina > 0 Then
nPagine = (righeTotali \ righePerPagina) + 1
Else
nPagine = (righeTotali \ righePerPagina)
End If
‘Calcola la X iniziale per centrare la tabella nella pagina
‘La dimensione della DataGridView è uguale a 360=80+80+100+100
posX = (e.MarginBounds.Width - 360) / 2 + e.MarginBounds.Left
‘Dimensione del testo contenuto nella cella
Dim dimensioneCella As System.Drawing.SizeF
‘Spazio da aggiungere alla coordinate X affinché il testo nella cella risulti centrato
Dim incremento As Integer
‘Disegno Intestazioni Tabella
For Each colonna As DataGridViewColumn In Tabella.Columns
dimensioneCella = e.Graphics.MeasureString(colonna.HeaderText.ToString, NormalFont)
incremento = (colonna.Width - dimensioneCella.Width) / 2
‘Definisce il rettangolo da disegnare
Rettangolo = New Rectangle(posX, posY, colonna.Width, Altezza)
‘Disegna il rettangolo
e.Graphics.DrawRectangle(Pens.Black, Rettangolo)
‘Scrive l’intestazione della colonna
e.Graphics.DrawString(colonna.HeaderText, BoldFont, Brushes.Black, posX + incremento, posY + 5)
posX += colonna.Width
Next
posY += Altezza
‘Testo da inserire nelle celle della tabella
Dim testo As String
‘Disegna e riempe tutte le celle della tabella
For i As Integer = righeStampate To righeStampate + righePerPagina-2
posX = (e.MarginBounds.Width - 360) / 2 + e.MarginBounds.Left
‘Se le righe stampate sono tutte interrompe il ciclo For…Next
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 = (colonna.Width - dimensioneCella.Width) / 2
Rettangolo = New Rectangle(posX, posY, colonna.Width, Altezza)
‘Disegna il rettangolo
e.Graphics.DrawRectangle(Pens.Black, Rettangolo)
‘Scrive il dato nella cella
e.Graphics.DrawString(testo, NormalFont, Brushes.Black, posX + incremento, posY + 5)
posX += colonna.Width
Next
righeStampate += 1
posY += Altezza
Next
pagineStampate += 1
'Controlla se vi sono altre pagine da stampare
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
Tutto il resto sono istruzioni che controllano la correttezza del processo: quante righe e quante pagine stampare, il font delle intestazioni e delle celle, , la larghezza delle colonne e l'altezza delle righe... E il gioco è fatto! Come ho scritto all’inizio dell’articolo, questo codice è un semplice esempio che può essere migliorato: -Si possono, per esempio, scrivere poche istruzioni per verificare ed eventualmente ridimensionare i titoli delle colonne se queste superano la larghezza delle celle; -Si può avvisare l’utente se sta tentando di stampare una tabella troppo grande per il formato di carta prescelto, offrendogli la possibilità di selezionare l’opzione Landscape, per la stampa in orizzontale, o di ridurre il numero di colonne; -Si possono modificare i margini aumentando o riducendo l’area stampabile. Spero comunque che queste poche righe possano servirvi come spunto per creare una routine adatta alle vostre esigenze e alla tabella che dovete stampare. Francesco.
__________________
Francesco Visita la mia Home Page La stampa in VB.Net Giochiamo a Sudoku Se qualcuno ti è stato di aiuto potresti ringraziarlo usando il pulsante "COMMENTA INTERVENTO" ![]() |
|
|
|
|
|
#2 (permalink) |
|
Collega della community ![]() ![]()
934 Messaggi
![]() ![]() |
Ho aggiunto alcune righe di codice per ridimensionare il testo nell' intestazione di colonna, qualora la sua lunghezza risulti maggiore di quella della colonna stessa.
codice:
...
...
posX = (e.MarginBounds.Width - 360) / 2 + e.MarginBounds.Left
Dim dimensioneCella As System.Drawing.SizeF
Dim incremento As Integer
'Stringa per contenere il testo dell' Intestazione
Dim testoColonna As String
'Testo ("*" oppure "") da aggiungere al titolo se risulta troppo grande
Dim tfColonna As String = ""
For Each colonna As DataGridViewColumn In Tabella.Columns
dimensioneCella = e.Graphics.MeasureString(colonna.HeaderText.ToString, BoldFont)
'Testo dell'intestazione di colonna
testoColonna = colonna.HeaderText
'Ciclo Do...Loop per ridurre la lunghezza del testo
Do While dimensioneCella.Width > colonna.Width
'Rimuove un carattere dal testo dell'intestazione
testoColonna = testoColonna.Remove(testoColonna.Length - 1, 1)
'Calcola le nuove dimensioni della cella
dimensioneCella = e.Graphics.MeasureString(testoColonna & "*", BoldFont)
tfColonna = "*"
Loop
incremento = (colonna.Width - dimensioneCella.Width) / 2
Rettangolo = New Rectangle(posX, posY, colonna.Width, Altezza)
e.Graphics.DrawRectangle(Pens.Black, Rettangolo)
e.Graphics.DrawString(testoColonna & tfColonna, BoldFont, Brushes.Black, posX + incremento, posY + 5)
posX += colonna.Width
tfColonna = ""
Next
posY += Altezza
Dim testo As String
...
...
In pratica si tratta di verificare l'ampiezza del testo nell'intestazione di colonna e se questo ne supera l'ampiezza, tale testo viene ridotto di un carattere alla volta fino a che può entrare liberamente nella spazio a disposizione. Inoltre per evidenziare che il titolo è stato TAGLIATO viene aggiunto un ASTERISCO (*) a fine testo.
__________________
Francesco Visita la mia Home Page La stampa in VB.Net Giochiamo a Sudoku Se qualcuno ti è stato di aiuto potresti ringraziarlo usando il pulsante "COMMENTA INTERVENTO" ![]() |
|
|
|
|
|
#3 (permalink) |
|
Utente della community ![]() ![]()
486 Messaggi
![]() ![]() |
D'accordo con Francesco propongo questa aggiunta copia\incollata ed adattata dalla Guida che inserisce la finestra di dialogo 'Anteprima di Stampa'
Al posto di: codice:
Friend PrintDialog1 As New System.Windows.Forms.PrintDialog codice:
Friend WithEvents PrintPreviewDialog1 As PrintPreviewDialog codice:
ImpostaStampa() PrintPreviewDialog1.Document = docToPrint PrintPreviewDialog1.ShowDialog() codice:
Private Sub ImpostaStampa()
Me.PrintPreviewDialog1 = New PrintPreviewDialog
Me.PrintPreviewDialog1.ClientSize = New System.Drawing.Size(400, 300)
Me.PrintPreviewDialog1.Location = New System.Drawing.Point(29, 29)
Me.PrintPreviewDialog1.Name = "PrintPreviewDialog1"
Me.PrintPreviewDialog1.MinimumSize = New System.Drawing.Size(375, 250)
Me.PrintPreviewDialog1.UseAntiAlias = True
End Sub
__________________
Alberto. |
|
|
|
|
|
#5 (permalink) |
|
Collega della community ![]() ![]()
934 Messaggi
![]() ![]() |
Chiedo scusa se non ho risposto prima, ma non avevo visto questa domanda.
Per stampare delle immagini inserite nella tabella devi usare: codice:
e.Graphics.DrawImage(NomeImmagine, PosizioneX, PosizioneY LarghezzaImmagine,AltezzaImmagine)
__________________
Francesco Visita la mia Home Page La stampa in VB.Net Giochiamo a Sudoku Se qualcuno ti è stato di aiuto potresti ringraziarlo usando il pulsante "COMMENTA INTERVENTO" ![]() |
|
|
|
|
|
#6 (permalink) |
|
Collega della community ![]() ![]()
934 Messaggi
![]() ![]() |
Stampare le celle selezionate di una tabella DataGridView
Stampare le celle selezionate di una DataGridView
Un utente, qualche tempo fa, mi ha spedito una mail per chiedermi se sapevo come fare , in VB2008EE, per stampare le celle selezionate di una tabella, senza usare i report. Non avevo mai avuto la necessità di fare una cosa del genere, pertanto, incuriosito, mi sono messo a ragionare su come avrei potuto fare per risolvere il problema. La soluzione che ho trovato è la seguente: Nella finestra di dialogo ‘Stampa’ abilito l’opzione ‘Stampa Selezione’ e nel codice recupero quelle celle che sono state selezionate, o con il mouse o con la tastiera, per avere la possibilità di manipolarle e inviarle al processo di stampa. Avendo già creato un piccolo programma sulla stampa delle DataGridView, ho pensato di adattare quel codice per renderlo utilizzabile anche per elaborare le selezioni. Per recuperare le celle selezionate si può usare la proprietà: DataGridView.SelectedCells la quale contiene gli indici delle celle selezionate nell’ordine inverso a quello con il quale sono state scelte. Facciamo un esempio: prendiamo una tabella di 24 celle (6 righe e 4 colonne) [cella 0,0] [cella 0,1] [cella 0,2] [cella 0,3] [cella 1,0] [cella 1,1] [cella 1,2] [cella 1,3] [cella 2,0] [cella 2,1] [cella 2,2] [cella 2,3] [cella 3,0] [cella 3,1] [cella 3,2] [cella 3,3] [cella 4,0] [cella 4,1] [cella 4,2] [cella 4,3] [cella 5,0] [cella 5,1] [cella 5,2] [cella 5,3] Supponiamo che l’utente abbia selezionato queste celle nel seguente ordine: [cella 4,3] [cella 1,3] [cella 1,0] [cella 4,0] [cella 3,1] [cella 1,1] [cella 3,2] [cella 4,1] Saranno memorizzate in questo modo: [cella 4,1] [cella 3,2] [cella 1,1] [cella 3,1] [cella 4,0] [cella 1,0] [cella 1,3] [cella 4,3] Dovendole elaborare diventa difficile gestirne il contenuto se non sono elencate in modo crescente. Pertanto ho riordinato le celle selezionate per poi stamparle comodamente con un ciclo, così come farei per una normale tabella se dovessi stamparla tutta. Dapprima riordino le righe in questo modo: [cella 1,3] [cella 1,0] [cella 1,1] [cella 3,1] [cella 3,2] [cella 4,3] [cella 4,0] [cella 4,1] Quindi metto in ordine le colonne che hanno in comune una stessa riga. [cella 1,0] [cella 1,1] [cella 1,3] [cella 3,1] [cella 3,2] [cella 4,0] [cella 4,1] [cella 4,3] Calcolo anche il numero di righe che sono state selezionate (3 in questo caso: 1,3,4), in modo da ricavare il numero di pagine da stampare tenendo conto dell’altezza del font utilizzato, e dei margini del foglio. Ottengo il numero di colonne che sono coinvolte nella stampa ( 4 in questo caso: 0,1,2,3) in modo da sapere quali intestazioni della tabella devo disegnare; quindi elaboro il tutto e lo invio alla periferica di stampa. Il programma è in grado di stampare senza problemi sia una tabella intera che una selezione di una parte di essa Considerata la lunghezza del codice allego il file compresso, il quale contiene numerose note che spiegano passo-passo tutte le istruzioni. Sono a disposizione per ogni chiarimento.
__________________
Francesco Visita la mia Home Page La stampa in VB.Net Giochiamo a Sudoku Se qualcuno ti è stato di aiuto potresti ringraziarlo usando il pulsante "COMMENTA INTERVENTO" ![]() Ultima modifica di Gandalfrank : 07-02-2009 a 20:03. |
|
|
|
|
|
#7 (permalink) |
|
Collega della community ![]() ![]()
934 Messaggi
![]() ![]() |
Ho migliorato l'aspetto finale della stampa senza compromettere le linee generali dell'applicazione.
Allego il NUOVO codice.
__________________
Francesco Visita la mia Home Page La stampa in VB.Net Giochiamo a Sudoku Se qualcuno ti è stato di aiuto potresti ringraziarlo usando il pulsante "COMMENTA INTERVENTO" ![]() |
|
|
|
![]() |
| Strumenti della discussione | |
| Modalità di visualizzazione | |
|
|
Tutti gli orari sono GMT +2. Attualmente sono le 09:57.











Modalità lineare

