研究自:http://blog.csdn.net/u012345283/article/details/41011977java
這兩天在研究Java調用打印機打印PDF文件的方法,學到了很多東西,特別來記錄一下。web
關於Java打印網上最多的而且也是Java正統的打印方法就是使用PrintService,一套比較標準的打印代碼以下:.net
public class PrintDemo { public static void main(String[] args) { JFileChooser fileChooser = new JFileChooser(); // 建立打印做業 int state = fileChooser.showOpenDialog(null); if (state == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); // 獲取選擇的文件 // 構建打印請求屬性集 HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); // 設置打印格式,由於未肯定類型,因此選擇autosense DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE; // 查找全部的可用的打印服務 PrintService printService[] = PrintServiceLookup .lookupPrintServices(flavor, pras); // 定位默認的打印服務 PrintService defaultService = PrintServiceLookup .lookupDefaultPrintService(); // 顯示打印對話框 PrintService service = ServiceUI.printDialog(null, 200, 200, printService, defaultService, flavor, pras); if (service != null) { try { DocPrintJob job = service.createPrintJob(); // 建立打印做業 FileInputStream fis = new FileInputStream(file); // 構造待打印的文件流 DocAttributeSet das = new HashDocAttributeSet(); Doc doc = new SimpleDoc(fis, flavor, das); job.print(doc, pras); } catch (Exception e) { e.printStackTrace(); } } } } }
可是通過嘗試以後,發現pdf文件並無以pdf的格式打印出來,而是打印出亂碼(也就是文件的二進制碼)命令行
初步猜測是打印機沒法識別吧。因而將上面的DocFlavor改爲DocFlavor.INPUT_STREAM.PDF;code
那麼printService[]將會爲null,爲何呢?由於lookupDefaultPrintService()方法只會返回支持docFlavor的打印機~對象
若未經過docFlavor來過濾打印機,而直接進行打印時,會報錯:invalid flavor,也就是不支持該類型~blog
其實咱們看docFlavor,它其實也就是發送到打印機的數據流的content-type,相似到web中,也就是不支持該content-type,那麼就比較容易理解了。圖片
後來從網上找到的解釋是:ip
Java print service API自己支持打印, 但其並不具備解釋PDF文件的能力,也就是說,用標準的Java Print API可以打印PDF文件, 但所用的打印機必須支持PDF打印標準,即打印機支持Post Script標準, 而這種打印機一般昂貴,目前市場上流通的廉價打印機(使用基於主機的驅動程序)基本不支持get
那怎麼辦呢?難道咱們就沒辦法經過Java程序來打印pdf文件了嗎?無論有沒有,至少要去試試吧~
發現網上並無特別好的解決方案。大概收集了幾種:
一、比較偷懶的方法,調外掛程序來實現打印,最典型的就是Adobe Reader
二、使用PdfRenderer等第三方庫先將pdf文件轉換成圖片,那麼就能夠調用PrintService來打印了
先說第一種方法吧~
首先你的電腦上得裝上Adobe Reader,調用Adobe Reader來打印須要依賴acrord32這個命令
咱們知道在Java中要調用命令行須要Runtime對象,具體代碼以下:
public static boolean printPdf(String pdfPath){ try{ Runtime.getRuntime().exec("cmd.exe /C start acrord32 /P /h " + pdfPath); return true; }catch(Exception e){ e.printStackTrace(); return false; } }
這裏調用了Adobe Reader的acrord32.exe方法,下面來介紹下這個命令的參數。
acrord32.exe filename - 執行Adobe Reader,而且瀏覽PDF
其餘還支持的參數有:
AcroRd32.exe /p filename - 執行Adobe Reader,而且打印一個PDF文件
AcroRd32.exe /t path printername drivername portname
初始化Adobe Reader, 不彈出打印對話框,而後結束打印
/t 命令所需的四個參數有
path - 打印文件路徑
printername - 打印機名字
drivername - 打印機驅動名字
portname - 打印機端口
其餘的參數:
/n 開一個新的Adobe Reader, 儘管有Adobe Reader已經打開 (靜默打印不用)
/s 打開一個Adobe Reader不開splash screen
/o 打開一個Adobe Reader不開打開文件對話框
/h 以最小化方式打開一個Adobe Reader (靜默打印使用)