miércoles, 27 de junio de 2012

Java: Utilizar la Impresora en Java


Durante mucho tiempo he programado en Java sin saber como realizar una impresión a través de la impresora, esto puede ser muy importante si se desea realizar un sistema de facturación, calculo de remuneraciones, ticket o comprobantes de algún tipo.

Ahora voy a describir algunos pasos que encontré y me han permitido realizar impresiones desde Java.

Lo primero que se debe crear es una clase donde se ingrese toda la información que se desea imprimir, para esto creamos el archivo ObjetoDeImpresion.java que implementa la interfaz de java Printable, como se puede ver en el siguiente ejemplo.

import java.awt.*;
import java.awt.print.*;
class ObjetoDeImpresion implements Printable{
public int print(Graphics g, PageFormat f, int pageIndex){
if(pageIndex == 0){
g.drawString(“texto que se imprime”, 100, 200);
return PAGE_EXISTS;
}else{
return NO_SUCH_PAGE;
}
}
}

Con la clase anterior se dibuja la cadena “texto que se imprime” en las coordenadas 100 pixeles a lo ancho y 200 pixeles a lo alto, estas coordenadas se consideran desde la parte superior izquierda de la hoja y van aumentando hacia la derecha en el caso de la primera coordenada (100) y hacia abajo en el caso de la segunda coordenada (200).

Si deseas imprimir más líneas solo tienes que agregar más texto utilizando la sentencia g.drawString(“mas texto”, coordenada_x, coordenada_y), con esto puedes dibujar todos los textos que se desee imprimir.

Debo aclarar que hasta este punto no se ha enviado ningún documento a la impresora, para esto se debe crear la siguiente clase, en el archivo Imprimir.java.

import java.io.*;
import java.awt.print.*;
import java.awt.print.PrinterJob.*;
import java.awt.print.PageFormat.*;
class Imprimir{
static public void main(String []args){
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new ObjetoDeImpresion());
if(job.printDialog()){
try{
job.print();
}catch(PrinterException e){
System.out.println(e);
}
}
}
}

La clase Imprimir es la encargada de enviar el texto a la impresora, para entender un poco mejor el funcionamiento de esta clase explicare lo que hacen algunas de estas líneas.

Para comenzar se debe aclarar que la clase Imprimir es una clase ejecutable por eso tiene el método main que permite comenzar a ejecutar todo el programa.

El primer paso es crear un objeto PrinterJob el cual nos permitirá manipular la interfaz de la impresora que nos proporciona el sistema operativo que se esta utilizando, es importante mencionar que la creación de este objeto no se realiza con la sentencia new PrinterJob(), como la mayoría de las instancias de objetos, sino con la sentencia PrinterJob.getPrinterJob().

Una vez que se tiene instanciado el objeto que permite manipular la interfaz de la impresora, se le debe asignar al objeto la instancia de la clase que se desea imprimir, en este caso la clase ObjetoDeImpresion utilizando la sentencia Job.setPrintable(new ObjetoDeImpresion()).

El siguiente paso es opcional y permite desplegar la interfaz que proporciona el sistema operativo para la impresora con ella se puede selección la impresora, seleccionar la hoja y los margenes, esta sentencia también recibe la respuesta que el usuario selecciona en la interfaz, indicando si se debe realizar la impresión o se cancela, para esto se utiliza la sentencia job.printDialog().

Por último esta la sentencia job.print() que realiza la impresión del documento, esta sentencia puede ser utilizada sin utilizar el dialogo de la impresora descrita en el segmento anterior, en este caso la impresión se realiza en la impresora por defecto, con los margenes y las propiedades que la impresora tiene por defecto.

Con la información que he descrito se puede realizar la impresión de cualquier documento que se genere a través de un programa realizado en Java.

A pesar que con la información anterior se puede imprimir el documento, existen ocasiones donde se desea controlar algunas propiedades de la impresión, sobre todo sino se desea desplegar la ventana de propiedades de la impresora, para revisar esta información se presenta el siguiente código.

import java.io.*;
import java.awt.print.*;
import java.awt.print.PrinterJob;
import java.awt.print.PageFormat;
class Imprimir{
static public void main(String []args){
PrinterJob job = PrinterJob.getPrinterJob();
PageFormat pf = job.defaultPage();
Paper paper = new Paper();
paper.setSize(612.0,832.0);
double margin = 10;
paper.setImageableArea(margin, margin, paper.getWidth() – margin, paper.getHeight() – margin);
pf.setPaper(paper);
pf.setOrientation(PageFormat.LANDSCAPE);
job.setPrintable(new ObjetoDeImpresion(), pf);
job.setJobName(“nombre_de_impresion”);
try{
job.print();
}catch(PrinterException e){
System.out.println(e);
}
}
}

La primera sentencia nueva que aparece es PageFormat pf = job.defaultPage() que permite crear un objeto del tipo PageFormat el cual permitirá ingresar algunas de las propiedades de la impresión.

