Tutoriales gratuitos para el aprendizaje de la programacion informatica! Recuerda que si lo puedes imaginar... lo puedes programar!

IMPRIMIR REPORTES EN VB.NET DESDE UN DATAGRIDVIEW



PASO 1: Crear una clase llamada printdgv



PASO 2: Copiar el siguiente código en la clase

Public Class PRINTDGV
    Private Shared STRFORMAT As StringFormat
    Private Shared STRFORMATCOMBOBOX As StringFormat
    Private Shared CELLBUTTON As Button
    Private Shared CELLCHECKBOX As CheckBox
    Private Shared CELLCOMBOBOX As ComboBox
    Private Shared TOTALWIDTH As Int16
    Private Shared ROWPOS As Int16
    Private Shared NEWPAGE As Boolean
    Private Shared PAGENO As Int16
    Private Shared COLUMNLEFTS As New ArrayList
    Private Shared COLUMNWIDTHS As New ArrayList
    Private Shared COLUMNTYPES As New ArrayList
    Private Shared CELLHEIGHT As Int16
    Private Shared ROWSPERPAGE As Int16
    Private Shared WithEvents PRINTDOC As New System.Drawing.Printing.PrintDocument
    Private Shared PRINTTITLE As String = ""
    Private Shared PRINTTITLE2 As String = ""
    Private Shared WithEvents PRINTDOC2 As New System.Drawing.Printing.PrintDocument
    Private Shared DGV As DataGridView
    Private Shared SELECTEDCOLUMNS As New List(Of String)
    Private Shared AVAILABLECOLUMNS As New List(Of String) '
    Private Shared PRINTALLROWS As Boolean = True
    Private Shared FITTOPAGEWIDTH As Boolean = True
    Private Shared HEADERHEIGHT As Int16 = 0
    Public Shared Sub PRINT_DATAGRIDVIEW(ByVal DGV1 As DataGridView)
        Dim PPVW As PrintPreviewDialog
        Dim PPVW2 As PrintPreviewDialog
        Try
            DGV = DGV1
            AVAILABLECOLUMNS.Clear()
            For Each C As DataGridViewColumn In DGV.Columns
                If Not C.Visible Then Continue For
                AVAILABLECOLUMNS.Add(C.HeaderText)
            Next
            Dim DLG As New FORMOPCIONESIMPRESION(AVAILABLECOLUMNS)
            If DLG.SHOWDIALOG() <> DialogResult.OK Then Exit Sub
            PRINTTITLE = DLG.PRINTTITLE
            PRINTALLROWS = DLG.PRINTALLROWS
            FITTOPAGEWIDTH = DLG.FITTOPAGEWIDTH
            SELECTEDCOLUMNS = DLG.GETSELECTEDCOLUMNS
            ROWSPERPAGE = 0
            PPVW = New PrintPreviewDialog
            PPVW.Document = PRINTDOC
            PRINTTITLE2 = DLG.PRINTTITLE2
            PRINTALLROWS = DLG.PRINTALLROWS
            FITTOPAGEWIDTH = DLG.FITTOPAGEWIDTH
            SELECTEDCOLUMNS = DLG.GETSELECTEDCOLUMNS
            ROWSPERPAGE = 0
            PPVW2 = New PrintPreviewDialog
            PPVW2.Document = PRINTDOC2
            If PPVW.ShowDialog() <> DialogResult.OK Then Exit Sub
            PRINTDOC.Print()
        Catch EX As Exception
            MessageBox.Show(EX.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
        End Try
    End Sub
    Private Shared Sub PRINTDOC_BEGINPRINT(ByVal SENDER As Object,
                ByVal E As System.Drawing.Printing.PrintEventArgs) Handles PRINTDOC.BeginPrint
        Try
            STRFORMAT = New StringFormat
            STRFORMAT.Alignment = StringAlignment.Near
            STRFORMAT.LineAlignment = StringAlignment.Center
            STRFORMAT.Trimming = StringTrimming.EllipsisCharacter
            STRFORMATCOMBOBOX = New StringFormat
            STRFORMATCOMBOBOX.LineAlignment = StringAlignment.Center
            STRFORMATCOMBOBOX.FormatFlags = StringFormatFlags.NoWrap
            STRFORMATCOMBOBOX.Trimming = StringTrimming.EllipsisCharacter
            COLUMNLEFTS.Clear()
            COLUMNWIDTHS.Clear()
            COLUMNTYPES.Clear()
            CELLHEIGHT = 0
            ROWSPERPAGE = 0
            CELLBUTTON = New Button
            CELLCHECKBOX = New CheckBox
            CELLCOMBOBOX = New ComboBox
            TOTALWIDTH = 0
            For Each GRIDCOL As DataGridViewColumn In DGV.Columns
                If Not GRIDCOL.Visible Then Continue For
                If Not SELECTEDCOLUMNS.Contains(GRIDCOL.HeaderText) Then Continue For
                TOTALWIDTH += GRIDCOL.Width
            Next
            PAGENO = 1
            NEWPAGE = True
            ROWPOS = 0
        Catch EX As Exception
            MessageBox.Show(EX.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
        End Try
    End Sub
    Private Shared Sub PRINTDOC_PRINTPAGE(ByVal SENDER As Object,
            ByVal E As System.Drawing.Printing.PrintPageEventArgs) Handles PRINTDOC.PrintPage
        Dim TMPWIDTH As Int16, I As Int16
        Dim TMPTOP As Int16 = E.MarginBounds.Top
        Dim TMPLEFT As Int16 = E.MarginBounds.Left
        Try
            If PAGENO = 1 Then
                For Each GRIDCOL As DataGridViewColumn In DGV.Columns
                    If Not GRIDCOL.Visible Then Continue For
                    If Not SELECTEDCOLUMNS.Contains(GRIDCOL.HeaderText) Then
                        Continue For
                    End If
                    If FITTOPAGEWIDTH Then
                        TMPWIDTH = CType(Math.Floor(GRIDCOL.Width / TOTALWIDTH *
                                   TOTALWIDTH * (E.MarginBounds.Width / TOTALWIDTH)), Int16)
                    Else
                        TMPWIDTH = GRIDCOL.Width
                    End If
                    HEADERHEIGHT = E.Graphics.MeasureString(GRIDCOL.HeaderText,
                                   GRIDCOL.InheritedStyle.Font, TMPWIDTH).Height + 11
                    COLUMNLEFTS.Add(TMPLEFT)
                    COLUMNWIDTHS.Add(TMPWIDTH)
                    COLUMNTYPES.Add(GRIDCOL.GetType)
                    TMPLEFT += TMPWIDTH
                Next
            End If
            Do While ROWPOS <= DGV.Rows.Count - 1
                Dim GRIDROW As DataGridViewRow = DGV.Rows(ROWPOS)
                If GRIDROW.IsNewRow OrElse (Not PRINTALLROWS AndAlso Not GRIDROW.Selected) Then
                    ROWPOS += 1 : Continue Do
                End If
                CELLHEIGHT = GRIDROW.Height
                If TMPTOP + CELLHEIGHT >= E.MarginBounds.Height + E.MarginBounds.Top Then
                    DRAWFOOTER(E, ROWSPERPAGE)
                    NEWPAGE = True
                    PAGENO += 1
                    E.HasMorePages = True
                    Exit Sub
                Else
                    If NEWPAGE Then
                        'COLOR DEL TITULO DEL REPORTE
                        E.Graphics.DrawString(PRINTTITLE, New Font(DGV.Font, FontStyle.Bold),
                                Brushes.DeepPink, E.MarginBounds.Left, E.MarginBounds.Top -
                        E.Graphics.MeasureString(PRINTTITLE, New Font(DGV.Font,
                                FontStyle.Bold), E.MarginBounds.Width).Height - 5)
                       'COLOR DEL TITULO DEL REPORTE
                       E.Graphics.DrawString(PRINTTITLE2, New Font(DGV.Font, FontStyle.Bold),
                                Brushes.RoyalBlue, E.MarginBounds.Left, E.MarginBounds.Top -
                        E.Graphics.MeasureString(PRINTTITLE2, New Font(DGV.Font,
                                FontStyle.Bold), E.MarginBounds.Width).Height - 10)
                        Dim S As String = Now.ToLongDateString + " " + Now.ToShortTimeString
                        'COLOR DEL TITULO DE LA FECHA
                        E.Graphics.DrawString(S, New Font(DGV.Font, FontStyle.Bold),
                           Brushes.Black, E.MarginBounds.Left + (E.MarginBounds.Width -
                           E.Graphics.MeasureString(S, New Font(DGV.Font, FontStyle.Bold),
                           E.MarginBounds.Width).Width), E.MarginBounds.Top -
                           E.Graphics.MeasureString(PRINTTITLE,
                           New Font(New Font(DGV.Font, FontStyle.Bold), FontStyle.Bold),
                           E.MarginBounds.Width).Height - 11)
                        TMPTOP = E.MarginBounds.Top
                        I = 0
                        For Each GRIDCOL As DataGridViewColumn In DGV.Columns
                            If Not GRIDCOL.Visible Then Continue For
                            If Not SELECTEDCOLUMNS.Contains(GRIDCOL.HeaderText) Then
                                Continue For
                            End If
                            'COLOR DE FONDO
                            E.Graphics.FillRectangle(New SolidBrush(Drawing.Color.Azure),
                                    New Rectangle(COLUMNLEFTS(I), TMPTOP, COLUMNWIDTHS(I), HEADERHEIGHT))
                            'COLOR DE LINEAS
                            E.Graphics.DrawRectangle(Pens.LightBlue, New Rectangle(COLUMNLEFTS(I),
                                    TMPTOP, COLUMNWIDTHS(I), HEADERHEIGHT))
                            E.Graphics.DrawString(GRIDCOL.HeaderText, GRIDCOL.InheritedStyle.Font,
                                    New SolidBrush(GRIDCOL.InheritedStyle.ForeColor),
                                    New RectangleF(COLUMNLEFTS(I), TMPTOP, COLUMNWIDTHS(I),
                                    HEADERHEIGHT), STRFORMAT)
                            I += 1
                        Next
                        NEWPAGE = False
                        TMPTOP += HEADERHEIGHT
                    End If
                    I = 0
                    For Each CEL As DataGridViewCell In GRIDROW.Cells
                        If Not CEL.OwningColumn.Visible Then Continue For
                        If Not SELECTEDCOLUMNS.Contains(CEL.OwningColumn.HeaderText) Then
                            Continue For
                        End If
                        If COLUMNTYPES(I) Is GetType(DataGridViewTextBoxColumn) OrElse
                           COLUMNTYPES(I) Is GetType(DataGridViewLinkColumn) Then
                            E.Graphics.DrawString(CEL.Value.ToString, CEL.InheritedStyle.Font,
                                    New SolidBrush(CEL.InheritedStyle.ForeColor),
                                    New RectangleF(COLUMNLEFTS(I), TMPTOP, COLUMNWIDTHS(I),
                                    CELLHEIGHT), STRFORMAT)
                        ElseIf COLUMNTYPES(I) Is GetType(DataGridViewButtonColumn) Then
                            CELLBUTTON.Text = CEL.Value.ToString
                            CELLBUTTON.Size = New Size(COLUMNWIDTHS(I), CELLHEIGHT)
                            Dim BMP As New Bitmap(CELLBUTTON.Width, CELLBUTTON.Height)
                            CELLBUTTON.DrawToBitmap(BMP, New Rectangle(0, 0,
                                    BMP.Width, BMP.Height))
                            E.Graphics.DrawImage(BMP, New Point(COLUMNLEFTS(I), TMPTOP))
                        ElseIf COLUMNTYPES(I) Is GetType(DataGridViewCheckBoxColumn) Then
                            CELLCHECKBOX.Size = New Size(14, 14)
                            CELLCHECKBOX.Checked = CType(CEL.Value, Boolean)
                            Dim BMP As New Bitmap(COLUMNWIDTHS(I), CELLHEIGHT)
                            Dim TMPGRAPHICS As Graphics = Graphics.FromImage(BMP)
                            TMPGRAPHICS.FillRectangle(Brushes.White, New Rectangle(0, 0,
                                    BMP.Width, BMP.Height))
                            CELLCHECKBOX.DrawToBitmap(BMP, New Rectangle(CType((BMP.Width -
                                    CELLCHECKBOX.Width) / 2, Int32), CType((BMP.Height -
                                    CELLCHECKBOX.Height) / 2, Int32), CELLCHECKBOX.Width,
                                    CELLCHECKBOX.Height))
                            E.Graphics.DrawImage(BMP, New Point(COLUMNLEFTS(I), TMPTOP))
                        ElseIf COLUMNTYPES(I) Is GetType(DataGridViewComboBoxColumn) Then
                            CELLCOMBOBOX.Size = New Size(COLUMNWIDTHS(I), CELLHEIGHT)
                            Dim BMP As New Bitmap(CELLCOMBOBOX.Width, CELLCOMBOBOX.Height)
                            CELLCOMBOBOX.DrawToBitmap(BMP, New Rectangle(0, 0,
                                    BMP.Width, BMP.Height))
                            E.Graphics.DrawImage(BMP, New Point(COLUMNLEFTS(I), TMPTOP))
                            E.Graphics.DrawString(CEL.Value.ToString, CEL.InheritedStyle.Font,
                                    New SolidBrush(CEL.InheritedStyle.ForeColor),
                                    New RectangleF(COLUMNLEFTS(I) + 1, TMPTOP, COLUMNWIDTHS(I) _
                                    - 16, CELLHEIGHT), STRFORMATCOMBOBOX)
                        ElseIf COLUMNTYPES(I) Is GetType(DataGridViewImageColumn) Then
                            Dim CELSIZE As Rectangle = New Rectangle(COLUMNLEFTS(I),
                                    TMPTOP, COLUMNWIDTHS(I), CELLHEIGHT)
                            Dim IMGSIZE As Size = CType(CEL.FormattedValue, Image).Size
                            E.Graphics.DrawImage(CEL.FormattedValue, New Rectangle(COLUMNLEFTS(I) _
                                    + CType(((CELSIZE.Width - IMGSIZE.Width) / 2), Int32),
                                    TMPTOP + CType(((CELSIZE.Height - IMGSIZE.Height) / 2),
                                    Int32), CType(CEL.FormattedValue, Image).Width, CType(CEL.FormattedValue,
                                    Image).Height))
                        End If

                        'COLOR DE LOS BORDES (PARTE DE ABAJO)

                        E.Graphics.DrawRectangle(Pens.AliceBlue, New Rectangle(COLUMNLEFTS(I),
                                TMPTOP, COLUMNWIDTHS(I), CELLHEIGHT))
                        I += 1
                    Next
                    TMPTOP += CELLHEIGHT
                End If
                ROWPOS += 1
                If PAGENO = 1 Then
                    ROWSPERPAGE += 1
                End If
            Loop
            If ROWSPERPAGE = 0 Then Exit Sub
            DRAWFOOTER(E, ROWSPERPAGE)
            E.HasMorePages = False
        Catch EX As Exception
            MessageBox.Show(EX.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Finally
        End Try
    End Sub
    Private Shared Sub DRAWFOOTER(ByVal E As System.Drawing.Printing.PrintPageEventArgs, ByVal ROWSPERPAGE As Int32)
        Dim CNT As Integer
        If PRINTALLROWS Then
            If DGV.Rows(DGV.Rows.Count - 1).IsNewRow Then
                CNT = DGV.Rows.Count - 2
            Else
                CNT = DGV.Rows.Count - 1
            End If
        Else
            CNT = DGV.SelectedRows.Count
        End If
        Dim PAGENUM As String = PAGENO.ToString + " DE " +
                    Math.Ceiling(CNT / ROWSPERPAGE).ToString
        E.Graphics.DrawString(PAGENUM, DGV.Font, Brushes.Orange,
                    E.MarginBounds.Left + (E.MarginBounds.Width -
                    E.Graphics.MeasureString(PAGENUM, DGV.Font,
                    E.MarginBounds.Width).Width) / 2, E.MarginBounds.Top +
                    E.MarginBounds.Height + 31)
    End Sub
End Class


PASO 3: Crear un formulario llamado formopcionesimpresion



PASO 4: Diseñar el formulario de impresion




CONTROLES Y PROPIEDADES:

CHECKEDLISTBOX1: NAME= CHKLST
RADIOBUTTON1: NAME= RDOALLROWS; TEXT= TODAS LAS FILAS SELECCIONADAS
RADIOBUTTON2: NAME= RDOSELECTEDROWS; TEXT= SELECCIONADOS
TEXTBOX1: NAME= TXTTITLE1; MULTILINE= TRUE; SCROLLBARS=VERTICAL
TEXTBOX2: NAME= TXTTITLE2; MULTILINE= TRUE; SCROLLBARS=VERTICAL
BUTTON1: NAME= BTNOK;
BUTTON2: NAME= BTNMINIMIZAR;
BUTTON3: NAME= BTNCANCEL;
CHECKBOX1: NAME= CHKFITTOPAGEWIDTH; TEXT= AJUSTAR AL ANCHO DE PÁGINA


PASO 5: Adaptar el siguiente código en el formulario FORMOPCIONESIMPRESION

Imports System.Collections.Generic
Imports System.Collections.Generic
Public Class FORMOPCIONESIMPRESION
    Public Sub New(ByVal AVAILABLEFIELDS As List(Of String))
        INITIALIZECOMPONENT()
        For Each FIELD As String In AVAILABLEFIELDS
            CHKLST.ITEMS.ADD(FIELD, False)
        Next
    End Sub

    Private Sub FORMOPCIONESIMPRESION_LOAD(ByVal SENDER As System.Object, ByVal E As System.EventArgs) Handles MyBase.LOAD
        RDOALLROWS.CHECKED = True
        CHKFITTOPAGEWIDTH.CHECKED = True
    End Sub

    Private Sub BTNCANCEL_CLICK(ByVal SENDER As System.Object, ByVal E As System.EventArgs) Handles BTNCANCEL.CLICK
        Me.DIALOGRESULT = Windows.FORMS.DIALOGRESULT.CANCEL
        Me.CLOSE()
    End Sub

    Public Function GETSELECTEDCOLUMNS() As List(Of String)
        Dim LST As New List(Of String)
        For Each ITEM As Object In CHKLST.CHECKEDITEMS
            LST.Add(ITEM.ToString)
        Next
        Return LST
    End Function

    Public ReadOnly Property PRINTTITLE() As String
        Get
            Return TXTTITLE2.TEXT
        End Get
    End Property
    Public ReadOnly Property PRINTTITLE2() As String
        Get
            Return TXTTITLE1.TEXT
        End Get
    End Property
    Public ReadOnly Property PRINTALLROWS() As Boolean
        Get
            Return RDOALLROWS.CHECKED
        End Get
    End Property
    Public ReadOnly Property FITTOPAGEWIDTH() As Boolean
        Get
            Return CHKFITTOPAGEWIDTH.CHECKED
        End Get
    End Property
    Private Sub BTNOK_CLICK(ByVal SENDER As System.Object, ByVal E As System.EventArgs) Handles BTNOK.CLICK
        Me.DIALOGRESULT = Windows.FORMS.DIALOGRESULT.OK
        Me.CLOSE()
    End Sub
    Private Sub BUTTON1_CLICK(ByVal SENDER As System.Object, ByVal E As System.EventArgs) Handles BTNMINIMIZAR.CLICK
        Me.WINDOWSTATE = FormWindowState.Minimized
    End Sub
    Private Sub PICTUREBOX3_CLICK(ByVal SENDER As System.Object, ByVal E As System.EventArgs) Handles PICTUREBOX3.CLICK
        FORMACERCADE.SHOW()
    End Sub
End Class

PASO 6: Copiar el siguiente código en un button desde el form donde se encuentre el datagridview para llamar la instrucción

Private Sub BUTTON1_CLICK(ByVal SENDER As System.Object, ByVal E As System.EventArgs) Handles BUTTON1.CLICK
    PRINTDGV.PRINT_DATAGRIDVIEW(GRID)

End Sub

NOTA: EL DATAGRIDVIEW SE DEBE DE LLAMAR GRID

PROYECTO FINALIZADO:




'AL PRESIONAR EL BUTTON1 DEBE APARECER EL SIGUIENTE FORMULARIO:





'AL PRESIONAR EL BOTON OK DEBE APARECER EL SIGUIENTE REPORTE:



No hay comentarios:

Publicar un comentario