Exportar a PDF

download Exportar a PDF

of 27

Transcript of Exportar a PDF

Exportar a PDF, Excel y Otros formatos en C# Exportar a PDF, Excel y Otros formatos en C# (DataGridView & Windows Forms).Hola, en esta ocasin 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 librera llamada iTextSharp y para los dems es solo programacin, 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 informacin 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 exportacin de los datos del dataGridView a PDF estoy utilizando una librera muy interesante llamada iTextSharp que es un "Port" de otra librera llamada iText para Java solo que esta es para C#. Al estar utilizando esta librera me sorprendi de una forma muy grata ya que no la conoca. esta puede ser una opcin a crystal reports al momento de hacer reportes principalmente si es que no deseas que tu aplicacin eleve considerablemente su tamao y su rendimiento, eso si es mucho mas trabajo porque todo es por cdigo y no puedes disear tus reportes de una forma visual aunque con un poco de dedicacin puedes sacar PDFs muy completos en cuanto a diseo ya que esta librera te provee de muchas clases para disear el PDF conforme a tus necesidades (Para mas informacin 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 diseamos un WindowsForm como en la siguiente imagen agregamos un botn 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 cdigo es necesario agregar los siguientes espacios de nombres entre otros: using iTextSharp.text; using iTextSharp.text.pdf; //Cdigo para exportar DataGridView a PDF usando iTextSharp //Evento clic del Botn 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); } } //Funcin 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 diseo del pdf datatable.DefaultCell.Padding = 3; float[] headerwidths = GetTamaoColumnas(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); }

//Funcin que obtiene los tamaos de las columnas del grid

public float[] GetTamaoColumnas(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

diseo de la forma para exportar a otros formatos en este ejemplo

Exportando A Excel Para la exportacin a este formato es una pequea trampita si es que se puede llamar as porque lo que se esta haciendo es generar un documento con cdigo HTML pero guardarlo con extensin 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 cdigo es una clase llamada OtrosFormatos la cual tiene 2 mtodos los cuales son Export y ExportCSV este ultimo para exportar al formato CSV adems 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; }}

/// /// Constructor que establece el path del archivo ///

/// public OtrosFormatos(string path) { ruta = @path; }

/// /// Exporta datos a un archivo /// /// /// 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(@""); html.Append(@""); html.Append(@""); html.Append(@""); html.Append(@"Untitled Document"); html.Append(@""); html.Append(@"");

//Generando encabezados del archivo //(aqu podemos dar el formato como a una tabla de HTML) html.Append(@""); html.Append(@" ");foreach (object item in titulos) { html.Append(@"" + item.ToString() + ""); } html.Append(@" ");

//Generando datos del archivo for (int i = 0; i < datos.Rows.Count; i++)

{ html.Append(@""); for (int j = 0; j < datos.Columns.Count; j++) { html.Append(@"" + datos.Rows[i][j].ToString() + ""); } html.Append(@""); } html.Append(@""); html.Append(@""); w.Write(html.ToString()); w.Close(); } catch (Exception ex) { throw ex; } } //Fin de la Funcin Export

/// /// Genera un archivo CSV /// /// ///

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

Cdigo del uso de esta clase en la Aplicacin para Exportar a Excel.//Cdigo para exportar a Excel //Evento Onclick del Botn private void BotExcel_Click(object sender, EventArgs e) { try { ArrayList titulos = new ArrayList();

DataTable datosTabla = new DataTable(); //Especificar ruta del archivo con extensin 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 Botn

Archivo de Excel Resultante.

Exportacin a WORD Para la exportacin 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 extensin .xls lo guardamos con extensin .doc.//Cdigo para exportar a Word //Evento Onclick del Botn private void BotWord_Click(object sender, EventArgs e) { try

