viernes, 18 de enero de 2013

Regresando al blog

Nuevamente despues de un buen rato de ausencia, regreso a ingresar paginas en este blog, espero poder entontrar un tiempo para hacerlo crecer y compartir las experiencias del dia a dia que m ehe encontrado en el proceso del desarrollo de software, y en especial con las tecnologias .Net, ahora he estado explorando nuevos rumbos del desarrollo web, temas de aplicaciones multidispositivo y como evitarlo, el patron de diseño MVC aplicado a Asp .NET. Será un grandioso camino a seguir de ahora en adelante Saludos CR

martes, 18 de enero de 2011

Exportar pdf desde crystal sin usar crystal report viewer

Siguiendo con este blog, y con deseos que no muera, recorde la programación de reportes con crystal, en mi actual trabajo no los utilizan pero durante años los use y hacian mas amena la vida, sobre todo con reportes complejos, sin embargo me encontre con un problema cuando comenze a trabajar en web, y es que el crystal report viewer para Asp .Net era algo tedioso de configurar y consumia tiempo en detalles inverosimiles, por ende preferí exportar inmediatamente el reporte a pdf y mostrarlo desde la pagina, obviamente hay que hacer pruebas una vez puesta la solucion en producción ya que la exportación se ve afectada por los tamaños de pagina guardados en el servidor, pero el trabajo pienso que es mínimo una vez teniendo listo lo anterior, bueno pues despues de esta breve introducción let's fun programming!!!

Comenzaremos, creando un sitio web con el nombre Generar Pdf, en mi caso lo realize con vs 2008 apuntando al Net framework 2.0, en el webform Default ingresamos un TextBox llamado txtMostrar y un boton:




Dentro de la pagina creamos una función en javascript la cual tomara los datos de la caja de texto y posteriormente los mandara a la pagina que nos abrira el pdf

function mandaReporte()
{
 var txt = document.getElementById('txtMostrar');
 if(txt.value!='')
 {
   abrir('Default2.aspx?par='+txt.value,600,600,600,600,false);
 }
 else
 {
   alert('escribe algo');
 }        
 return false;
}
function abrir(pagina, ancho, alto, izquierda, arriba, sustituir) {            
 var ventana = window.open(pagina, "venta", 'location=no,menubar=no,status=no,toolbar=no,resizable=yes,scrollbars=yes',sustituir);
}

Una vez hecho esto integramos la pagina Default2.aspx en la cual mandaremos a traer el reporte hecho en crystal y lo mandara a exportar, tambien generamos la carpeta temp dentro de nuestro proyecto, que es donde se pondran los reportes para ser mostrados y la carpeta debe tener permisos para escritura lectura con la cuenta de asp del server donde lo instalen, el reporte fue previamente realizado y como esta en crystal es tema de otro post jeje, en fin en el behind de la pagina Default2.aspx pondremos lo siguiente:
protected void Page_Load(object sender, EventArgs e)
{
   string prueba = Request.QueryString["par"].ToString();
   DataTable tb = new DataTable();
   tb.Columns.Add("prueba",typeof(string));
   DataRow dr = tb.NewRow();
   dr["prueba"] = prueba;

   CrystalDecisions.CrystalReports.Engine.ReportDocument myReportDocument = new CrystalDecisions.CrystalReports.Engine.ReportDocument();
   myReportDocument.Load(Server.MapPath("~\\CrystalReport.rpt"));
   myReportDocument.SetDataSource(tb);


   Response.Buffer = false;
   Response.ClearContent();
   Response.ClearHeaders();
   //sakamos el nombre para el pdf
   string NombreExport = "ReportePrueba" + prueba + "_" + DateTime.Now.ToShortDateString().Replace('/', '_') + "";        //akamos la path a exportar
   //le ponemos la extención
   NombreExport += ".pdf";
   string path = Server.MapPath("~\\tem");
   path += "\\" + NombreExport ;
   //exportamos a pdf
   myReportDocument.ExportToDisk(ExportFormatType.PortableDocFormat, path);
   //redirijimos l pagina a el pdf
   string sRdireccion = "~\\tem";//
   sRdireccion += "\\"+NombreExport ;
   Response.Redirect( sRdireccion);
}

