Descargar el contenido de un DataSet en formato CSV Como generar un fichero en formato CSV con el contenido de un DataSet y forzar la descarga Fecha: 09/Sep/2004 (03/09/2004) |
Esta ejemplo muestra como crear una clase para convertir del contenido de un DataSet a un fichero, con formato CSV, y automatizar su descarga, de manera que en nuestra aplicación ASP.NET podamos integrar esta funcionalidad mediante un control Button o Linkbutton.
El formato CSV (¿Carácteres Separados por Valor?) es reconocido por todos los programas de hoja de cálculo (como MS Excel) y se puede utilizar como orígenes de datos (utilizando por ejemplo MS Text Driver para ODBC) y por lo tanto importar facilmente en cualquier base de datos.
La implementación de esta funcionalidad la hacemos en una clase, un buen nombre sería DataSet2CSV, de esta manera la podremos utilizar facilmente en varios proyectos, compilar por separado y por ejemplo incluirla facilmente en un Servicio Web a utilizar desde múltiples aplicaciones.
Conversión a CSV
La primera funcionalidad de la clase será convertir el contenido del DataSet a formato CSV. Para ello creamos una función, privada a la clase, que reciba el objeto DataSet y genera el contenido del fichero CSV
'Función de Conversión a CSV Private Function ConvierteCSV(ByRef pDatos As DataSet, _ Optional ByVal pDelimitadorColumnas As String = ",", _ Optional ByVal pDelimitadorRegistros As String = vbNewLine) As String 'Variables Locales Dim mSalida As String Dim mRegistro As String Dim mContadorRegistros As Integer = 0 Dim mContadorColumnas As Integer = 0 Dim mValor As String = "" Dim mNombreColumna As String = "" 'Solo si hay datos If Not IsNothing(pDatos) Then If pDatos.Tables.Count > 0 Then 'fila de titulos de columna mContadorColumnas = 0 mRegistro = "" 'para cada columna While mContadorColumnas < pDatos.Tables(0).Columns.Count mNombreColumna = pDatos.Tables(0).Columns(mContadorColumnas).ColumnName If mRegistro <> "" Then mRegistro = mRegistro & pDelimitadorColumnas End If mValor = """" & mNombreColumna & """" mRegistro = mRegistro & mValor mContadorColumnas = mContadorColumnas + 1 End While mSalida = mSalida & mRegistro 'procesa los registros del dataset While mContadorRegistros < pDatos.Tables(0).Rows.Count If mSalida <> "" Then mSalida = mSalida & pDelimitadorRegistros End If mRegistro = "" mContadorColumnas = 0 'para cada columna While mContadorColumnas < pDatos.Tables(0).Columns.Count If mRegistro <> "" Then mRegistro = mRegistro & pDelimitadorColumnas End If mValor = pDatos.Tables(0).Rows(mContadorRegistros)(mContadorColumnas) If InStr(mValor, pDelimitadorColumnas) > 0 Then mValor = """" & mValor & """" End If mRegistro = mRegistro & mValor mContadorColumnas = mContadorColumnas + 1 End While 'añade el registro mSalida = mSalida & mRegistro mContadorRegistros = mContadorRegistros + 1 End While End If End If Return mSalida End FunctionAutomatizar la descarga
Una vez generado el CSV es necesario implementar la descarga del resultado al PC del usuario final.
La siguiente implementación hace que se fuerze la descarga a disco e impide que se visualize el resultado de la conversión a CSV en el propio explorador.Private Sub DescargaCSV(ByVal pCSV As String, ByVal pNombreCSV As String) 'Obtiene la respuesta actual Dim response As System.Web.HttpResponse = System.Web.HttpContext.Current.Response 'Borra la respuesta response.Clear() response.ClearContent() response.ClearHeaders() 'Tipo de contenido para forzar la descarga response.ContentType = "application/octet-stream" response.AddHeader("Content-Disposition", "attachment; filename=" & pNombreCSV) 'Convierte el string a array de bytes Dim buffer(Len(pCSV)) As Byte Dim mContador As Long = 0 While mContador < Len(pCSV) buffer(mContador) = Asc(Mid(pCSV, mContador + 1, 1)) mContador = mContador + 1 End While 'Envia los bytes response.BinaryWrite(buffer) response.End() End SubEsta función la podemos utilizar para descargar cualquiero fichero. Si esa fuese nuestra idea sería recomendable hacer una clase propia para esta función con vistas a ampliarla con otras funciones para descargar ficheros existentes en disco, realizar cargas al servidor, etc ..
Interfaz pública de la clase
Para concluir la clase no resta hacer la función publica a través de la cual se va a acceder a las funcionalidades de la clase.
Public Sub EnviaCSV(ByRef pDatos As DataSet, Optional ByVal pNombreFicheroCSV As String = "datos.csv") 'Convirte el DataSet a String en CSV Dim mSalida As String mSalida = ConvierteCSV(pDatos) 'Envia el String en CSV DescargaCSV(mSalida, pNombreFicheroCSV) End SubUtilizando la clase
Una vez creada nuestra clase vamos a ver como utlizarla desde un formulario ASPX. Por ejemplo suponiendo que nuestro formulario tiene un Datagrid con nombre Datagrid1 y una función CargaDataSet que devuelve un DataSet con los datos a mostrar en el DataGrid. El Load de la página podría ser algo así:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Introducir aquí el código de usuario para inicializar la página If Not IsPostBack Then 'carga el dataset Dim mDatos as DataSet mDatos = CargaDataSet() 'carga el dataset en el datagrid DataGrid1.DataSource = mDatos DataGrid1.DataBind() End If End Sub Private Function CargaDataSet() As DataSet '....... End FunctionPara habilitar la generación y descarga del fichero CSV añadimos un linkbutton LinkButton1
Private Sub LinkButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LinkButton1.Click 'carga el dataset Dim mDatos as DataSet mDatos = CargaDataSet() 'instancia la clase Dim mDescargaCSV as New DataSet2CSV 'genera el CSV y lo envia mDescargaCSV.EnviaCSV(mDatos, "NombreFichero.csv") End SubAl pulsar el Linkbutton se convertirá el dataset a CSV y se mostrará al usuario la típica pantalla de Guardar como ...