java調用打印機的兩種方式

一、用java中自帶的PrintServiceLookup實現

import javax.imageio.ImageIO;
import javax.print.*;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.MediaSizeName;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.InputStream;

public class PrintDemo {

    public static void main(String[] args) {
        //創建輸入流
        InputStream inputStream = null;
        try{
            inputStream=new FileInputStream("D:/data/files/tending/qrcode/2019/11/15/1573801224220.png");
        }catch (Exception e){
            e.printStackTrace();
        }
        PrintDemo pd=new PrintDemo();
        pd.printQRCode(inputStream);//打印方法
    }

    private void printQRCode(InputStream inputStream){
        //設置文檔類型當前是png圖片
        DocFlavor flavor=DocFlavor.INPUT_STREAM.PNG;
        assert inputStream != null;
        //創建一個文檔
        Doc doc=new SimpleDoc(inputStream, flavor, null);
        //創建屬性設置對象
        PrintRequestAttributeSet attributeSet=new HashPrintRequestAttributeSet();
        attributeSet.add(new Copies(1));//設置打印份數
        //設置打印方向
        //attributeSet.add(OrientationRequested.PORTRAIT);
        // 設置紙張大小,也可以新建MediaSize類來自定義大小
        *//*new MediaSize(90,130, Size2DSyntax.MM);
        MediaSizeExt mediaSize=new MediaSizeExt(90,130, Size2DSyntax.MM);
        attributeSet.add(mediaSize);*//*
        //發現可以根據屬性設置指令打印格式的打印機
        PrintService[] services=PrintServiceLookup.lookupPrintServices(flavor, null);
        //重其中一個打印服務中創建一個打印作業
        PrintService TscTtp244Pro=null;
        if (services.length > 0) {
            for (PrintService service : services) {
                if(service.getName().equals("TSC TTP-244 Pro"))//選擇二維碼打印機
                    TscTtp244Pro=service;
            }
        }
        // 顯示打印對話框
        TscTtp244Pro = ServiceUI.printDialog(null, 200, 200, services, TscTtp244Pro, flavor, attributeSet);
        if(TscTtp244Pro == null) return;
        DocPrintJob job = TscTtp244Pro.createPrintJob();
        try {
            job.print(doc, attributeSet);
        } catch (PrintException e) {
            e.printStackTrace();
        }
    }
}

二、使用java自帶的Printable接口,實現接口中的print方法實現打印

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.print.*;
import java.io.IOException;
import java.net.URL;

import static java.awt.print.Printable.PAGE_EXISTS;

public class PrintDemo extends JFrame {
    public static void main(String[] args) {
        //這裏選擇一個網絡上的圖片
        //紙張大小要一個值一個值的試,比較煩,好像是有一個轉化比例
        PrintQRCodePrint.qrCodePrint("https://csdnimg.cn/pubfooter/images/csdn-kf.png", 222, 334, 222, 334);
    }
}

class PrintQRCodePrint {

    static void qrCodePrint(String path, int pageWidth, int pageHeight, int showWidth, int showHeight) {
        // 通俗理解就是書、文檔
        Book book = new Book();
        // 設置成豎打
        PageFormat pf = new PageFormat();
        pf.setOrientation(PageFormat.PORTRAIT);
        // 通過Paper設置頁面的空白邊距和可打印區域。必須與實際打印紙張大小相符。
        Paper p = new Paper();
        p.setSize(pageWidth,pageHeight);//紙張大小
        p.setImageableArea(0,0, pageWidth,pageHeight);//打印區域
        pf.setPaper(p);
        // 把 PageFormat 和 Printable 添加到書中,組成一個頁面
        book.append((graphics, pageFormat, pageIndex) -> {//通過一個匿名內部內實現Printable接口,不懂的自行查看jdk8的新特性
            try {
                URL url = new URL(path);//也可以通過file構建一個本地圖片File對象傳遞給ImageIO.read()方法
                Image image=ImageIO.read(url);
                //將圖片繪製到graphics對象中(爲什麼把需要打印的內容drawImage就可以實現打印自己取看值傳遞一引用傳遞的區別)
                graphics.drawImage(image,0,0,showWidth,showHeight,null);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return PAGE_EXISTS;//返回0(PAGE_EXISTS)則執行打印,返回1(NO_SUCH_PAGE)則不執行打印
        }, pf);
        // 獲取打印服務對象
        PrinterJob job = PrinterJob.getPrinterJob();
        // 設置打印類
        job.setPageable(book);
        try {
            //可以用printDialog顯示打印對話框,在用戶確認後打印;也可以直接打印
            boolean a=job.printDialog();
            if(a){
                job.print();
            }else{
                job.cancel();
            }
        } catch (PrinterException e) {
            e.printStackTrace();
        }
    }
}

注意:將inputstream流對象作爲參數傳遞,沒有搞懂爲什麼打印不出來(對象不是空值)

解決:如果有內部類(非匿名內部內不知道會不會),將路徑字符串作爲參數傳遞,部傳遞inputstream對象流,inputstream對象流在具體使用的地方創建

歡迎加羣:517413713 討論

發佈了8 篇原創文章 · 獲贊 13 · 訪問量 4597
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章