JAVA實現調用打印機打印PDF
- 2019 年 11 月 7 日
- 筆記
JAVA實現調用打印機打印PDF,網上搜索了一大把資料,基本上都是重複。。。下面罵人的一大堆。。我這裡來解決一下。
需求:前端調用用接口 後端根據模版生成數據聯通打印機直接一鍵打印!
思路:這裡講一下打印最好使用pdf去打印。不管是word.excel 都是通過轉PDF 再打印出來的。所以我這裡的思路就是 選擇模版生成文件,並且打印。
我這裡選擇html模版 也就是freemark模版。
1、通過vm文件生成html
2、通過html再轉成 pdf
3、調用打印機方法打印
可能這有人問為啥不用 word模版。我這裡說明一個坑。如果是模版網上解決方案基本上是 xml格式的。xml格式的word轉pdf是很困難的。至少我沒找到合適的方法去轉。
本文的第一步第二部 就不介紹了 在我的 另一篇博客中有講到。 html轉pdf 中有講解 本文重點介紹 調用打印機的方式!
調用打印機驅動的我目前實驗了 網上所有的方法,查了很多資料。大概摸出了兩種最有效的方式。
第一種 java調用打印機:在本機安裝驅動,利用java代碼去調用進行打印。如果你的代碼是在服務器上那麼就需要在服務器上安裝驅動。
代碼如下:
/** * 通過本機默認打印機打印pdf文件 * @param filePath 文件路徑 * @throws Exception */ public static void defaultPrintPDF(String filePath) throws Exception{ logger.info("打印工具類入參:filePath==================="+filePath); File file = new File(filePath); // 獲取選擇的文件 // 構建打印請求屬性集 HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); // 設置打印格式,因為未確定類型,所以選擇autosense DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF; logger.info("打印文件類型為:==================="+flavor); //pras.add(MediaName.ISO_A4_TRANSPARENT);//A4紙張 //遍歷 // PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras); // // for (PrintService printService2 : printService) { // logger.info("本機可使用打印機列表:==================="+printService2); // } // 定位默認的打印服務 PrintService defaultService = PrintServiceLookup .lookupDefaultPrintService(); logger.info("打印工具選擇打印機為:==================="+defaultService); try { DocPrintJob job = defaultService.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(); logger.info("打印異常",e); throw new Exception(); } }
本來這種方式是OK的 但是我們的運維人員說 服務器安裝打印機的紙張沒辦法更改,需要重啟服務器。重啟服務器我們都不願意。所以改用第二種方式。
第二種:java無驅實現連接打印機打印PDF
代碼如下:
/** * 通過 IP+端口 連接打印機打印文件 * @param filePath * @throws Exception */ public static void print2(String filePath,String ip) throws Exception{ File file = new File(filePath); // 獲取選擇的文件 Socket socket = new Socket(ip, 9100); OutputStream out = socket.getOutputStream(); FileInputStream fis = new FileInputStream(file); //建立數組 byte[] buf = new byte[1024]; int len = 0; //判斷是否讀到文件末尾 while((len=fis.read(buf)) != -1) { out.write(buf, 0, len); } //告訴服務端,文件已傳輸完畢 socket.shutdownOutput(); socket.close(); fis.close(); }
打印的過程中:
1、 第一種方式:比如紙張設置。如果裝了驅動直接叫運維人員選擇紙張大小,當然代碼也可以設置 盡量少動手嘛
2、第二種的紙張大小可以在html轉pdf的時候設置一下,

以上就是我要介紹的。如果你有更好的方式可以聯繫我。