Hola, en esta ocasión les traigo un ejemplo de como exportar los datos de un dataGridView (en WinForms) a diversos formatos sin la necesidad de interactuar con componentes ActiveX y tampoco de utilizar la interoperabilidad de Office.
En el caso de utilizar PDF si utilice una librería llamada iTextSharp y para los demás es solo programación, pero eso lo veremos un poco mas adelante.
Este ejemplo muestro un programa que tiene un dataGridView en el que se muestran los datos que se llenan desde una base de datos y esa información es la que se exporta a diferentes formatos. En esta entrada no explico como se llena el dataGridView porque hay muchas formas de hacerlo y me imagino que eso no les interesa. Habiendo quedando claro eso comencemos con el ejemplo.
Exportando a PDF
Para la exportación de los datos del dataGridView a PDF estoy utilizando una librería muy interesante llamada iTextSharp que es un "Port" de otra librería llamada iText para Java solo que esta es para C#. Al estar utilizando esta librería me sorprendió de una forma muy grata ya que no la conocía. esta puede ser una opción a crystal reports al momento de hacer reportes principalmente si es que no deseas que tu aplicación eleve considerablemente su tamaño y su rendimiento, eso si es mucho mas trabajo porque todo es por código y no puedes diseñar tus reportes de una forma visual aunque con un poco de dedicación puedes sacar PDF’s muy completos en cuanto a diseño ya que esta librería te provee de muchas clases para diseñar el PDF conforme a tus necesidades (Para mas información sobre iTextSharp visiten este pagina http://itextsharp.sourceforge.net/ ), pero bueno no me quiero meter tanto en esto y continuemos con el ejemplo.
Primero que nada creamos un Nuevo proyecto del Tipo WidowsApplication en Visual Studio y agregamos una referencia a la DLL de iTextSharp (descargar DLL iTextSharp) en nuestro proyecto.
Agregamos la dll de iTextSharp nuestro proyecto.
Una vez teniendo agregada la DLL diseñamos un WindowsForm como en la siguiente imagen agregamos un botón al que le pondremos “Exportar ” y accedemos a su evento Onclick.
En este ejemplo tendremos estos datos y los exportaremos a PDF usando ItextSharp.
Antes de poner el código es necesario agregar los siguientes espacios de nombres entre otros:
using iTextSharp.text;
using iTextSharp.text.pdf;
//Código para exportar DataGridView a PDF usando iTextSharp
//Evento clic del Botón Exportar
private void Exportar_pdf(object sender, EventArgs e)
{
try
{
Document doc = new Document(PageSize.A4.Rotate(), 10, 10
,10, 10);
string filename = "DataGridViewTest.pdf";
FileStream file = new FileStream(filename,
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.ReadWrite);
PdfWriter.GetInstance(doc, file);
doc.Open();
GenerarDocumento(doc);
doc.Close();
Process.Start(filename);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Función que genera el documento Pdf
public void GenerarDocumento(Document document)
{
//se crea un objeto PdfTable con el numero de columnas del
//dataGridView
PdfPTable datatable = new PdfPTable(dataGridView1.ColumnCount);
//asignamos algunas propiedades para el diseño del pdf
datatable.DefaultCell.Padding = 3;
float[] headerwidths = GetTamañoColumnas(dataGridView1);
datatable.SetWidths(headerwidths);
datatable.WidthPercentage = 100;
datatable.DefaultCell.BorderWidth = 2;
datatable.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER;
//SE GENERA EL ENCABEZADO DE LA TABLA EN EL PDF
for (int i = 0; i < dataGridView1.ColumnCount; i++)
{
datatable.AddCell(dataGridView1.Columns[i].HeaderText);
}
datatable.HeaderRows = 1;
datatable.DefaultCell.BorderWidth = 1;
//SE GENERA EL CUERPO DEL PDF
for (int i = 0; i < dataGridView1.RowCount; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
datatable.AddCell(dataGridView1[j, i].Value.ToString());
}
datatable.CompleteRow();
}
//SE AGREGAR LA PDFPTABLE AL DOCUMENTO
document.Add(datatable);
}
//Función que obtiene los tamaños de las columnas del grid
public float[] GetTamañoColumnas(DataGridView dg)
{ float[] values = new float[dg.ColumnCount];
for (int i = 0; i < dg.ColumnCount; i++)
{ values[i] = (float)dg.Columns[i].Width;
}
return values;
}
Imagen del Pdf generado en este ejemplo.
Nota: Este ejemplo esta hecho para Windows Forms para el componente DataGridView pero para ASP.net seria muy similar para el componente DataGrid solo que manejando con mucho cuidado los paths.
Exportando a otros formatos
diseño de la forma para exportar a otros formatos en este ejemplo
Exportando A Excel
Para la exportación a este formato es una pequeña trampita si es que se puede llamar así porque lo que se esta haciendo es generar un documento con código HTML pero guardarlo con extensión XLS!!!, en donde simplemente los datos que tenemos en el Grid lo pasamos a una tabla HTML y ya con eso tendremos nuestros datos exportados a Excel .
El siguiente código es una clase llamada “OtrosFormatos” la cual tiene 2 métodos los cuales son “Export” y “ExportCSV” este ultimo para exportar al formato CSV además de contar con 2 atributos los cuales son el “StreamWriter” (clase del NameSpace System.IO) y la ruta en donde queremos guardar el archivo.
clase OtrosFormatos
public class OtrosFormatos
{
StreamWriter w;
string ruta;
public string xpath { get { return ruta; } set { value = ruta; }}
/// <summary>
/// Constructor que establece el path del archivo
/// </summary>
/// <param name="path"></param>
public OtrosFormatos(string path)
{
ruta = @path;
}
/// <summary>
/// Exporta datos a un archivo
/// </summary>
/// <param name="titulos"></param>
/// <param name="datos"></param>
public void Export(ArrayList titulos, DataTable datos)
{
try
{
FileStream fs = new FileStream(ruta, FileMode.Create,
FileAccess.ReadWrite);
w = new StreamWriter(fs);
string comillas = char.ConvertFromUtf32(34);
StringBuilder html = new StringBuilder();
html.Append(@"<!DOCTYPE html PUBLIC" + comillas +
"-//W3C//DTD XHTML 1.0 Transitional//EN" + comillas +
" " + comillas
+ http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
+ comillas + ">");
html.Append(@"<html xmlns=" + comillas
+ http://www.w3.org/1999/xhtml
+ comillas + ">");
html.Append(@"<head>");
html.Append(@"<meta http-equiv=" + comillas +"Content-Type"
+ comillas + "content=" + comillas
+ "text/html; charset=utf-8" + comillas+"/>");
html.Append(@"<title>Untitled Document</title>");
html.Append(@"</head>");
html.Append(@"<body>");
//Generando encabezados del archivo
//(aquí podemos dar el formato como a una tabla de HTML)
html.Append(@"<table WIDTH=730 CELLSPACING=0 CELLPADDING=10
border=8 BORDERCOLOR=" + comillas + "#333366"
+ comillas + " bgcolor=" + comillas + "#FFFFFF"
+ comillas + ">");
html.Append(@"<tr> <b>");
foreach (object item in titulos)
{
html.Append(@"<th>" + item.ToString() + "</th>");
}
html.Append(@"</b> </tr>");
//Generando datos del archivo
for (int i = 0; i < datos.Rows.Count; i++)
{
html.Append(@"<tr>");
for (int j = 0; j < datos.Columns.Count; j++)
{
html.Append(@"<td>" +
datos.Rows[i][j].ToString() + "</td>");
}
html.Append(@"</tr>");
}
html.Append(@"</body>");
html.Append(@"</html>");
w.Write(html.ToString());
w.Close();
}
catch (Exception ex)
{
throw ex;
}
} //Fin de la Función Export
/// <summary>
/// Genera un archivo CSV
/// </summary>
/// <param name="titulos"></param>
/// <param name="datos"></param>
public void ExportCSV(ArrayList titulos, DataTable datos)
{
try
{
FileStream fs = new FileStream(ruta, FileMode.Create,
FileAccess.ReadWrite);
w = new StreamWriter(fs);
string comillas = char.ConvertFromUtf32(34);
StringBuilder CSV = new StringBuilder();
//Encabezados
for (int i = 0; i < titulos.Count; i++)
{
if (i != (titulos.Count - 1))
CSV.Append(comillas + titulos[i].ToString() + comillas + ",");
else
CSV.Append(comillas + titulos[i].ToString() + comillas
+ Environment.NewLine);
}
// se generan datos
for (int i = 0; i < datos.Rows.Count; i++)
{
for (int j = 0; j < datos.Columns.Count; j++)
{
if (j != (titulos.Count - 1))
CSV.Append(comillas + datos.Rows[i][j].ToString()
+ comillas + ",");
else
CSV.Append(comillas + datos.Rows[i][j].ToString()
+ comillas + Environment.NewLine);
}
}
w.Write(CSV.ToString()); //se escribe la cadena en el archivo
w.Close();
}
catch (Exception ex)
{
throw ex;
}
} //Fin de ExportCSV
} // Fin de Clase OtrosFormatos
Código del uso de esta clase en la Aplicación para Exportar a Excel.
//Código para exportar a Excel
//Evento Onclick del Botón
private void BotExcel_Click(object sender, EventArgs e)
{
try
{
ArrayList titulos = new ArrayList();
DataTable datosTabla = new DataTable();
//Especificar ruta del archivo con extensión de EXCEL.
OtrosFormatos OF = new OtrosFormatos(Application.StartupPath
+ @\\test.xls);
//obtenemos los titulos del grid y creamos las columnas de la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
titulos.Add(item.HeaderText);
datosTabla.Columns.Add();
}
//se crean los renglones de la tabla
foreach (DataGridViewRow item in dataGridView1.Rows)
{
DataRow rowx = datosTabla.NewRow();
datosTabla.Rows.Add(rowx);
}
//se pasan los datos del dataGridView a la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
foreach (DataGridViewRow itemx in dataGridView1.Rows)
{
datosTabla.Rows[itemx.Index][item.Index] =
dataGridView1[item.Index, itemx.Index].Value;
}
}
OF.Export(titulos, datosTabla);
Process.Start(OF.xpath);
MessageBox.Show("Proceso Completo");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} //Fin del Evento Clic del Botón
Archivo de Excel Resultante.
Exportación a WORD
Para la exportación de los datos a Word se sigue el mismo procedimiento que para exportar los datos a Excel, solo que en vez de guardar el archivo con extensión .xls lo guardamos con extensión .doc.
//Código para exportar a Word
//Evento Onclick del Botón
private void BotWord_Click(object sender, EventArgs e)
{
try
{
ArrayList titulos = new ArrayList();
DataTable datosTabla = new DataTable();
//Especificar ruta del archivo con extensión de WORD.
OtrosFormatos OF = new OtrosFormatos(Application.StartupPath
+ @\\test.doc);
//obtenemos los titulos del grid y creamos las columnas de la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
titulos.Add(item.HeaderText);
datosTabla.Columns.Add();
}
//se crean los renglones de la tabla
foreach (DataGridViewRow item in dataGridView1.Rows)
{
DataRow rowx = datosTabla.NewRow();
datosTabla.Rows.Add(rowx);
}
//se pasan los datos del dataGridView a la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
foreach (DataGridViewRow itemx in dataGridView1.Rows)
{
datosTabla.Rows[itemx.Index][item.Index] =
dataGridView1[item.Index, itemx.Index].Value;
}
}
OF.Export(titulos, datosTabla);
Process.Start(OF.xpath);
MessageBox.Show("Proceso Completo");
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
} //Fin del Evento Clic del Botón