Traemos por el querystring el dato a imprimir, buscamos el reporte a imprimir y realizamos los metodos para la exportación a pdf grabando el reporte en nuestro proyecto, despues simplemente hacemos un redirect a donde se encuentre nuestro proyecto, es todo, realmente sencillo, cualquier cosa se aceptan sugerencias y comentarios, asi como adjunto el proyecto para descarga, saludos;

Generar Pdf Crystal....

jueves, 12 de febrero de 2009

GridView Dinámico con DataTable y ViewState

Saludos, creo que espere bastante tiempo antes de publicar una entrada en este blog pero el trabajo ha sido abrumador, jejeje.
Bueno para empezar tuve un problema con crear controles en tiempo de ejecución, así que esta solucion tiene una pequeña historia con algo de teoría:
Cuando programamos en Asp net es común que se nos presenten complicaciones con los controles creados en tiempo de ejecución ya que al crearlos se muestran perfectamente al usuario, pero solo la primera vez, ya que si hay un postback de la pagina, los controles se mueren y hay que redibujarlos para que el usuario pueda volver a verlos, lo que significa, oh desilucion la pérdida de los datos que se nos haya ocurrido meterle a nuestros amados controles.
Para persistir los datos entre las idas y venidas de la pagina entre el cliente y el servidor existe en .Net una maravillosa herramienta llamada View State, la cual de forma natural realiza esta tarea en todos los controles de .Net para evitar la pérdida de los datos, pero como nuestros controles son creados en tiempo de ejecución tendriamos que incluir a mano dicho uso del View State.
Hasta aqui todo suena de lujo, es sencillo incluir valores en el view state y utilizarlos en la pagina para llevar y traer valores es relativamente sencillo, pero el detalle es que para poder incluir algo en el view state, éste debe ser serializable.
al iniciar este experimento me lleve el chubasco de que cuando guardaba mi caja de texto en vel view state no habia problema, el problema era al intentar traer de regreso el valor, ya que me marcaba un pequeño error:

El tipo 'System.Web.UI.WebControls.TextBox' del ensamblado 'System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' no está marcado como serializable.


bastante tiempo le di vueltas al por que era esto hasta que le pregunte a un amigo (Edwin el crédito es tuyo) si sabia algo al respecto, entonces me preguntó el por que deseaba hacerlo de esta manera con los textboxes, y me dijo :¿por que no lo haces con un gridview y lo rellenas con una tabla? las tablas si son serializables, así que despues de meditarlo me dije, ¿por que no lo hago asi? y bueno lo que salio fue algo mas o menos así:
en primer lugar el html, ¿que necesitaba? un grid view, así que a escribir un poco de código:
El html:

como no se puede poner escrito lo veremos en imagen

En éste código pusimos un grid view un poco estilizado con un item template llamado txtName y un require field validator para forzar al usuario a escribir algo en la caja, el valor a recibor se declara en el Eval y es "nombreAlumno" asi que con esto esta terminada la parte del usuario

y en el behind :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
//la libreia para usar la clase DataTable
using System.Data;

