Documente Academic
Documente Profesional
Documente Cultură
NET Página 1 de 13
Buscar
Web www.elguille.info
Cómo... en .NET
Publicado el 03/Feb/2009
Actualizado el 03/Feb/2009
Autor: Guillermo 'guille' Som
Ejemplos prácticos de cómo imprimir con Visual Basic .NET (y con un pequeño esfuerzo, cómo hacerlo también en C#)
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 2 de 13
Este mismo artículo lo autoricé para su publicación exclusiva en la revista electrónica de Ineta Latam, lo
nadie venga después diciendo algo así como "Guille, esto mismo lo he visto publicado en tal revista en fo
Otra cosa que quiero aclarar es que esto lo escribí en Enero de 2005 (o incluso antes), por tanto, la vers
Basic .NET usada para los ejemplos y esas cosas, es la conocida como 2003, esto lo digo por si ahora ha
más fáciles de imprimir, que puede que las haya, pero que este que escribe ni lo ha comprobado, m
como no me dedico a hacer programas y los que hago son para mi uso particular y esos no necesitan im
pues... en fin...
Ya no me enrollo más, aquí tienes el artículo: Imprimir con Visual Basic .NET
Introducción
Muchos de los usuarios de Visual Basic 6 que han migrado a .NET han sufrido (incluso están sufriendo) la
este "nuevo" entorno de programación de un objeto que les permita imprimir de forma tan fácil como lo
Printer o de una colección que les permita saber las impresoras disponibles en el sistema. En este art
cómo imprimir en .NET y comprobaremos que aunque parezca complicado, a la larga, imprimir en .NET e
fácil que con VB6, aunque tratándose de un lenguaje orientado a objetos, debemos cambiar un poco el c
Nota:
Actualmente el equipo de desarrollo de Visual Basic está sacando una serie de paquetes de ayuda a
programador llamados genéricamente Visual Basic 2005 Power Packs, entre ellos está uno para fac
impresión: PrintForm component, el cual se puede descargar desde esta dirección:
http://msdn2.microsoft.com/en-us/vbasic/aa701261.aspx.
Los precedentes
Lo primero que debemos tener en cuenta es que todo lo que queramos hacer en .NET debemos hacerlo u
que este entorno nos ofrece y el tema de imprimir no es una excepción. En Visual Basic 6 solamente disp
objeto Printer, que era el que realmente nos permitía imprimir, de la colección Printers, la cual pod
las impresoras que teníamos disponibles, además del control para diálogos comunes, el cual nos permit
configurar la impresora que queríamos usar, además de permitirnos indicar el número de páginas a impr
aunque no siempre funcionara como a nosotros nos hubiera gustado y en ocasiones tuviésemos que acu
funciones del API de Windows si realmente queríamos hacer algo verdaderamente práctico. En .NET ha c
poco la forma de hacer todo lo que hacíamos en VB6, ya no existen "objetos" que nos permitan imprimir
que nos permitan saber las impresoras disponibles, bueno, un poco sí, pero como veremos de una forma
y algo diferente. Esa diferencia es la que a muchos les ha causado desesperación e incluso les ha llevado
excesivo de Aspirinas. En los siguientes puntos veremos que nuestra vida puede ser más soportable e in
aprendemos a manejar las clases de .NET que nos permiten imprimir y configurar las opciones de impres
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 3 de 13
clase PrintDocument lo que realmente hace es "despertar a la bestia", es decir, dar las instrucciones pert
de .NET para que se inicie el proceso de impresión, dicho proceso se lleva a cabo básicamente
PrintPage de la clase PrintDocument, en este evento es donde tendremos que hacer todo lo necesario pa
imprima lo que queramos imprimir. Por tanto, para poder controlar lo que se va a imprimir, debemos
nuestro código en ese evento, el cual se produce para cada página que deba imprimirse; posiblemente e
problemático, al menos desde el punto de vista del programador de VB6, ya que antes para controlar lo
imprimirse simplemente usábamos el método Print del objeto Printer, (o de cualquier objeto del tipo Prin
hubiésemos obtenido de la colección Printers), al que le indicábamos qué es lo que debía imprimirse, aun
éramos nosotros los que debíamos comprobar cuando cambiar de página, cuando imprimir la cabecera, e
esto se hace en un solo sitio: el evento PrintPage, por tanto podemos decir que en .NET es má
todo controlar cómo y dónde se imprime cada cosa, ya que, si lo simplificamos al máximo, todo se hace
el evento PrintPage de la clase PrintDocument.
En el listado 1 podemos ver un ejemplo de la forma más simple de imprimir en .NET, en este ejemplo mo
cadena "Hola, Mundo" en la parte superior de la página usando una fuente Arial de 24 puntos en negrita.
End Sub
End Sub
Primero tenemos el código usado para dar la orden de imprimir, (este código puede estar en el eve
botón), en el que creamos un nuevo objeto del tipo PrintDocument al que asignamos el procedimien
usar cuando se vaya a imprimir cada página, cosa que ocurrirá después de llamar al método Print d
En el evento PrintPage le indicamos a .NET que es lo que queremos imprimir, en nuestro caso s
Mundo", para imprimir dicho texto utilizamos el método DrawString del objeto Graphics, (una propi
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 4 de 13
Esta simpleza es en parte porque tampoco hacemos demasiadas cosas en el código del evento PrintPage
mostramos algunas de las cosas necesarias, como por ejemplo indicar el tipo de fuente a usar para la im
se puede cambiar en cada una de las líneas a imprimir (e incluso en distintas partes de esa línea), ya qu
"dibuja" por medio del método DrawString del objeto Graphics obtenido del segundo parámetro pasado a
Como vemos en DrawString debemos indicarle que es lo que queremos imprimir, con qué tipo de fuente
posición. Por último indicaremos si quedan más páginas a imprimir, esto lo haremos asignado un valor v
a la propiedad HasMorePages del objeto recibido como segundo parámetro del evento, si el valor asignad
estaremos indicando que queremos seguir imprimiendo, por el contrario, asignando un valor False termin
impresión, cosa que también ocurrirá si no le asignamos expresamente nada a esa propiedad.
Configurar la impresión
Pero para ser claros esta no será la forma "habitual" de usar este evento, ya que en la mayorí
imprimiremos más de una página y seguramente querremos asignar otros valores a la impresora, como
número de copias, el tamaño del papel, la orientación de la impresión (vertical o apaisada) e incluso, lo m
qué impresora usar. Todos estos valores los podremos indicar usando un objeto del tipo PrinterSettings,
otras cosas, nos permite saber cuáles son las impresoras que tenemos disponibles en el equipo actual. P
habitual será que usemos un objeto de esta clase en conjunto con el de la clase principal para imprimir:
Otra de las tareas que seguramente nos veremos en la necesidad de ofrecer a los usuarios de nuestras a
que puedan seleccionar de una manera fácil qué impresora usar y darles la posibilidad de que ajusten su
de impresión. Todo esto lo podríamos hacer manualmente creando un formulario que utilice un objeto de
PrinterSettings y que le ofrezca a los usuarios las opciones que creamos conveniente, pero para que todo
más homogéneo y no tengamos que reinventar la rueda, podemos hacer que toda esta configuraci
impresora a usar la ofrezcamos mediante los mismos cuadros de diálogo que utiliza el resto de aplicacion
basan en los cuadros de diálogos comunes del sistema operativo, si esta es nuestra elección, nos
podemos usar la clase PrintDialog. Con un objeto de esta clase, tal como hemos comentado, podemos m
cuadro de diálogo que utilizan el resto de aplicaciones de Windows, con la ventaja añadida de que
las opciones que se mostrarán, de forma que lo configuremos para que se adapte, en la medida de lo po
preferencias de nuestra aplicación.
En breve veremos cuáles son las opciones que podemos usar para ajustar este cuadro de diálogo a nues
o a la de nuestra aplicación.
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 5 de 13
La clase PrintDocument
Esta es la clase elemental o principal si queremos imprimir en .NET, como hemos comentado anteriorme
miembros que esta clase ofrece principalmente usaremos tres:
El método Print es el que iniciará el proceso de impresión, haciendo que se produzcan los eventos n
controlar lo que queremos imprimir.
El evento PrintPage, el cual se producirá cada vez que tengamos que imprimir una página. Dentro d
donde haremos todo lo que tengamos que hacer para imprimir cada una de las páginas, desde aqu
controlar si quedan más páginas por imprimir, etc.
La propiedad PrinterSettings a la que podemos asignarle un objeto del mismo nombre en el que ind
impresora a usar y otros valores como el rango de página, el número de copias, el tamañ
etc.
Del resto de miembros de esta clase podemos destacar la propiedad DocumentName a la que podemos a
nombre del documento que estamos imprimiendo y que será el que se muestre en el estado de la impres
tenemos el evento QueryPageSettings el cual se produce justo antes del evento PrintPage y que nos perm
valores "particulares" a cada una de las páginas a imprimir antes de que se produzca el evento PrintPage
La clase PrinterSettings
Tal y como hemos estado indicando en los párrafos anteriores, esta clase nos permite especificar caracte
impresión como la impresora a usar, el número de copias a imprimir, el rango de páginas, etc. Realment
necesitamos indicar nada, al menos de forma explícita para usar un objeto de esta clase, ya que al crear
instancia los valores predeterminados serán los que tengamos asignado en la impresora, valga la redund
predeterminada de nuestro sistema. Pero si queremos modificar esos valores, tendremos que asignarlos
propiedades de esta clase, entre las que podemos destacar las siguientes:
Tanto MaximunPage como MinimunPage se utilizarán para indicar los valores máximo y mínimo de las p
disponibles y se usarán con una clase del tipo PrintDialog.
InstalledPrinters es una propiedad compartida y por tanto podemos usarla sin necesidad de crear u
la clase PrinterSettings, esta colección devuelve un array de tipo String con el nombre de cada una
impresoras instaladas en el sistema.
PaperSizes es una colección con elementos del tipo PaperSize que nos permite saber los tama
impresora soporta. Cada elemento del tipo PaperSize nos proporciona información sobre el tama
el nombre y la "clase" de papel, que no es ni más que una enumeración del tipo PaperKind.
PrinterResolutions es una colección con elementos del tipo PrinterResolution, de forma que podamo
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 6 de 13
resoluciones (y calidades) permitidas por la impresora. Cada uno de estos elementos nos
resolución horizontal como la vertical, además de la calidad de impresión, especificada con uno de l
enumeración PrinterResolutionKind, cuyos valores pueden ser: Custom, Draft, High, Low y
CreateMeasurementGraphics el cual nos permite conseguir un objeto del tipo Graphics con el cual p
averiguar ciertas características de la impresora sin necesidad de tener que imprimir, ya que el obje
este método es igual al que se incluye en la clase PrintPageEventArgs, usada como segundo
eventos producidos por la clase PrintDocument.
Como regla general deberíamos tener una variable del tipo PrinterSettings para usarla como almacenam
preferencias de impresión de nuestros usuarios, ya que esta clase se utiliza tanto con PrintDocument com
PrintDialog.
La clase PrintDialog
Esta clase nos servirá para que nuestros usuarios seleccionen la impresora a usar así como para que ind
características relacionadas con la impresión, como la calidad del papel, el número de copias, etc., con la
todo esto lo haremos usando el mismo cuadro de diálogo común incluido en Windows y que es el que la
totalidad de aplicaciones de este sistema operativo utilizarán, tal como podemos comprobar en la figura
En la figura 1 podemos comprobar que hay ciertos elementos que puede que no nos interese mostrar o d
por ejemplo, si nuestra aplicación no permite imprimir el código seleccionado no tiene mucho significado
opción "Selección", (la figura está capturada de un Windows XP en inglés, por eso se muestran las opcion
mismo ocurre con el botón de ayuda o con las cajas de texto que permiten indicar el rango de p
estas características las podemos habilitar o deshabilitar mediante algunas de las propiedades de la clase
tales como: AllowPrintToFile, AllowSelection, AllowSomePages, PrintToFile, ShowHelp y ShowNetwork.
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 7 de 13
La ayuda del cuadro de diálogo de imprimir
Como curiosidad, decir que la propiedad ShowHelp nos permite indicar si se debe mostrar o no el b
ayuda, (no la interrogación de la barra de títulos que siempre estará funcional), pero entre las prop
de esta clase no tenemos ninguna a la que indicarle que ayuda se debe mostrar si pulsamos en ese
lugar de eso, de lo que disponemos es de un evento: HelpRequest el cual se producirá cuando el us
pulse en dicho botón, por tanto si queremos mostrar algún tipo de ayuda, tendremos que usar ese
para mostrar la información que creamos conveniente para nuestro cuadro de diálogo.
Al igual que en el resto de cuadros de diálogos de .NET, tenemos el método ShowDialog que ser
mostrar el cuadro de diálogo y saber si el usuario ha pulsado en el botón OK (Aceptar) o Cancelar, para
forma sepamos si debemos seguir con el proceso de impresión o no.
La propiedad PrinterSettings será la que nos permita saber lo que el usuario ha seleccionado, adem
usemos para asignar los valores predeterminados o bien los que tengamos almacenado de ocasiones ant
como indicamos anteriormente, lo habitual será que tengamos una variable del tipo de esta propiedad co
preferencias del usuario, por tanto antes de llamar al método ShowDialog deberíamos asignar a esta pro
variable que tengamos con las preferencias del usuario y si no se ha cancelado, debemos asignar nuevam
resultado de dichas preferencias, tal como mostramos en el listado 2.
''' <summary>
''' Seleccionar la impresora.
''' </summary>
''' <returns>
''' Devuelve True si todo fue bien o false si se canceló
''' </returns>
Private Function seleccionarImpresora() As Boolean
Dim prtDialog As New PrintDialog
If prtSettings Is Nothing Then
prtSettings = New PrinterSettings
End If
With prtDialog
.AllowPrintToFile = False
.AllowSelection = False
.AllowSomePages = False
.PrintToFile = False
.ShowHelp = False
.ShowNetwork = True
.PrinterSettings = prtSettings
End With
Return True
End Function
Listado 2.
La clase PrintPreviewDialog
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 8 de 13
Esta clase nos permitirá mostrar una ventana con la vista preliminar del documento que queremos impri
que los usuarios de nuestra aplicación pueden ver lo que se imprimirá. Debido a que esta clase al estar d
tiene todas las propiedades, métodos y eventos de cualquier formulario además de los relacionados con
previsualización del documento a imprimir, veamos solamente los dos miembros que nos interesar
El método ShowDialog será el que se encargue de mostrar el formulario con la vista preliminar.
A la propiedad Document le asignaremos un objeto del tipo PrintDocument que será el que utilicem
qué es lo que queremos imprimir.
NOTA:
Por regla general deberíamos asignar a la propiedad Document de la clase PrintPreviewDialog el mi
objeto PrintDocument usado para imprimir, ya que la clase PrintPreviewDialog se encargar
produzcan los mismos eventos que si hubiésemos llamado al método Print del objeto PrintDocumen
asignado, de forma que lo que se muestre mediante este diálogo sea lo mismo que se imprima, qu
y al cabo lo que queremos conseguir.
Tal como hemos resaltado en la nota, tanto el método Print de la clase PrintDocument como la clase Prin
utilizan los mismos eventos del objeto PrintDocument, por tanto podríamos usar un método gen
encargado de mostrar una vista preliminar de lo que queremos imprimir o de mandarlo a la impresora, d
podemos usar de forma común las opciones ofrecidas al usuario, como por ejemplo permitir la selecci
antes de imprimir, etc.
En el listado 3 podemos ver cómo podría ser ese método genérico para elegir entre imprimir o previsuali
deseamos imprimir.
If chkSelAntes.Checked Then
If seleccionarImpresora() = False Then Return
End If
If esPreview Then
Dim prtPrev As New PrintPreviewDialog
prtPrev.Document = prtDoc
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 9 de 13
Listado 3.
Tal como podemos ver en la figura 2, el formulario (o cuadro de diálogo) de previsualización nos permite
número de página a mostrar, si queremos ver una o más páginas a un mismo tiempo, el porcentaje de a
incluso imprimir lo que estamos viendo, todos estas características ya están incluidas en ese formulario.
La clase PrintPreviewControl
Si nuestra intención es crear nuestro propio formulario de previsualización, también podemos hacerlo si
control PrintPreviewControl que es el que la clase PrintPreviewDialog utiliza, si bien todos los botones y o
tendremos que crearlos nosotros, para ello podemos usar los miembros específicos de este control, tales
AutoZoom lo usaremos para que al cambiar el tamaño del control se cambie también la p
Columns indica el número de páginas a mostrar cuando se elija la orientación horizontal (apaisada)
Document es donde asignaremos el objeto PrintDocument a imprimir.
Rows indica el número de páginas a mostrar cuando elijamos la orientación vertical.
Zoom para indicar la ampliación con la que queremos mostrar los documentos.
StartPageChanged en un evento que se producirá cada vez que cambiemos la página de inicio (este
servirá para crear un equivalente al NumericDropDown usado en la clase PrintPreviewDialog).
Si también quisiéramos implementar un botón para imprimir, tendremos que manejar nosotros mismos l
pero realmente resultaría fácil, ya que lo único que tendríamos que hacer es llamar al método Print del o
PrintDocument asignado a la propiedad Document.
Como siempre la última palabra la tendremos nosotros y dependiendo de lo que queramos hacer usarem
otra.
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 10 de 13
Tal como hemos podido comprobar, imprimir en .NET no es tan complicado como en un principio pudiera
además de que tenemos valores añadidos que nos permiten un mayor control sobre la impresi
las opciones que podemos ofrecer a los usuarios de nuestras aplicaciones, ya que como hemos visto, hac
presentación preliminar, que en otros lenguajes nos obligaría a escribir bastante código, es tan sencillo c
nuevo objeto en la memoria y asignar un par de propiedades.
Por supuesto, lo que no es totalmente sencillo ni automático es la presentación o impresión de los datos
mostrar, al menos si queremos darle un toque, digamos, profesional a nuestra impresión, ya que
que debamos "afinar" en la forma de mostrar esos resultados; pero de todas formas eso es algo que siem
hacer, utilicemos el entorno de programación que utilicemos, la ventaja de usar lo que .NET nos ofrece e
ciertas posibilidades de hacerlo de una forma más o menos fácil y que de alguna forma nos facilita basta
aunque para la mayoría de situaciones será más que suficiente e incluso podemos automatizar,
podemos aprovechar las posibilidades que nos da la programación orientada a objetos de crear nuestras
implementar métodos de impresión que se adapten a los datos que tengamos que mostrar, ya que
la POO es la abstracción y que mejor forma de abstracción que crear un método que se encargue de man
que la propia clase mantiene y que "sepa" cómo mostrar esos datos e incluso qué formato deben
presentar esos datos por la impresora. Posiblemente tengamos que quemar unas cuantas neuronas m
"concebir" esa clase, pero a la larga ese esfuerzo habrá valido la pena ya que puede suponernos una
"olvidarnos" de esos pequeños detalles de ajustar cada una de las líneas que vamos a imprimir.
De seguro que el lector puede pensar que tampoco es necesario ese "esfuerzo" extra para imprimir una
seguramente tenga razón, pero precisamente si cuando diseñamos nuestras clases para manejar datos t
cuenta estos detalles, seguramente nos resultará más fácil realizar cambios en ocasiones futuras. Por eje
tenemos una clase en la que hay datos de cadena y de tipo numérico y queremos mostrar esos datos, la
cada uno de esos datos será diferente, ya que con toda seguridad los datos numéricos querremos
y los de cadena a la izquierda, además de que si debemos recortar la información que tenemos que mos
seguridad preferiremos "truncar" los datos de cadena antes que los numéricos. En este tipo de situacione
que el código de la clase sea el que decida estos truncamientos, (realmente el código de la clase no va a
que tendremos que ser nosotros los que hagamos esa decisión), siempre será preferible que tener que h
propio evento de impresión, sobre todo si ese mismo evento es el que usaremos para imprimir datos de
que pueden proceder de diferentes clases, pero si las clases usadas para contener los datos est
imprimir el contenido de cada línea, entonces resultará tan sencillo como llamar a un método de cada un
clases...
En el listado 4 podemos ver cómo quedaría el evento PrintPage si hiciéramos algo de lo que acabamos de
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 11 de 13
Listado 4.
En el código completo que acompaña a este artículo, hay un proyecto en el que he definido una interfaz c
métodos, una colección para almacenar objetos del tipo de la interfaz, una clase abstracta que define los
usados en el evento mostrado en el Listado 4, tres clases diferentes para ver cómo poder usar tanto la c
como la interfaz, dos de ellas se basan en la clase abstracta (por tanto parte del código ya estar
simplemente implementa la interfaz y define los cuatro métodos; también incluyo un formulario el cual p
de forma genérica con cualquiera de esas tres clases o de cualquier otra que utilice la interfaz o la clase
esta forma podrás comprobar que no todo son "palabras".
Lo vamos a dejar aquí, porque aunque sería interesante explicar todo el código con más detalle, eso me
montón de horas y no es plan de abusar ;-)))
De todas formas, confío que con lo aquí explicado más el código incluido en el ZIP sea más que suficiente
comprender cómo podemos imprimir en .NET Framework con Visual Basic para .NET.
¡Feliz impresión!
Nos vemos.
Guillermo
Contiene tres proyectos, para usar con Visual Basic 2008 aunque el código usado en cada formulario y ca
válido para cualquier versión de Visual Basic .NET.
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 12 de 13
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009
Imprimir con Visual Basic .NET Página 13 de 13
Mentor de
Orador de Ineta L
http://www.elguille.info/net/dotnet/imprimir_visual_basic_net.aspx 06/09/2009