java打印程序——打印图片(不带对话框)

java打印程序——打印图片(不带对话框)

可执行程序

  前提:将要使用的打印机设为默认打印机,或者利用打印机属性进行筛选而不用lookupDefaultPrintService()指令。

import javax.imageio.ImageIO;
import javax.print.*;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PrintQuality;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class PrintClass {
    public void printImg(String fileName, int count) {
        try {
        	//DocFlavor dof = DocFlavor.INPUT_STREAM.AUTOSENSE;
       	
            DocFlavor dof = null;
            if (fileName.endsWith(".gif")) {
                dof = DocFlavor.INPUT_STREAM.GIF;
            } else if (fileName.endsWith(".jpg")) {
                dof = DocFlavor.INPUT_STREAM.JPEG;
            } else if (fileName.endsWith(".png")) {
                dof = DocFlavor.INPUT_STREAM.PNG;
            }
            PrintService pservice  = PrintServiceLookup.lookupDefaultPrintService();
			
			//打印属性
            PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
            
            pras.add(OrientationRequested.PORTRAIT);
            pras.add(new Copies(count));
            pras.add(PrintQuality.HIGH);
            pras.add(Chromaticity.MONOCHROME);
            
			//文档属性
            DocAttributeSet das = new HashDocAttributeSet();
            FileInputStream fis = new FileInputStream(fileName);
             	// 设置打印纸张的大小(将像素转化为mm)
            das.add(new MediaPrintableArea(0, 0, 110, 148, MediaPrintableArea.MM));
           
            Doc doc = new SimpleDoc(fis, dof, das);

            DocPrintJob job = pservice.createPrintJob();
            job.print(doc, pras);

            fis.close();
                
        } catch (IOException ie) {
            ie.printStackTrace();
        } catch (PrintException pe) {
            pe.printStackTrace();
        }
    }
}

遇到的问题及解决方法

1.不论是电脑直接打印还是java打印程序均只能将打印文档加入打印列表中但是不执行打印。

  解决方法:重启电脑与打印机(可能是环境的问题)。

2.打印时java打印程序发送给打印机的文件在打印列表闪退而不执行打印。

  原因:文件流出了问题。分析及解决过程如下:

  原始代码(部分):

 PrintService pservice  = PrintServiceLookup.lookupDefaultPrintService();

 PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();          
 pras.add(OrientationRequested.PORTRAIT);
 pras.add(new Copies(count));
 pras.add(PrintQuality.HIGH);
 pras.add(Chromaticity.MONOCHROME);
            
 DocAttributeSet das = new HashDocAttributeSet();

 FileInputStream fis = new FileInputStream(fileName);               // (1)
 
 /////////////////////  (2) ///////////////////////   
 FileOutputStream fos = new FileOutputStream("E:\Software\3.jpg");

 byte[] b = new byte[1024];
 while((fis.read(b)) != -1){
  	fos.write(b);

 }
 fos.close();
 /////////////////////////////////////////////////
           
 //获取图像参数
 BufferedImage img = ImageIO.read(fis);	                           //  (3)				
 int width = (int) (img.getWidth() * 2.54f /72);
 int height = (int) (img.getHeight() * 2.54f /72);
 System.out.println("尺寸,宽:"+width+"高"+height);

 // 设置打印纸张的大小(将像素转化为mm)
 das.add(new MediaPrintableArea(0, 0, width, height, MediaPrintableArea.MM));
            
 Doc doc = new SimpleDoc(fis, dof, das);

 DocPrintJob job = pservice.createPrintJob();

 job.print(doc, pras);
 fis.close();

  分析:因为打印是文件大小仅1.22K,应该是文件流出了问题。

  假设一:文件输入流读取文件时出了问题。

  验证:添加代码段(2),运行后发现图片3.jpg存储正常,与原文件一样大小。故排除。

  假设二:既然文件输入流读取文件时没问题,那就是读入后出现了误操作,观看程序,出了(3)处用到了文件输入流,然后就只有打印处用到了文件输入流,故可能是(3)处出现了问题。

  验证:注释掉(3)处以及代码段(2)的代码,并修改后面的代码,将width与height设置为常数,发现打印正常。然后再将代码(3)放至(1)后面,解除代码段(2)的注释,执行发现不仅打印出问题,代码段(2)输出的图片3.jpg也出了问题。接着,将代码三放回原处,运行发现(3)处报错:"java.lang.NullPointerException"。由此可以看出,一个流数据只能读取一次,一旦读取后内部指针就会移到尾部,故源程序问题出在(3)上,(3)读取了文件输入流导致流数据内部指针移到了尾部无法再次读取,从而无法完成打印。

API参考:

  java实现打印功能的一些类

  Print Service (JDK 8)

数据流多次读取的方法:
  (1)重复利用数据流来源
  (2)通过mark和reset的方法

原文地址:https://www.cnblogs.com/silentteen/p/6555367.html