{ ArrayList titulos = new ArrayList(); DataTable datosTabla = new DataTable(); //Especificar ruta del archivo con extensin 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 Botn

Archivo .doc Resultante

Exportacin a HTML Para la exportacin a HTML es la mas sencilla ya que en este ejemplo lo que se crea es un archivo HTML solo se guarda con extensin HTML y ya esta.//Cdigo para Exportar a HTML //Evento Click del Botn private void BotHTML_Click(object sender, EventArgs e)

{ try { ArrayList titulos = new ArrayList(); DataTable datosTabla = new DataTable(); //Especificar ruta del archivo con extensin 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 botn

Archivo html resultante

Exportacin a CSV (comma-separated values)

La exportacin a este formato es bastante sencilla y se usa el mismo principio que en los dems solo que usando el mtodo 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 sealar que este tipo de formatos se puede abrir tambin en Excel en cual se mostrara los datos en forma de tabla.//Cdigo para Exportar a CSV //Evento Click del Botn private void BotCSV_Click(object sender, EventArgs e) { try { ArrayList titulos = new ArrayList(); DataTable datosTabla = new DataTable(); //Especificar ruta del archivo con extensin 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 Botn

Archivo CSV resultante

Este ejemplo en conjunto con todo su cdigo lo pueden descargar desde mi SkyDrive aqu.

Nota: La conexin 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 cdigo y que funcione tendrn que instalar el Proveedor de datos SQLite, esto lo hice por portabilidad ya que con SQlite la base de datos esta en un pequeo archivo.Pueden preguntar con toda confianza por si tiene alguna duda con SQLite y si esta dentro de mis posibilidades intentare ayudarlos. Saludos!!!

Etiquetas de Technorati: C#,Exportar,PDF,Excel,Word,HTML,DataGridView,Windows Forms,CSV,Visual Studio Posted: Nov 06 2009, 01:37 PM by Edgar Rafael Galicia Reyes | with 46 comment(s)

Filed under: C#, Visual Studio 2008, Exportar, PDF, Word, Excel, CSV, HTML, DataGridView,Windows Forms Comments DoWaL said:Como Puedo Exportar datos de un DataGridView a PDF en Asp.Net?# November 7, 2009 3:56 PM

Luna said:Gracias, me ayudo muchoooo, me salvaste Jajaja Gracias# November 11, 2009 4:51 PM

aurelio said:Amigo, excelente la informacion, mas bien tengo una pregunta, cuando ejecuto el programa y exporto a PDF los resultados de mi datagridview, el programa me devuelve un error: Referencia a objeto no establecida como instancia de un objeto. Tu sabes a que se debe este error, por lo que averigue el error se da cuando la clase no es iniciada. Uso VS2005. Gracias.# November 18, 2009 10:05 PM

erisbel said:Estupendo.... genial este ejemplo, muy bueno con las palabras reservadas del codigo en colores facil de leer y entender. Gracias. Muy util# December 3, 2009 9:57 AM

Esteban said:Excelente...... me ayuda un monton... estoy cansado de renegar con las herramientas de reportes q son demasiado estaticas a mi gusto... Saludos!# December 10, 2009 10:20 PM

drytusss said:muy buen articulo... Thanks a lot :)# December 15, 2009 1:55 AM

Anai said:Muuui buen aporteee!!! Sigue asi sirvee mucho:D# January 5, 2010 6:30 PM

Matias said:Hola muy buen articulo, me ayudo mucho. una pregunta como seria para exportar el datagrid a pdf pero omitiendo una fila Muchas Gracias!# January 5, 2010 9:27 PM

Francisco said:Muy bueno, pero tienes el mismo ejemplo para VB.Net es que soy novato y aun no lo puedo pasar de c# a vb Saludos,

# January 6, 2010 8:46 AM

Jane said:Hola muy bueno tu articulo, pero tengo una duda en la parte del codigo para exportar a CSV tiene la dll de OtrosFormatos?????????? es que no me reconoce esa linea de codigo OtrosFormatos OF = new OtrosFormatos(Application.StartupPath + @\\test.csv); Gracias por tu ayuda# January 14, 2010 5:56 PM

Jorge Luis said:Hola!! muy buena la info pero tengo una pergunta... me dic que hay un error con la variable Process, que en el ejemplo de PDF parece que viene de la clase iText, en mi caso no reconoce esta variable.. me podrias ayudar?# February 23, 2010 9:53 AM

gaby said:Mucha mucha gracias por la explicacion muy buena y me ayudo mucho, ojala hubieran mas aportes como este.# June 12, 2010 11:33 PM

dodos said:amigo exelente, te doy un 100, solo que me marca un error de referencia, que significa???# June 13, 2010 12:26 AM

jose said:podrias subir denuevo el poryecto# June 20, 2010 1:11 PM

jose said:q pongo en el evento click para exportara a un pdf seria algo asi le envio el metodo pero me sale error (no acepta 0 argumentos ) Exportar_pdf();# June 20, 2010 1:35 PM

jose said:como haria para tb me expotet el encabezado d mis filas# June 22, 2010 12:49 AM

jose said:como hago para tb importat el encabezad las filas# June 22, 2010 1:00 AM

lukas cely said:parce sos un montruo, llevabarato buscando esto...

si fuese posible seria bueno saber si exporta imagenes...# July 17, 2010 2:15 PM

jim said:me sale un error en http://# July 23, 2010 3:41 PM

andrea said:gracias de mucha utilidad# August 10, 2010 12:19 PM

andrea said:gracias me ayudo bastante# August 10, 2010 12:21 PM

fede said:Hola parece bueno lastima que el error que ponen de Referencia a objeto no establecida como instancia de un objeto es debido a esta parte datatable.AddCell(DGVMEMe[j, i].Value.ToString()); me parece que es por que en el recorrido que hace en el grid recorre una parte null por eso es el error creo espero lo soluciones y para los que les da el error en el process tienen que importar la siguientes referencias: using System.IO; using System.Diagnostics; gracias por favor ayudanos con los errores# August 12, 2010 5:16 PM

Carlos said:Me pasa lo mismo: "Object reference not set to an instance of an object", que podra ser? ayuda...# August 19, 2010 7:40 PM

Edgar Rafael Galicia Reyes said:Con lo del Error de "Referencia a objeto no establecida como instancia de un objeto", lo mas probable es que en la parte del codigo DGVMEMe[j, i].Value.ToString() sea un valor nulo en la base de datos y se intente convertir en String y por lo tanto "Crashea", este ejemplo es algo bastante simple y por lo tanto faltan algunas validaciones, Sorry =)# August 20, 2010 9:30 AM

Coco said:

Hola me ayudo bastante el codigo especialmente lo de excel usando html muy bueno , tengo una duda como podria incrustar una imagen para el mismo caso de exportar a Excel Gracias# September 27, 2010 9:09 AM

Andres said:Amigo Muchas GRACIAS!.. me has salvado la vida! :D# October 22, 2010 3:41 PM

Sussy Q said:DataGridView1.RowCount-1 esto hace que no cuente la ultima fila o row vacia y no marca error.# November 30, 2010 2:26 PM

elmarros said:Hola, la verdad esta muy bueno este ejemplo ya lo ajuste al mi aplicacion y me funciono muy bien. Solo una pregunta, como puedo hacer que el archivo que me genera tantro en pdf y word pueda insertar imagenes y darle formato al texto, si me pueden ayudar se los agradecer mucho. que esten bien y saludos.# January 6, 2011 6:18 PM

azzul said:aurelio, eres programador???... si viste el codigo y eres programador, entenderas que te sale ese mensaje por que entra al cath , y eso sucede por q alguna celda del datagrid esta vacia y si ese no es el error, ps ponle puntos de interrupcion y averigualo por ti mismo , saludos Ahh, gracias por la informacion Atte. una aprendiz de programacin.# January 25, 2011 8:38 AM

Khriz Muoz said:Excelentes Post compadre....>>>># February 15, 2011 2:23 PM

Pato said:"Referencia a objeto no establecida como instancia de un objeto" Saquen la opcion de agreagar filas a la tabla y listo no hay valores nulos# February 25, 2011 10:41 AM

bbb said:Muchiiiiiissssssssiiiiiiimas gracias!!! :)# March 19, 2011 8:02 AM

