Descrizione :
Un esempio pratico di stampa immagini / etichette usando PrintDocument e PrintPreviewDialog.
+ Articolo :
Si tratta di stampare un certo numero prefissato di immagini / etichette prendendo nomi e quantità da una lista in un DataGridView.
Nel foglio deve essere possibile determinare :
--> Numero di Righe e Colonne ( numero immagini per foglio ).
--> Alcune misure necessarie per l'adattamento alle varie situazioni ( come il cambiamento delle dimensioni immagini ).
Le immagini / etichette devono sempre riempire ogni Foglio alla sua capienza massima possibile ( economizzare carta... ), anche se su uno stesso foglio dovessero trovarsene di tipi diversi.
Come sempre, un'immagine per rendere subito l'idea del risultato desiderato ( Preview di Stampa ) :
Per replicare questa soluzione basta creare una nuova Applicazione Windows Forms con una sola Form "FormMain".
Tutto quello che serve a design è la FormMain ( Form di avvio ) con un DataGridView "DGV", e un Button "cmd_stampa".
--> Codice completo per FormMain :
Public Class FormMain 'Cartella Immagini : modificare... Private percorsoImmagini As String = Application.StartupPath & "\Immagini\" Private WithEvents PD As New Printing.PrintDocument Private rigaDoc As Integer 'indice riga Private colonnaDoc As Integer 'indice colonna Private nomiImgs As New List(Of String) Private indiceImg As Integer Private nuovaPag As Boolean Private bmpTemp As Bitmap 'Variabili di controllo : posizionamento e quantità immagini su foglio... Private stepRiga As Integer = CP(60) 'distanza tra righe Private stepColonna As Integer = CP(70) 'distanza tra colonne Private scartoX As Integer = CP(15) 'scarto iniziale sinistro Private scartoY As Integer = CP(10) 'scarto iniziale superiore Private maxRigheDoc As Integer = 5 'max righe per pag. Private maxColonneDoc As Integer = 3 'max colonne per pag. Private Function CP(ByVal millimetri As Integer) As Integer 'CP = Centesimi di Pollice Return millimetri * 100 / 25.4 End Function Private Sub FormMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim r1() As Object = {"150", "BarCode", "A", "5"} Dim r2() As Object = {"150", "BarCode", "B", "8"} Dim r3() As Object = {"150", "BarCode", "C", "15"} With DGV .Columns.Add("Size", "Size") .Columns.Add("Categoria", "Categoria") .Columns.Add("Nome", "Nome") .Columns.Add("Quantità", "Quantità") .Rows.Add(r1) .Rows.Add(r2) .Rows.Add(r3) End With End Sub Private Sub cmd_stampa_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmd_stampa.Click 'Caricamento nomiImgs 'Qui eventuali controlli su reale esistenza directory e files... Dim nomeImg As String Dim qta As Integer nomiImgs.Clear() For i As Integer = 0 To DGV.RowCount - 1 nomeImg = percorsoImmagini & DGV(2, i).Value & ".jpg" '... Eventuale controllo su esistenza nomeImg ... qta = DGV(3, i).Value For j As Integer = 1 To qta nomiImgs.Add(nomeImg) Next Next If nomiImgs.Count = 0 Then Exit Sub 'Preview Dim PPD As New PrintPreviewDialog PPD.Document = PD PPD.Show() 'Stampa diretta 'PD.Print() End Sub Private Sub PD_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PD.BeginPrint 'Inizializzo valori di partenza per PD_PrintPage indiceImg = 0 rigaDoc = 1 colonnaDoc = 1 nuovaPag = False bmpTemp = New Bitmap(nomiImgs(0)) End Sub Private Sub PD_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PD.PrintPage Do 'Disegno Img e.Graphics.DrawImageUnscaled(bmpTemp, (colonnaDoc - 1) * stepColonna + scartoX, (rigaDoc - 1) * stepRiga + scartoY) 'Controlli / avanzamento righe, colonne, pagine If indiceImg = nomiImgs.Count - 1 Then nuovaPag = False Exit Do Else indiceImg += 1 'Caricamento da disco solo se l'immagine è cambiata rispetto alla precedente If nomiImgs(indiceImg) <> nomiImgs(indiceImg - 1) Then bmpTemp = New Bitmap(nomiImgs(indiceImg)) If colonnaDoc = maxColonneDoc Then colonnaDoc = 1 If rigaDoc = maxRigheDoc Then rigaDoc = 1 nuovaPag = True Exit Do Else rigaDoc += 1 End If Else colonnaDoc += 1 End If End If Loop e.HasMorePages = nuovaPag End Sub End Class
Note :
--> In questo test il caricamento dati in DGV è ovviamente fittizio e avviene nel Form_Load().
--> Viene sempre usato un solo oggetto Bitmap e viene caricato da disco una volta sola per tipo di immagine.
--> Da segnalare l'uso opportuno dell'Evento BeginPrint() : il posto giusto in cui inserire le varie istruzioni di reset delle variabili che controllano la stampa.
--> Il processo è personalizzabile a piacere : l'ultimo blocco di dichiarazioni "Variabili di controllo" permette di definire in millimetri ( Function CP() ) tutte le misure necessarie per adattare la stampa alle dimensioni delle immagini, al numero di righe / colonne desiderato e agli spazi inter-riga e inter-colonna desiderati.
Nel mio caso ho usato 3 Immagini jpg 150x150 pixel.
Le immagini usate nel test erano esattamente queste :
--> Per testare più precisamente la disposizione delle immagini su foglio ovviamente meglio usare immagini con riquadro, e inoltre va ricordato di non trascurare i margini di stampa, che possono variare da stampante a stampante...
Passo successivo potrebbe essere riportare su Form il controllo diretto su queste variabili con NumericUpDown ecc...
--> PD.Print() è volutamente commentato : si può provare sia la preview di stampa, sia la stampa diretta su carta, sia la stampa indiretta tramite la PPD.
+ Fine Articolo.
2 commenti:
Codice bello, pulito..bravo
Grazie mille per queste chicche
Michele
Prego ! :)
Posta un commento