Luego se debe crear el objeto paper utilizando la sentencia Paper paper = new Paper(), esto permite asignar el tamaño de la hoja y el margen.

Después se define el tamaño de la hoja utilizando la sentencia paper.setSize(612.0,832.0) donde 612.0 representa el ancho de la hoja y 832.0 indica el alto de la hoja.

El siguiente paso es definir el tamaño de margen, para esto se utiliza la sentencia double margin = 10, con este valor se puede definir los margenes del documento de impresión utilizando la sentencia paper.setImageableArea(margin, margin, paper.getWidth() - margin, paper.getHeight() - margin), donde el primer margen representa la coordenada x, el segundo margen representa la coordenada y, luego se debe indicar el ancho desde la coordenada x y por último se indica el alto del documento desde la coordenada y.

Ahora que se han establecido los valores de la pagina se debe asignar los valores al objeto PageFormat utilizando la sentencia pf.setPaper(paper).

También es necesario definir la orientación de la impresión, para esto se utiliza la sentencia pf.setOrientation(PageFormat.LANDSCAPE) que permite una orientación horizontal. Los otros valores que existen para la orientación de la página son PORTRAIT que realiza una orientación vertical de la hoja y REVERSE_LANDSCAPE que orienta la hoja de modo horizontal invertido.

La sentencia siguiente permite asignar el objeto que se desea imprimir y el formato de la hoja que se desea imprimir utilizando la siguiente línea de código job.setPrintable(new ObjetoDeImpresion(), pf).

Finalmente se puede asignar el nombre a la impresión a través del código job.setJobName(“nombre_de_impresion”).

Referencias:
"Gracias, por compartir tus conocimientos"

13 comentarios:

  1. Hola, tengo el siguente problema las medidas de mi factura son 21,00cm de ancho por 15,28 de alto, margenes son 0,00cm la impresora que tengo es una Epson Lx-300, no puedo hacer que Java imprima correctamente, al darle estas medidas en el servidor de impresion de windows xp, al imprimir me reduce el area imprimible a 12cm de ancho y 13cm de alto. ¿Cual seria el problema?, el driver, la hoja personalizada o Java.

    ResponderEliminar
    Respuestas
    1. Estimado Miguel. Tal vez deberías revisar si la impresora tiene algún margen predeterminado para realizar la impresión. Existen algunas impresoras que vienen configuradas para generar un margen de manera automáticas.

      Eliminar
  2. Hola Juan Pablo, agradezco mucho este articulo, me resulta realmente útil, y después de hecharle un vistazo a tu código me parece no solo útil sino practico, la gente en la red tiene la tendencia a colocar códigos que se adaptan a sus necesidades, es un tanto molesto tener que estar revisando tantos programas cuando lo verdaderamente práctico es que indiquen como funciona correctamente la interfaz y luego que te apañes como puedas. Rara vez suelo comentar en internet, pero ya que esto lo estaba buscando hace días y me has dado una buena idéa, no puedo evitar darte las gracias. ;)

    ResponderEliminar
    Respuestas
    1. Muchas gracias DOSunix por tu comentario. Es una alegría saber que a alguien le sirven los post que escribo.

      Eliminar
    2. mare bosh... limosnero y con garrote. pagate unos cursos de java y listo. En mi opinion agradezco todos los sitios donde encuentro informacion que necesito por que al cabo todos son un "grano de arena" que me dan mas conocimento. sorry.

      Eliminar
  3. Excelente Articulo.
    Tengo un código parecido. Imprimo 1 hoja sin ningún problema pero ¿como lo hago para imprimir múltiples hojas de una sola vez?. Estoy creando un sistema de facturación y necesito imprimir las guías de despacho que están en papel continuo por lo tanto debo imprimir al rededor de 50 hojas de una sola vez. Ojala me puedas ayudar. Gracias

    ResponderEliminar
  4. Excelente el articulo...
    Quisiera saber como imprimir un frame, no simple lineas de codigo mediante un g.drawString... se lo agradeceria ya que es para implementarlo en un proyecto final... GRACIAs

    ResponderEliminar
  5. No me queda mas que agradecerte Juan Pablo por este espectacular aporte, muy claro y sobre todo muy útil. Muchas gracias!

    ResponderEliminar
  6. hola como puedo imprimir un salto de linea??

    ResponderEliminar
  7. una consulta voy a implementar un sistema de farmacia y ellos van a utilizar una impresora de ticket factura, ¿con esta clase o libreria se puede programar para que imprima el ticket factura o dependo de los driver que pueda tener la impresora o cómo lo podría configurar?

    ResponderEliminar
  8. Amigo muchas gracias estoy haciendo un sistema de ventas con impresion de ticket y no tenia la menor idea de como imprimir ahora ya lo tengo todo listo...gracias por tu aporte te pasaste

    ResponderEliminar
  9. y si quiero que lo que se imprima sean textos capturados de unos jTextField?

    ResponderEliminar