Gil said:Error no!!!!!!!!

Bueno tengo la solucin al error "Referencia a objeto no establecida como instancia de un objeto" solo hay que poner en la parte del for que llena la tabla en -1 ya q el grid deja el ultimo renglon vacio por lo q no hay q tomarlo en cuenta osea seria asi .RowCount-1# May 7, 2011 5:28 PM

leonardo castro said:wao. men, muchas gracias por este post

Me salvo la vida jeje# May 24, 2011 12:16 PM

Jose Cabrera said:Hola, alguien me podra decir si se le puede asignar un Ttulo (con alguna propiedad iText) al PDF cuando exportamos el DataGV.# June 15, 2011 11:12 PM

Ismel said:@\\test.xls esta mal escrito de todos modos gracias por la fuente, solo cambias la diagonal mas o menos asi queda @"/test.xls" por que ponia la estas puesto rnla fuente y me marcaba error que no se encotraba la ruta.# June 20, 2011 1:28 PM

magda said:me marca erro r en FileStream y FileMode en la exportacion a pdf ayuda please!!!!# July 19, 2011 8:45 PM

Joe said:Como puedo contactarme contigo para hacer un proyecto que tengo en mente, soy de Lima Peru. Espero tu respuesta, mi email es: [email protected] Cel. +51 996056556# July 23, 2011 1:15 PM