public partial class _Default : System.Web.UI.Page
{
//las variables que trabajarán con el view state
private DataTable __tabla;
protected DataTable tabla// nuestra variable de view state es ViewState["tabla"]
{
get
{
if (ViewState["tabla"] != null)
return (DataTable)ViewState["tabla"];
else
{
__tabla = new DataTable();
ViewState["tabla"] = (DataTable)__tabla.Clone();
return this.__tabla;
}
}
set
{
ViewState["tabla"] = value;
this.__tabla = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)//en caso que no sea un post back o sea la primera carga de la página
{
//si no tenemos columnas declaradas en la tabla guardada en el view state
if (tabla.Columns.Count == 0)
{
cargaColumnas();//este metodo se encargará de insertarle columnas a la tabla
}
}

//este mètodo leera la grilla cuando se haga un postback para traer los datos que hayamos
//modificado en la parte del usuario y con esto cargar nuestra tabla guardada en el view state
//
leeGrilla();

}
protected void Page_PreRender(object sender, EventArgs e)
{
//en este evento cargaremos el data source del grid asi como el bindeo de los datos
usaEnlace();
}

protected void cargaColumnas()
{
//ingresamos la columna a nuestra tabla
tabla.Columns.Add("nombre", typeof(string));
}
protected void btnAgrega_Click(object sender, EventArgs e)
{
DataRow dr = tabla.NewRow();//instanciamos una nueva fila de nuestra tabla       
tabla.Rows.Add(dr);//insertamos la copia de fila y le creamos una nueva fila a nuestra tabla
}
protected void leeGrilla()
{
if (grvAlumnos.Rows.Count > 0)//en caso que el grid tenga filas realizamos las operaciones de lectura
{
tabla.Rows.Clear();//eliminamos las filas de la tabla guardada en el grid
foreach (GridViewRow gr in grvAlumnos.Rows)//recorremos la grilla de datos
{
DataRow dr = tabla.NewRow();
//el truco para traer los datos de el template de la grilla es buscar los controles gracias de nuevo Edwin jeje
// al hacer el retrieve de el itemtemplate lo casteamos a tipo TextBox para poder usar el text (esto puede ser para cualquier control)
dr["nombre"] = ((TextBox)gr.Cells[0].Controls[1]).Text;
tabla.Rows.Add(dr);//agregamos la fila en la tabla
}              
}
}

protected void usaEnlace()
{
grvAlumnos.DataSource = tabla;//asignamos como datasource al grid la tabla que guardamos en el view state
grvAlumnos.DataBind();//bindeamos los datos de la grilla
}

}

Explicamos un poco el código:
bueno para empezar las librerias, sin la System.Data no hay DataTable asi que a agregarla, después tenemos la variable que movera los datos a traves del view state, una vez con esto trabajamos con la tabla, hay que ponerles columnas asi que estas dependeran de los datos que querramos guardar, para el ejemplo los datos en la grilla estan en un item template con un textbox dentro pero puede ser cualquier control, la carga de las columnas se hara la primera vez que cargue la pagina y en caso de no tener columnas en la tabla, posteriormente si se quieren agregar columnas a la grilla se deberan de agregar en la tabla y volver a poner el data source de la grilla y el bindeo de datos, los enlaces de datos los realizamos en el Page_PreRender ya que es el ultimo evento antes de mostrar la pagina y si lo hacemos en el load puede provocar un conflicto , eso es otra hisoria.
Ahora, cada vez que se haga un postback hay que revisa los datos de la grilla para ahora llenar con estos la tabla y rebindear los datos, esto es relativamente sencillo pero no es tan obvio hasta que no lo vemos en vivo, a mi me costo mas de un dia el encontrar la solución, y esto con ayuda de el buen Edwin, saludos, espero les sirva para alguna cosilla que requieran hacer, dudas comentarios, sugerencias y correcciones con gusto las atendere, este es mi primer post con una solucion así que estoy muy contento, aunque no le pude poner con colores el codigo para diferenciar, pero espero corregir rsto pronto, saludos y estamos en contacto.

Como es mejor con ejemplos aqui les dejo el ejemplo para descargar, esta hecho con el web developer 2008 express, saludos.
gridview dinamico....

miércoles, 26 de noviembre de 2008

Inicio

El primer post de mi publicación, antes que nada agradecer a quienes lean este blog y los articulos existentes en el, publicare cosas sobre tecnologìas .Net y algunas soluciones personales a distintos problemas con los que me he enfrentado, asi como traducciones de soluciones al idioma castellano, espero comenzar pronto y poder ayudar a resolver problemas a quienes me honren con su visita.