Imprimir directamente ReportViewer a impresora predeterminada


                                                                                                                   MODIFICADO 07-10-2015
Un tema muy importante y picante en algunos blogs y foros es éste que les expongo, sin embargo adaptarlo no es facil, el hecho de verlo como reporte no es suficiente en aspectos donde ya se conoce y se quiere omitir dicho paso, siendo así me encamine el hacer un ejemplo que satisfaga estas necesidades como la de imprimir directamente a la impresora predeterminada de nuestra casa o trabajo.                                                              
Con un ejemplo ya publicado en este post:
http://jossm03.blogspot.com/2015/08/exportar-reporviewer-pdf-de.html  hice unas mejoras y tomando como base los codigos expuestos en el foro msn: 

Con ajustes y adaptaciones les presento la  clase Impresión:
veamos el código:

Imports System
Imports System.IO
Imports System.Data
Imports System.Text
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Printing
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports Microsoft.Reporting.WinForms

Public Class Impresion
 Implements IDisposable
 Private m_currentPageIndex As Integer
 Private m_streams As IList(Of Stream)

    ' Routine to provide to the report renderer, in order to
    ' save an image for each page of the report.
    Private Function CreateStream(ByVal name As String, ByVal fileNameExtension As String, ByVal encoding As Encoding, ByVal mimeType As String, ByVal willSeek As Boolean) As Stream
  Dim stream As Stream = New MemoryStream()
  m_streams.Add(stream)
  Return stream
 End Function

    ' Export the given report as an EMF (Enhanced Metafile) file.
    Private Sub Export(ByVal report As LocalReport)
  Dim deviceInfo As String = "" &
   "EMF" &
   "8.5in" &
   "11in" &
   "0.25in" &
   "0.25in" &
   "0.25in" &
   "0.25in" &
   ""
  Dim warnings As Warning()
  m_streams = New List(Of Stream)()
  report.Render("Image", deviceInfo, AddressOf CreateStream, warnings)
  For Each stream As Stream In m_streams
   stream.Position = 0
  Next
 End Sub

    ' Handler for PrintPageEvents
    Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
  Dim pageImage As New Metafile(m_streams(m_currentPageIndex))

        ' Adjust rectangular area with printer margins.
        Dim adjustedRect As New Rectangle(ev.PageBounds.Left - CInt(ev.PageSettings.HardMarginX),
            ev.PageBounds.Top - CInt(ev.PageSettings.HardMarginY),
            ev.PageBounds.Width,
            ev.PageBounds.Height)

        ' Draw a white background for the report
        ev.Graphics.FillRectangle(Brushes.White, adjustedRect)

        ' Draw the report content
        ev.Graphics.DrawImage(pageImage, adjustedRect)

        ' Prepare for the next page. Make sure we haven't hit the end.
        m_currentPageIndex += 1
  ev.HasMorePages = (m_currentPageIndex < m_streams.Count)
 End Sub

 Private Sub Print()
  If m_streams Is Nothing OrElse m_streams.Count = 0 Then
   Throw New Exception("Error: no se puede imprimir.")
  End If
  Dim printDoc As New PrintDocument()
  If Not printDoc.PrinterSettings.IsValid Then
   Throw New Exception("Error: no se puede hallar la impresora.")
  Else
   AddHandler printDoc.PrintPage, AddressOf PrintPage
   m_currentPageIndex = 0
   printDoc.Print()
  End If
 End Sub

    ' Create a local report for Report.rdlc, load the data,
    ' export the report to an .emf file, and print it.
    Private Sub Run(ByVal rp As LocalReport)
  Export(rp)
  Print()
 End Sub

 Public Sub Dispose() Implements IDisposable.Dispose
  If m_streams IsNot Nothing Then
   For Each stream As Stream In m_streams
    stream.Close()
   Next
   m_streams = Nothing
  End If
 End Sub

 Public Shared Sub Imprimir(ByRef rp As LocalReport)
  Using demo As New Impresion
   demo.Run(rp)
  End Using
 End Sub
End Class

En el Form principal:

Imports System.Drawing.Printing
Imports System.Drawing.Imaging
Imports System.IO
Imports System.Text
Imports Microsoft.Reporting.WinForms