Archivo .doc Resultante
Exportación a HTML
Para la exportación a HTML es la mas sencilla ya que en este ejemplo lo que se crea es un archivo HTML solo se guarda con extensión HTML y ya esta.
//Código para Exportar a HTML
//Evento Click del Botón
private void BotHTML_Click(object sender, EventArgs e)
{
try
{
ArrayList titulos = new ArrayList();
DataTable datosTabla = new DataTable();
//Especificar ruta del archivo con extensión de HTML.
OtrosFormatos OF = new OtrosFormatos(Application.StartupPath
+ @\\test.html);
//obtenemos los titulos del grid y creamos las columnas de la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
titulos.Add(item.HeaderText);
datosTabla.Columns.Add();
}
//se crean los renglones de la tabla
foreach (DataGridViewRow item in dataGridView1.Rows)
{
DataRow rowx = datosTabla.NewRow();
datosTabla.Rows.Add(rowx);
}
//se pasan los datos del dataGridView a la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
foreach (DataGridViewRow itemx in dataGridView1.Rows)
{
datosTabla.Rows[itemx.Index][item.Index] =
dataGridView1[item.Index, itemx.Index].Value;
}
}
OF.Export(titulos, datosTabla);
Process.Start(OF.xpath);
MessageBox.Show("Proceso Completo");
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
} // Fin del Evento Click del botón
Archivo html resultante
Exportación a CSV (comma-separated values)
La exportación a este formato es bastante sencilla y se usa el mismo principio que en los demás solo que usando el método ExportCSV de este ejemplo ya que el vaciado de los datos es diferente porque no se crea un documento HTML sino que se escribe directamente sobre un archivo csv.
Nota: Cabe señalar que este tipo de formatos se puede abrir también en Excel en cual se mostrara los datos en forma de tabla.
//Código para Exportar a CSV
//Evento Click del Botón
private void BotCSV_Click(object sender, EventArgs e)
{
try
{
ArrayList titulos = new ArrayList();
DataTable datosTabla = new DataTable();
//Especificar ruta del archivo con extensión de CSV.
OtrosFormatos OF = new OtrosFormatos(Application.StartupPath
+ @\\test.csv);
//obtenemos los titulos del grid y creamos las columnas de la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
titulos.Add(item.HeaderText);
datosTabla.Columns.Add();
}
//se crean los renglones de la tabla
foreach (DataGridViewRow item in dataGridView1.Rows)
{
DataRow rowx = datosTabla.NewRow();
datosTabla.Rows.Add(rowx);
}
//se pasan los datos del dataGridView a la tabla
foreach (DataGridViewColumn item in dataGridView1.Columns)
{
foreach (DataGridViewRow itemx in dataGridView1.Rows)
{
datosTabla.Rows[itemx.Index][item.Index] =
dataGridView1[item.Index, itemx.Index].Value;
}
}
OF.ExportCSV(titulos, datosTabla);
Process.Start(OF.xpath);
MessageBox.Show("Proceso Completo");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} //Fin del Evento Click del Botón
Archivo CSV resultante
Este ejemplo en conjunto con todo su código lo pueden descargar desde mi SkyDrive aquí.
Nota: La conexión a la base de datos de este ejemplo la realice con SQLite, en el ejemplo pongo lo necesario para que funcione el ejecutable incluyendo la base de datos, la DLL iTextSharp y el DataProvider de SQLite, pero si quieren modificar el código y que funcione tendrán que instalar el Proveedor de datos SQLite, esto lo hice por portabilidad ya que con SQlite la base de datos esta en un pequeño archivo.
Pueden preguntar con toda confianza por si tiene alguna duda con SQLite y si esta dentro de mis posibilidades intentare ayudarlos.
Saludos!!!