一、用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 讨论