| 
INTRODUCCION: Con el paso del tiempo, las aplicaciones que desarrollamos necesitan de
mayor dedicación para cumplir con los requerimientos de los usuarios. Esto
provoca que en algunas ocasiones tengamos ciertos problemas para satisfacer a
nuestros queridos clientes "Los Usuarios" que son la razón de ser de
nuestro trabajo. Estos esfuerzos por mantenerlos contentos, se ven mermados por
la imposibilidad (sea técnica o de herramientas) de mostrar una data en un
formato determinado. Este es el caso de los famosos Documentos de Formato
portátil (PDF) que tanto les gustan a los usuarios (Y a nosotros mismo). No
hace mucho tiempo tuve el inconveniente, de que un usuario deseaba mantener los
datos que le mostraba en un datagrid en un archivo. El problema comenzó cuando
deseaba que como primera opción le enviara el archivo en un .PDF, cosa que no
tenia idea de como lograrlo. En segundo lugar me ha propuesto que se lo envié
en un documento de Word. Es decir, que la información que le mostraba en un
DataGrid en una pagina, se la transformara en un documento de Word y se la
enviara. Al igual que la anterior opción, no tenía dominio de tema para
complacerlo. En ese caso, opté por terminar enviándole el DataGrid por correo a
sugerencia de un amigo (mi colega de código, Andrés Faya) y es así como he
salido de paso. Luego me he encontrado un artículo que escribió alguien para
www.elguille.info para generar PDF desde .net. La idea me atrajo y me he leído
el artículo y le he escrito al autor, he consultado el site que tiene como
referencia para descargar el componente extra que necesito (no nativo de
vs.net) y al final de cuentas no he conseguido lo que he deseado. Esta
situación, gracias a vs.net ha llegado a su final, pues nuestro IDE cuenta con
las herramientas necesarias para crear nuestros PDF sin tener que usar
componentes ni códigos de terceros. Este artículo, no pretende volverlos unos
expertos en la creación de archivos de extensión PDF, pero por lo menos les
mostrará la luz para continúen por ustedes mismos explorando y de paso
compartiendo los conocimientos que adquieran (que no se les olvide esa parte,
pues es la única forma en que podemos crecer como comunidad .net).  Desarrollo:Bien, lo primero que necesitamos hacer es crear un reporte con Crystal
Report que nos proporcione la apariencia que deseamos en nuestro .PDF. Se
preguntaran, porque un reporte con Crystal? La respuesta es sencilla, la
información que vamos a cargar en nuestro PDF, es la información que le estamos
mostrando a nuestros usuarios en un datagrid y por ende, quien mejor que
Crystal para darle un buen formato a ese reporte que deseamos convertir a PDF.
Recuerden que con crystal puedes diseñar cartas y no solo reportes como tal. El
fundamento de este ejemplo está sustentado en la creación de un DataSet tipado
con el esquema de los campos que vamos a mostrar en nuestro PDF. Una vez hecho
esto, entonces procedemos con las funciones que nos permiten crear nuestro PDF.
Cuerpo de código Imports CrystalDecisions.CrystalReports.Engine Imports System.Data.SqlClient Public Class Form1     Inherits System.Windows.Forms.Form   #Region " Windows Form Designer generated code "       Public Sub New()         MyBase.New()           'This call is required by the Windows Form Designer.         InitializeComponent()           'Add any initialization after the InitializeComponent() call       End Sub       'Form overrides dispose to clean up the component list.     Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)         If disposing Then             If Not (components Is Nothing) Then                 components.Dispose()             End If         End If         MyBase.Dispose(disposing)     End Sub       'Required by the Windows Form Designer     Private components As System.ComponentModel.IContainer       'NOTE: The following procedure is required by the Windows Form Designer     'It can be modified using the Windows Form Designer.       'Do not modify it using the code editor.     Friend WithEvents Button1 As System.Windows.Forms.Button     Friend WithEvents mconn As System.Data.SqlClient.SqlConnection     <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()         Me.Button1 = New System.Windows.Forms.Button         Me.mconn = New System.Data.SqlClient.SqlConnection         Me.SuspendLayout()         '         'Button1         '         Me.Button1.Location = New System.Drawing.Point(344, 264)         Me.Button1.Name = "Button1"         Me.Button1.TabIndex = 1         Me.Button1.Text = "Button1"         '         'mconn         '         Me.mconn.ConnectionString = "workstation id=U24603;packet size=4096;integrated security=SSPI;data source=U2460" & _         "3;persist security info=False;initial catalog=TimeManager"         '         'Form1         '         Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)         Me.ClientSize = New System.Drawing.Size(432, 318)         Me.Controls.Add(Me.Button1)         Me.Name = "Form1"         Me.Text = "Form1"         Me.ResumeLayout(False)       End Sub   #End Region       Private Function CrearPDF(ByVal ds As DataSet)          Dim strpdf As String         'Esta es la instancia del reporte que tengo hecho con un binding del dataset tipado         Dim cr As New Bloqueos         cr.SetDataSource(ds)         Try             'En la siguiente línea determinamos el formato final del reporte.             cr.ExportOptions.ExportFormatType = CrystalDecisions.[Shared].ExportFormatType.PortableDocFormat             Dim filedest As New CrystalDecisions.Shared.DiskFileDestinationOptions             'Determinamos la ruta donde se va a crear nuestro archivo al finalizar el proceso en este caso,             'concatenamos horas, minutos, segundos, para mantener control en caso de usar la misma ruta en otras instancias.             Dim nombrearchivopdf As String = "C:\pdf\PDF" & Date.Now.Hour & Date.Now.Minute & Date.Now.Second & ".pdf"             filedest.DiskFileName = nombrearchivopdf             'Le pasamos al reporte el parámetro destino del reporte (ruta)             cr.ExportOptions.DestinationOptions = filedest             'Le indicamos que el reporte no es para mostrarse en pantalla, sino, que es para guardar en disco             cr.ExportOptions.ExportDestinationType = CrystalDecisions.[Shared].ExportDestinationType.DiskFile             'Indicamos el formato de la página del reporte             cr.PrintOptions.PaperOrientation = CrystalDecisions.[Shared].PaperOrientation.Landscape             'Finalmente exportamos el reporte a PDF             cr.Export()             'Como buenos samaritanos nos curamos en salud, y atrapamos las posibles excepciones que se pudieran presentar.         Catch ex3 As CrystalDecisions.CrystalReports.Engine.InternalException             MsgBox(ex3.Message & "       -----" & ex3.StackTrace)         Catch ex2 As CrystalDecisions.CrystalReports.Engine.ExportException             MsgBox("Se ha producido un error cargando los archivos a PDF. Error: " & ex2.Message, MsgBoxStyle.Information, "PDF Creator")        Catch ex As System.IO.IOException             MsgBox("Se ha producido un error cargando los archivos a PDF. Error: " & ex.Message, MsgBoxStyle.Information, "PDF Creator")        End Try     End Function     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click         Dim ad As New SqlDataAdapter("select * from bloqueotiempo", mconn)        Dim ds2 As New ds         Dim dt As New DataTable         'Copiamos el esquema del DataSet tipado que hemos creado. "Ojo" no estamos copiando           'los registros que representa, solo la estructura. Pues, para copiar el contenido es con el método copy         dt = ds2.Tables(0).Clone         Try             mconn.Open()             ad.Fill(dt)         Catch ex As Exception             MsgBox(ex.Message, MsgBoxStyle.Information, "Prueba")         Finally             mconn.Close()         End Try         Dim i As Int32         Dim con As Int32         Dim dat As Date        'Debido a que en este caso vamos a retornar un PDF por registros, entonces limpiamos         'el DataSet tipado para que solo contenga el registro correspondiente a un pdf a la hora de llamar la función que los crea         ds2.Tables(0).Clear()         'Creamos un dataRow con el esquema de un row del dataset tipado para luego agregarle esta fila con datos al mismo dataset         Dim row2 As DataRow = ds2.Tables(0).NewRow         'Hacemos el recorrido de los registros         For i = 0 To dt.Rows.Count - 1         'Esta parte es fundamental que se realice de esta manera, pues en lo personal no he logrado pasar datos entre datarow directamente.             con = dt.Rows(i)(0)             row2(0) = con             dat = dt.Rows(i)(1)             row2(1) = dat             dat = dt.Rows(i)(2)             row2(2) = dat             con = dt.Rows(i)(3)             row2(3) = con             con = dt.Rows(i)(4)             row2(4) = con             'Agrego la fila llena con los datos para crear el pdf al dataset tipado             ds2.Tables(0).Rows.Add(row2)             'Paso el dataset tipado como parámetro a la función que me genera el pdf             CrearPDF(ds2)             'Limpio el dataset para que la próxima iteración solo contenga el próximo registro             ds2.Tables(0).Clear()         Next     End Sub End Class Conclusión:Como pudieron observar, no ha sido necesaria la inclusión de ningún
componente extra, para generar el PDF. Esto trae como consecuencia, que podamos
crear aplicaciones Sin depender de las limitaciones que nos impongan terceros
con sus componentes. Con esto y al igual que el los artículos anteriores espero
que les sirva de ayuda a los que necesitan el conocimiento referente a la
generación de PDF, que en honor a la verdad se que muchos son. Pues hasta hace
poco era parte del conglomerado. Espero que les sirva y contribuya en su
crecimientos como desarrolladores.  |