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參考:
數據流多次讀取的方法:
(1)重復利用數據流來源
(2)通過mark和reset的方法