Public Class Form1
 Dim fuente As New ReportDataSource
 Public imprint As New Impresion ' llamando a la clase
 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  rellenargrid()
 End Sub
 Sub rellenargrid()
  Try
   Dim filas As Integer = 1
   grid.Rows.Add(filas)
   Dim n As Integer = grid.Rows.Count
   For i As Integer = 0 To n - 1
    grid.Item(0, i).Value = i + 1
    grid.Item(1, i).Value = "PRODUCTO" & (i + 1)
    grid.Item(2, i).Value = Format((CDbl(CDbl((6.3 * Rnd()) + 1))), "0.00")
    grid.Item(3, i).Value = i + 2
    grid.Item(4, i).Value = Format((grid.Item(3, i).Value * grid.Item(2, i).Value), "0.00")
   Next
  Catch ex As Exception
  End Try
 End Sub
 Sub LLamar_e_imprimir_Reporte()
  Try
   Reportt.ReportViewer1.LocalReport.DataSources.Clear()
   Reportt.ReportViewer1.LocalReport.DataSources.Add(fuente)
   Reportt.ReportViewer1.LocalReport.ReportEmbeddedResource = "ImprimirReporte.Fact.rdlc" 'exactamente como se llaman el proyecto
   Impresion.Imprimir(Reportt.ReportViewer1.LocalReport) ' ejecuta la libreria
  Catch ex As Exception
  End Try
 End Sub
 Sub Almacenar() 'Almacena los datos presentados en el datagridview
        'instanciamos los objetos creados 
        Try
   Dim ds As New DataSet1
   Dim dtw As DataRow
   For i As Integer = 0 To grid.Rows.Count - 1
    dtw = ds.DataTable1.NewRow()
    dtw("n") = grid.Item(0, i).Value
    dtw("Descripcion") = grid.Item(1, i).Value
    dtw("Valor_Unitario") = Replace(CDbl(grid.Item(2, i).Value), ",", ".") ' formato de punto para datatable
    dtw("Cantidad") = grid.Item(3, i).Value
    dtw("Subtotal") = Replace(CDbl(grid.Item(4, i).Value), ",", ".") 'formato de punto para datatable
    ds.DataTable1.Rows.Add(dtw)
   Next
   ''---------------------PREPARAR REPORTE--------------------
   fuente.Name = "Productos" ' Nombre identico al que le di al dataset del report en tiempo de diseño
   fuente.Value = ds.Tables(0)
   ''---------------------PREPARAR REPORTE------------------
  Catch ex As Exception
  End Try
 End Sub
 Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
  Almacenar()
  LLamar_e_imprimir_Reporte()
 End Sub

End Class
Una captura:


Imprimirá a la impresora que tengan preterminada, Y eso es todo  sus comentarios son bienvenidos y espero se suscriban a mi pagina... nos vemos en otra publicacion!, les dejo el ejemplo en el link de abajo:

https://mega.nz/#!EcsxnIJZ!6x1uyTdb34aZsNnQA0yt2QCGhj1gbOia8YtngjQUmbk

Comentarios

  1. Buenas tarde amigo espero que estés bien! Te escribo porque mi amigo Christian siempre te consulta y cosas de programación y tengo una duda. Como puedo imprimir directamente de un formulario desde visual básic.

    ResponderEliminar
  2. yo ya tengo mi ticket echo me imprime muy bien todo pero ahora quiero que se imprima sin que se abra el reportviewer he buscado y no encuentro una manera abra una forma en que la no tengas que pasar a un grid?

    ResponderEliminar
  3. Omito mi comentario anterior, Solo era cuestión de analizar un poco tu proyecto para adaptarlo al mio, muchas gracias por tu aportación colega. no entendía por que almacenabas datos nueva mente en un data set pero me di cuenta que no estabas conectado a una base de datos y la perspectiva cambio total mente ya que estaba trabajando con el modelo MVC me marcaba unos errores pero quedo listo. de nuevo gracias siempre se aprende algo nuevo :D

    ResponderEliminar
    Respuestas
    1. Saludos Alan y me alegra que te haya servido, saludos

      Eliminar

Publicar un comentario

Entradas populares de este blog

Metodo Iterativo Gauss-Seidel en Visual Basic

DevComponents DotnetBar 12.5.0.2