Draco said:Hola que tal, bueno para los que les marca error de: Referencia a un objeto no valido, es en esta linea. Grid[j, i].Value.ToString(), ese error se presenta por que se quiere convertir un valor null a cadena y no se puede.

Yo lo resolvi poniendo esto: if ( !string.IsNullOrEmpty( (String)Grid[j, i].Value ) ) Y con eso ya no e tenido ningun problema. Muy buen aporte, solo una duda. Si yo deseo poner encabezados en el PDF antes de que aparezca la grilla como se le puede hacer ?. Gracias... =)# July 30, 2011 3:51 PM

eduard said:hola, gracias por el aporte, tengo un problema, estoy creando un sistema para una materia, pero me sale un error al querer exportar a pdf, Referencia a objeto no establecida como instancia de un objeto. estoy trabajando con c#2010 y sql 2008 espero ke puedan ayudarme, my email es: [email protected] agradeceria cualquier ayuda# August 14, 2011 2:49 PM

Dario Resendiz said:No me aparece valida la clase Process en los metodos tengo que agrega akguna biblioteca del sistema??? saludos uso VS2010# August 20, 2011 2:10 AM

juan said:muy bueno el post pero al generar el instalador e instaarlo en windows 7 marca error diciendo acceso denegado a la ruta de aaceso# September 26, 2011 10:28 AM

carlos said:jodaa brotherrr me salvo la patria con este proyectoooo gracias..... ahora lo que me falta es importar de afuera hacia el gridview. aqui les dejo mi correo: [email protected]# October 6, 2011 2:31 AM

carlos said:gracias me sirvio de muchoooo.

pero ahora me falta es el importar si alguien lo tiene ps me hace el favor de pasarmelo. aqui les dejo mi correo: [email protected] gracias# October 6, 2011 3:25 AM

Edna said:estos son los using q hay q importar using System.Collections.Generic; using System.Text; using iTextSharp.text; using iTextSharp.text.pdf; using System.IO; using System.Diagnostics; using iTextSharp.text.xml; using iTextSharp.text.html; using System.Collections; using System.Data; tengo una duda me sale un error en http agradezco su ayuda# October 11, 2011 12:58 PM

Joha said:me sale error en otros formatos me dice que la directiva o el using no existe que falta el using o la referencia de ensamblado al usar el codigo para word....que hago?? y esta mal escrito el @//test.doc ????# October 26, 2011 12:23 PM

Leave a Comment