19 diciembre 2008

Generando un informe de Microsoft Word

Aunque hay muchos generadores de informes para Delphi como pueden ser QuickReport, Rave Reports, Report Manager, etc., no hay procesador de textos más completo que Microsoft Word.

Es este artículo vamos a ver como generar un nuevo documento de Word y poder introducir textos, tablas, figuras, notas al pie, etc. Esto lo vamos a conseguir utilizando el componente TWordApplication que encuentra en el apartado Servers dentro de la paleta de componentes.

Aunque no he conseguido averiguar la inmensidad de funciones que incorpora este objeto sí que podemos generar un informe más o menos decente.

EL COMPONENTE TWORDAPPLICATION

Insertamos el componente en nuestro formulario y lo llamamos Word para abreviar:


Este es el documento que vamos a generar:


Creamos un par de variables del tipo OleVariant para poder enviar parámetros a funciones:

var
Documento, Texto: OleVariant;

Conectamos con Microsoft Word y le decimos que cree un nuevo documento que va a llamarse Informe.doc y que va a guardarse en el mismo directorio donde nos encontramos:

// Conectamos con Word y creamos un nuevo documento
Documento := ExtractFilePath( Application.ExeName ) + 'Informe.doc';
Word.Connect;
Word.Documents.Add(EmptyParam,EmptyParam,EmptyParam,EmptyParam);

Entramos al encabezado del documento y escribimos el título centrado:

with Word do
begin
with Selection do
begin
// Insertamos un título en el encabezado del documento
with Sections.Item(1).Headers.Item(1).Range do
begin
Font.Name := 'Courier New';
Font.Bold := 1;
Text := 'TITULO DEL DOCUMENTO';
Paragraphs.Item(1).Alignment := 1; // centramos párrafo
end;

La propiedad Selection contempla el punto donde se encuentra el cursor al principio de la página.

Dentro del documento escribimos tres frases de un color distinto:

// Establecemos la fuente Tahoma, negrita, azul y tamaño 10
Font.Name := 'Tahoma';
Font.Size := 10;
Font.Color := clNavy;
Font.Bold := 1;
TypeText( 'Frase 1' + #13 );
Font.Color := clRed;
TypeText( 'Frase 2' + #13 );
Font.Color := clGreen;
TypeText( 'Frase 3' + #13 + #13 + #13 );

También vamos a insertar una nota al pie de página y otra al final del documento:

// Insertamos una nota al pie y una nota al final
Texto := 'Nota al pie de página';
FootNotes.Add( Range, EmptyParam, Texto );
Texto := 'Nota al final';
EndNotes.Add( Range, EmptyParam, Texto );

Además insertamos una tabla configurando todas las celdas:

// Insertamos una tabla con fuente de color negro
Font.Color := clBlack;
with Tables.Add( Range, 3, 4, EmptyParam, EmptyParam ) do
begin
// Títulos de la tabla
Cell(1,1).Range.Text := 'Unidades';
Cell(1,2).Range.Text := 'Artículo';
Cell(1,3).Range.Text := 'Precio';
Cell(1,4).Range.Text := 'Total';
Rows.Item(1).Shading.BackgroundPatternColor := clGreen; // fonfo verde
Rows.Item(1).Range.Font.Color := clYellow; // fuente amarilla

// Contenido
Cell(2,1).Range.Text := '1';
Cell(2,2).Range.Text := 'PORTATIL ACER';
Cell(2,3).Range.Text := '540';
Cell(2,4).Range.Text := '540';
Cell(3,1).Range.Text := '2';
Cell(3,2).Range.Text := 'RATON OPTICO';
Cell(3,3).Range.Text := '2,50';
Cell(3,4).Range.Text := '5';
Columns.Item(4).Shading.BackgroundPatternColor := clBlue; // fondo azul
end;
end;
end;

Para crear una nueva tabla hemos llamado a:

Tables.Add( Range, 3, 4, EmptyParam, EmptyParam )

El segundo parámetro determina el número de filas y el tercero el número de columnas.

Aparte de añadir el contenido a cada celda hemos establecido para toda la primera fila el fondo de color verde y la fuente de color amarillo:

Rows.Item(1).Shading.BackgroundPatternColor := clGreen; // fonfo verde
Rows.Item(1).Range.Font.Color := clYellow; // fuente amarilla

Igualmente le hemos dicho a la cuarta columna que el color de fondo es azul:

Columns.Item(4).Shading.BackgroundPatternColor := clBlue; // fondo azul

Aun así, si queremos ser más específicos podemos hacerlo para cada celda (Cells).

Por último he añadido una línea recta cuyas coordenadas van por pixels:

Word.ActiveDocument.Shapes.AddLine( 200, 200, 250, 250, EmptyParam );

Una vez hemos finalizado el documento lo guardamos y desconectamos de Word:

Word.ActiveDocument.SaveAs( Documento,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam );
Word.Quit;
Word.Disconnect;

Aunque me hubiera gustado poder añadir muchos más elementos a este informe, debido a la pésima documentación de Delphi 2007 y que en la web tampoco abundan muchos ejemplos (lo único decente que he visto es de unas páginas rusas y japonesas). Si averiguo más cosas lo ampliaré en un futuro.

Pruebas realizadas en RAD Studio 2007.

7 comentarios:

Alejandro dijo...

muy buen articulo y coincido con que la documentacion de delphi 2007 apesta.
Saludos

Enrique Gabriel dijo...

Muy buen artículo. La verdad es que teniendo Word se pueden realizar informes muchos mas cmplejos que lo que permite un reporteador estandar.
Saludos,

Mariano Rocha dijo...

Hola amigo me encanta tu forma de explicar los temas de delphi, he visto que tienes varios temas sobre informes, me gustaria que crearas un tema de como crear informes con QuickReport, es el unico que no e visto muchas gracias

Administrador dijo...

Pues ya que me has dado la idea esta semana voy a comenzar con QuickReport.

Saludos.

Francisco Fernandez dijo...

Hola, excelente artículo, muy trabajado y muy bien explicado. Lo único es que echo en falta no poder introducir las coordenadas de donde se quiere introducir el texto dentro del documento, ¿sabes si es posible?.

Gracias y un saludo

Administrador dijo...

Manipulando los objetos Active X de Word se puede hacer de todo, pero hay que conocer bien sus propiedades.

Para lo que tu quieres hacer tienes que investigar sobre el objeto Range que es como una capa encima del documento que puede contener de todo.
Tienes que averiguar como recolocar dicho Range.

Saludos.

thejhorse dijo...

Buen articulo me sirvio de mucho, personalmente trabajo con Delphi7, y para trabajarlo tube que realizar la siguiente modificacion: "Word.Application.Selection" en ves de: "Word.Selection".

Por otra parte queria preguntar como se podria realizar una busqueda y reemplazo de palabras.

Publicidad